[PATCH 0/2] iommu/dma: Skip iova_to_phys() on unmap for coherent devices

From: Joe Damato

Date: Fri Nov 06 2026 - 13:03:57 EST


Greetings:

iommu_dma_unmap_phys() calls iommu_iova_to_phys() on every unmap, which
walks the IOMMU page table. The physical address it returns is only used
for devices that are non-coherent or use a swiotlb.

For a coherent device that does not use swiotlb, the lookup is not
needed. iommu_dma_sync_single_for_cpu() and
iommu_dma_sync_single_for_device() already skip it for these devices, as
does __iommu_dma_iova_unlink() for the dma_iova_link() API.

Patch 1 factors the check out into a helper. Patch 2 uses the helper to
skip the lookup in iommu_dma_unmap_phys().

I split this into two patches because I thought it would make review and
bisect easier, but I can make them a single patch if needed.

One behavior change: for these devices the WARN_ON(!phys) in
iommu_dma_unmap_phys() is no longer reached, so unmapping an IOVA that
is not mapped no longer warns there. CONFIG_DMA_API_DEBUG still catches
this class of driver bug.

I tested on prod hosts serving TX heavy network traffic, which unmaps TX
buffers on completion.

Intel Xeon Gold 6138 (Skylake), VT-d:

- iova_to_phys() on unmap: 119-143 ns per TX packet (~0.5% of busy
CPU) before, 0 after

AMD EPYC 9334 (Genoa), AMD IOMMU:

- iova_to_phys() on unmap: ~10 ns per TX packet (~0.1% of busy CPU)
before, 0 after

So, the performance improvement is small, but measureable. The proposed
change removes redundant work in the unmap, though, making it match the map
path.

Thanks,
Joe

Joe Damato (2):
iommu/dma: Add helper for coherent devs without swiotlb
iommu/dma: Skip iova_to_phys() on unmap when unneeded

drivers/iommu/dma-iommu.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)


base-commit: f66469d9905b39d2c260a15d7d6db450f4db67c1
--
2.53.0-Meta