DMA API Debugging: Catch Map and Unmap Contract Violations Before Random Corruption
DMA API debugging is a contract checker for the driver’s mapping lifecycle. Before interpreting a quiet log, verify that its bookkeeping is active, has capacity and can still print the errors you need. A successful device transfer does not prove that the corresponding map, synchronization and unmap calls obeyed the kernel API.
This procedure targets upstream Linux v6.12. It focuses on enabling and interpreting the checker, rather than teaching DMA address masks or scatter-gather descriptor construction. No checker-enabled kernel was built or booted, and no DMA operation or deliberately invalid mapping was executed for this article.
Establish whether the checker can observe this run
Start with the final configuration and architecture support. The v6.12 DMA Kconfig defines CONFIG_DMA_API_DEBUG and its dependencies. Verify the actual generated configuration instead of assuming that a debug-oriented distribution enables it. The upstream DMA API debugging documentation explicitly warns about performance impact and advises against enabling it in production kernels.
Use a recoverable development target with the same relevant driver and DMA backend. Record the kernel commit, configuration, device identity, driver revision, boot arguments and workload. Enabling the checker changes memory consumption and timing, so comparisons need that instrumentation difference recorded.
When debugfs is already available at its approved mount point, inspect the dma-api directory. Read disabled, error_count, num_errors, all_errors, driver_filter, num_free_entries, min_free_entries and nr_total_entries. Do not turn a missing directory into evidence that the driver passed. It may indicate configuration, mount visibility, permissions or initialization differences.
Separate detection, filtering and printing
The checker tracks mapping records and tests supported API calls against them. A printed report can identify the device, driver, contract mismatch and offending call stack. When supported stack capture is available, it can also show where the mapping was created. Preserve the complete first report before repeated failures obscure the original operation.
By default, the warning budget permits one printed error. Later errors can increase the error counter without generating another warning. A driver filter limits printed output; it does not establish that all bookkeeping belongs only to that driver.
The v6.12 implementation makes an important distinction: error_count increments before the driver-filter decision, and the remaining finite warning budget is decremented outside that decision. An error from another driver can therefore consume the shared budget even while its message is filtered out. Recheck the budget around your trial instead of treating a selected filter as a dedicated recording channel.
The same source documents that error_count updates can race and lose increments. Use a rising counter as evidence of detected violations, not a precise forensic count of every invalid API call. Avoid enabling unlimited warnings as a default remedy; a repeated defect can flood the log and disturb the system.

Turn one report into a lifecycle worksheet
The following is a synthetic field worksheet, not literal kernel output. Suppose one request records map length 512 bytes and later supplies unmap length 256 bytes. These values illustrate an inconsistent contract; they are not measurements from a real device.
| Report or source field | Question to resolve |
|---|---|
| Device and driver | Which device object owns the mapping, including reset generation? |
| Mapped operation and length | What did the successful creation call actually record? |
| Unmap operation and length | Which completion, abort or cleanup branch supplied the mismatch? |
| Mapping and violation stacks | Can both paths be tied to the same request lifetime? |
| Surrounding errors | Did an earlier failure redirect cleanup through a different path? |
Trace the request through normal completion, submission failure, timeout, reset and device removal. A correct normal path does not clear a bug in abort cleanup. Keep the original mapping parameters in the request’s owned state when that is the appropriate driver design; do not reconstruct them from mutable transfer progress.
The checker also has tests for mismatched API types, directions, unknown mappings and supported mapping-error checks. Their presence does not make it an observer of arbitrary hardware writes. Use the actual report category to choose a source audit, rather than replacing every DMA-related failure with the same suspected cause.
Watch the bookkeeping resource boundary
Mapping records require memory. The documented initial preallocation can grow on demand, but allocation failure can disable checking. A disabled indicator of Y invalidates a blanket “no more errors” conclusion. If the kernel was booted with dma_debug=off, runtime controls cannot turn the checker back on; a suitably configured reboot is required.
Record total entries and the historical minimum free count before and after the bounded operation. A low minimum is a capacity signal, not by itself a mapping leak. Sustained growth deserves a comparison with the number of legitimately outstanding requests and the driver’s teardown behavior.
The dump interface can help inspect current records, but a live snapshot is not a stable transaction log. Bound collection and preserve request context. Adjusting preallocation for a laboratory rerun should be justified by observed bookkeeping demand, not used to hide unbounded growth.
Run a bounded validation sequence
- Verify active checking, adequate recording capacity, the intended filter and a usable finite warning budget.
- Record a baseline and run one supported transfer sequence on the test target.
- Capture complete reports and checker status immediately afterward.
- Repeat relevant cleanup and recovery paths using reviewed, recoverable tests.
- After a source fix, compare the same paths and confirm that checking stayed active throughout.
A useful outcome identifies the violating lifecycle edge and the repair that preserves its contract on every exit path. If the counter rises without a visible report, investigate filter and budget state before concluding that the target driver is innocent. If checking disables itself, rerun with a justified capacity plan rather than certifying the incomplete interval.
State what a clean run leaves open
A clean observed sequence supports only the checked API paths, device backend and workloads exercised. It does not prove device coherency, descriptor correctness, absence of out-of-bounds DMA, electrical integrity or complete removal safety. Those require different evidence.
Deliver the source-linked lifecycle worksheet, full first report, checker-state snapshots and repeatable workload definition. This keeps the conclusion anchored to an API contract and its observation coverage, instead of interpreting log silence as a general hardware health certificate.