On 9/7/26 08:01, Donggeun Yoo wrote:
dma_alloc_attrs() passes *dma_handle to trace_dma_alloc() without checking whether the allocation succeeded. No backend writes it on failure: dma_direct_alloc(), iommu_dma_alloc() and the dma_map_ops instances assign it only on the path that returns a buffer. Callers usually pass an uninitialized automatic variable, so a failed allocation records whatever the stack held, next to the virt_addr=(null) that marks the record as an error:dma_alloc: dmatrace dir=BIDIRECTIONAL dma_addr=deadbeefdeadbeef size=1099511627776 virt_addr=0000000000000000 The device coherent pool path reaches the same call: a non-zero return from dma_alloc_from_dev_coherent() means the request was handled, not that it succeeded, so cpu_addr is NULL and dma_handle is untouched once the pool runs out. For an allocation event a NULL virt_addr already means the request failed, so the address field carries nothing. Report 0 for it in the event class rather than at each call site, which covers dma_alloc_pages() and dma_alloc_sgt_err() as well. Fixes: 038eb433dc14 ("dma-mapping: add tracing for dma-mapping API calls") Fixes: 68b6dbf1f441 ("dma-mapping: trace more error paths") Suggested-by: Marek Szyprowski <[email protected]> Signed-off-by: Donggeun Yoo <[email protected]> --- v2: - report 0 in the event class instead of splitting the two call sites, as suggested by Marek. kernel/dma/mapping.c is untouched now, so debug_dma_alloc_coherent() keeps being called for a failed allocation and decides for itself what to do with it. - tested on x86_64 rather than compile-tested only. v1: https://lore.kernel.org/linux-iommu/[email protected]/ Tested with a module that puts a known value in the caller's handle and then asks for 1 TiB from a 32-bit capable device, with the dma_alloc event enabled. Before, the record carries the caller's stale value; after, it carries 0: -dma_addr=deadbeefdeadbeef size=1099511627776 virt_addr=0000000000000000 +dma_addr=0 size=1099511627776 virt_addr=0000000000000000 A PAGE_SIZE request from the same device, as a control, reports its real address on both kernels, matching the handle the caller got back. This changes what the record contains, not what the caller does: *dma_handle is still read to build the tracepoint arguments, since those are evaluated before the static branch. include/trace/events/dma.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/trace/events/dma.h b/include/trace/events/dma.h index 9df02c1511de..b06d8f99922d 100644 --- a/include/trace/events/dma.h +++ b/include/trace/events/dma.h @@ -134,7 +134,7 @@ DECLARE_EVENT_CLASS(dma_alloc_class, TP_fast_assign( __assign_str(device); __entry->virt_addr = virt_addr; - __entry->dma_addr = dma_addr; + __entry->dma_addr = virt_addr ? dma_addr : 0; __entry->size = size; __entry->flags = flags; __entry->dir = dir; base-commit: cee9395acd8043be0644b25c34bfa86623f2b935
Reviewed-by: Sean Anderson <[email protected]>
