Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

iommu: Introduce iotlb_sync_map callback

Introduce iotlb_sync_map() callback that is invoked in the end of
iommu_map(). This new callback allows IOMMU drivers to avoid syncing
after mapping of each contiguous chunk and sync only when the whole
mapping is completed, optimizing performance of the mapping operation.

Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Reviewed-by: Thierry Reding <treding@nvidia.com>
Signed-off-by: Joerg Roedel <jroedel@suse.de>

authored by

Dmitry Osipenko and committed by
Joerg Roedel
1d7ae53b 4b6f0ea3

+7 -2
+6 -2
drivers/iommu/iommu.c
··· 1585 1585 int iommu_map(struct iommu_domain *domain, unsigned long iova, 1586 1586 phys_addr_t paddr, size_t size, int prot) 1587 1587 { 1588 + const struct iommu_ops *ops = domain->ops; 1588 1589 unsigned long orig_iova = iova; 1589 1590 unsigned int min_pagesz; 1590 1591 size_t orig_size = size; 1591 1592 phys_addr_t orig_paddr = paddr; 1592 1593 int ret = 0; 1593 1594 1594 - if (unlikely(domain->ops->map == NULL || 1595 + if (unlikely(ops->map == NULL || 1595 1596 domain->pgsize_bitmap == 0UL)) 1596 1597 return -ENODEV; 1597 1598 ··· 1621 1620 pr_debug("mapping: iova 0x%lx pa %pa pgsize 0x%zx\n", 1622 1621 iova, &paddr, pgsize); 1623 1622 1624 - ret = domain->ops->map(domain, iova, paddr, pgsize, prot); 1623 + ret = ops->map(domain, iova, paddr, pgsize, prot); 1625 1624 if (ret) 1626 1625 break; 1627 1626 ··· 1629 1628 paddr += pgsize; 1630 1629 size -= pgsize; 1631 1630 } 1631 + 1632 + if (ops->iotlb_sync_map) 1633 + ops->iotlb_sync_map(domain); 1632 1634 1633 1635 /* unroll mapping in case something went wrong */ 1634 1636 if (ret)
+1
include/linux/iommu.h
··· 201 201 void (*flush_iotlb_all)(struct iommu_domain *domain); 202 202 void (*iotlb_range_add)(struct iommu_domain *domain, 203 203 unsigned long iova, size_t size); 204 + void (*iotlb_sync_map)(struct iommu_domain *domain); 204 205 void (*iotlb_sync)(struct iommu_domain *domain); 205 206 phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova); 206 207 int (*add_device)(struct device *dev);