Skip to content

Day101 - DMA Descriptor

Today's Goal

Understand how the Linux DMA Engine represents individual DMA transactions using descriptors before studying the submission and execution flow.

The focus of this session is to build a complete mental model of DMA descriptors rather than individual APIs.


What I Learned

Why DMA Descriptor Exists

A DMA channel only represents an execution resource.

Each DMA transaction requires additional information, including:

  • Source address
  • Destination address
  • Transfer length
  • Direction
  • Callback
  • Control flags

Linux encapsulates this information into a DMA Descriptor.


Descriptor is a Transaction Object

A descriptor represents one DMA transaction.

Unlike DMA channels, descriptors are created per transaction and have a relatively short lifetime.

Conceptually, a descriptor contains three categories of information:

  • Transfer Information
  • Completion Information
  • Execution Information

DMA Channel and Descriptor Relationship

A DMA controller owns multiple DMA channels.

Each channel executes multiple DMA transactions during its lifetime.

Each transaction is represented by one struct dma_async_tx_descriptor.


Descriptor Ownership

A descriptor changes ownership as it moves through the DMA Engine framework.

Typical ownership flow:

Client Driver

DMA Engine

Controller Driver

DMA Hardware

DMA Engine

Client Driver

Ownership transfer is more important than individual API calls when understanding the DMA Engine framework.


Descriptor Lifecycle

The lifecycle of a descriptor is independent from its ownership.

Typical states include:

  • Created
  • Prepared
  • Submitted
  • Pending
  • Running
  • Completed
  • Reclaimed

Understanding descriptor state transitions makes the execution flow much easier to follow.


Descriptor Preparation

Different DMA transactions require different preparation APIs.

Examples include:

  • dmaengine_prep_slave_sg()
  • dmaengine_prep_dma_memcpy()
  • dmaengine_prep_dma_cyclic()
  • dmaengine_prep_interleaved_dma()

Although they prepare different transaction types, they all return a struct dma_async_tx_descriptor.


Scatter-Gather Descriptor

A descriptor does not necessarily represent a single buffer.

One descriptor may describe multiple memory segments through Scatter-Gather lists.

The descriptor represents one transaction rather than one memory buffer.


Each submitted descriptor receives a DMA Cookie.

A cookie uniquely identifies one DMA transaction.

It is assigned during descriptor submission and is later used for transaction tracking and completion queries.


Kernel Object Model

The key kernel objects are:

  • struct dma_device
  • struct dma_chan
  • struct dma_async_tx_descriptor

Controller drivers usually embed the generic descriptor inside a private descriptor structure containing hardware-specific information.


Diagrams

Created four reusable diagrams:

  • DMA Descriptor Architecture
  • DMA Channel and Descriptor Relationship
  • Descriptor Ownership Timeline
  • Descriptor Lifecycle

Both .drawio and exported .svg files were completed.


Key Takeaways

The most important concept learned today is:

A DMA Descriptor is a kernel object that represents one DMA transaction.

Everything in the DMA Engine framework—including ownership, lifecycle, cookies, callbacks, and submission—is built around this transaction object.


Next Step

The next topic is DMA Descriptor Submission and Completion.

The focus will shift from object relationships to the execution path of one DMA transaction:

  • dmaengine_submit()
  • Cookie assignment
  • dma_async_issue_pending()
  • Controller driver scheduling
  • DMA completion
  • Callback execution