From: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>

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.william...@redhat.com>
Cc: Joerg Roedel <jroe...@suse.de>
Signed-off-by: Suravee Suthikulpanit <suravee.suthikulpa...@amd.com>
---
 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

Reply via email to