From 536fdf792df0341ad65503cc67bf2ad4f8455da4 Mon Sep 17 00:00:00 2001 From: "Isaac J. Manjarres" Date: Thu, 7 Jan 2021 22:32:05 -0800 Subject: [PATCH] FROMLIST: iommu/io-pgtable: Introduce map_sg() as a page table op While mapping a scatter-gather list, iommu_map_sg() calls into the IOMMU driver through an indirect call, which can call into the io-pgtable code through another indirect call. This sequence of going through the IOMMU core code, the IOMMU driver, and finally the io-pgtable code, occurs for every element in the scatter-gather list, in the worse case, which is not optimal. Introduce a map_sg callback in the io-pgtable ops so that IOMMU drivers can invoke it with the complete scatter-gather list, so that it can be processed within the io-pgtable code entirely, reducing the number of indirect calls, and boosting overall iommu_map_sg() performance. Bug: 190544587 Link: https://lore.kernel.org/linux-iommu/1610376862-927-1-git-send-email-isaacm@codeaurora.org/T/#t Change-Id: I4b2088dd08eb97dcd94a6c6968082a3c4395351a Signed-off-by: Isaac J. Manjarres Tested-by: Sai Prakash Ranjan Signed-off-by: Georgi Djakov --- include/linux/io-pgtable.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/linux/io-pgtable.h b/include/linux/io-pgtable.h index 86af6f0a00a2..fd0ffd5ac203 100644 --- a/include/linux/io-pgtable.h +++ b/include/linux/io-pgtable.h @@ -145,6 +145,9 @@ struct io_pgtable_cfg { * * @map: Map a physically contiguous memory region. * @map_pages: Map a physically contiguous range of pages of the same size. + * @map_sg: Map a scatter-gather list of physically contiguous memory + * chunks. The mapped pointer argument is used to store how + * many bytes are mapped. * @unmap: Unmap a physically contiguous memory region. * @unmap_pages: Unmap a range of virtually contiguous pages of the same size. * @iova_to_phys: Translate iova to physical address. @@ -158,6 +161,9 @@ struct io_pgtable_ops { int (*map_pages)(struct io_pgtable_ops *ops, unsigned long iova, phys_addr_t paddr, size_t pgsize, size_t pgcount, int prot, gfp_t gfp, size_t *mapped); + int (*map_sg)(struct io_pgtable_ops *ops, unsigned long iova, + struct scatterlist *sg, unsigned int nents, int prot, + gfp_t gfp, size_t *mapped); size_t (*unmap)(struct io_pgtable_ops *ops, unsigned long iova, size_t size, struct iommu_iotlb_gather *gather); size_t (*unmap_pages)(struct io_pgtable_ops *ops, unsigned long iova,