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