Re: [RFC PATCH] dma-iommu: Add iommu_dma_max_mapping_size()

From: John Garry
Date: Tue May 17 2022 - 05:02:12 EST


On 17/05/2022 09:38, Christoph Hellwig wrote:
On Mon, May 16, 2022 at 09:06:01PM +0800, John Garry wrote:
For streaming DMA mappings involving an IOMMU and whose IOVA len regularly
exceeds the IOVA rcache upper limit (meaning that they are not cached),
performance can be reduced.

Add the IOMMU callback for DMA mapping API dma_max_mapping_size(), which
allows the drivers to know the mapping limit and thus limit the requested
IOVA lengths.

This resolves the performance issue originally reported in [0] for a SCSI
HBA driver which was regularly mapping SGLs which required IOVAs in
excess of the IOVA caching limit. In this case the block layer limits the
max sectors per request - as configured in __scsi_init_queue() - which
will limit the total SGL length the driver tries to map and in turn limits
IOVA lengths requested.

BTW, on a separate topic, I noticed that even with this change my ATA devices have max_hw_sectors_kb of 32767, as opposed to 128 for SAS devices. It seems that libata-scsi - specifically ata_scsi_dev_config() - doesn't honour the shost max_sectors limit. I guess that is not intentional.


[0] https://lore.kernel.org/linux-iommu/20210129092120.1482-1-thunder.leizhen@xxxxxxxxxx/

Signed-off-by: John Garry <john.garry@xxxxxxxxxx>
---
Sending as an RFC as iommu_dma_max_mapping_size() is a soft limit, and not
a hard limit which I expect is the semantics of dma_map_ops.max_mapping_size

diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c
index 09f6e1c0f9c0..e2d5205cde37 100644
--- a/drivers/iommu/dma-iommu.c
+++ b/drivers/iommu/dma-iommu.c
@@ -1442,6 +1442,21 @@ static unsigned long iommu_dma_get_merge_boundary(struct device *dev)
return (1UL << __ffs(domain->pgsize_bitmap)) - 1;
}

+ if (!domain)
+ return 0;
+
+ cookie = domain->iova_cookie;
+ if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE)
+ return 0;

Can these conditions even be true here?

I don't think so. Paranoia on my part.


+static inline unsigned long iova_rcache_range(void)
+{
+ return 0;
+}

Given that IOMMU_DMA select IOMMU_IOVA there is no need for this stub.

hmmm.. ok. Policy was to be stub everything but I think that it has changed.


Otherwise this looks sensible to me.

.

Great, thanks.