[PATCH 1/2] vfio/type1: Adopt fast IOTLB flush interface when unmap IOVAs

From: Suravee Suthikulpanit
Date: Fri Nov 17 2017 - 16:12:24 EST


From: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>

VFIO IOMMU type1 currently upmaps IOVA pages synchronously, which requires
IOTLB flushing for every unmapping. This results in large IOTLB flushing
overhead when handling pass-through devices with a large number of mapped
IOVAs (e.g. GPUs).

This can be avoided by using the new IOTLB flushing interface.

Cc: Alex Williamson <alex.williamson@xxxxxxxxxx>
Cc: Joerg Roedel <jroedel@xxxxxxx>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx>
---
drivers/vfio/vfio_iommu_type1.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
index 92155cc..28a7ab6 100644
--- a/drivers/vfio/vfio_iommu_type1.c
+++ b/drivers/vfio/vfio_iommu_type1.c
@@ -698,10 +698,12 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,
break;
}

- unmapped = iommu_unmap(domain->domain, iova, len);
+ unmapped = iommu_unmap_fast(domain->domain, iova, len);
if (WARN_ON(!unmapped))
break;

+ iommu_tlb_range_add(domain->domain, iova, len);
+
unlocked += vfio_unpin_pages_remote(dma, iova,
phys >> PAGE_SHIFT,
unmapped >> PAGE_SHIFT,
@@ -710,6 +712,7 @@ static long vfio_unmap_unpin(struct vfio_iommu *iommu, struct vfio_dma *dma,

cond_resched();
}
+ iommu_tlb_sync(domain->domain);

dma->iommu_mapped = false;
if (do_accounting) {
@@ -884,8 +887,11 @@ static int map_try_harder(struct vfio_domain *domain, dma_addr_t iova,
break;
}

- for (; i < npage && i > 0; i--, iova -= PAGE_SIZE)
- iommu_unmap(domain->domain, iova, PAGE_SIZE);
+ for (; i < npage && i > 0; i--, iova -= PAGE_SIZE) {
+ iommu_unmap_fast(domain->domain, iova, PAGE_SIZE);
+ iommu_tlb_range_add(domain->domain, iova, PAGE_SIZE);
+ }
+ iommu_tlb_sync(domain->domain);

return ret;
}
--
1.8.3.1