Add MSM SMMUv1 support
Subsystems (6)
cover Add MSM SMMUv1 support
These patches add support for Qualcomm MSM SMMUv1 hardware. The first patch renames the files for the existing MSM IOMMU driver to align with the SMMU hardware revision (v1 is ARM SMMUv1 spec). The second patch adds back map_range/unmap_range APIs. These APIs allows SMMU driver implementations to optimize mappings of scatter-gather list of physically contiguous chunks of memory. The third patch adds common macros to allow device drivers to poll memory mapped registers. The fourth and fifth patch is the actual MSM SMMUv1 driver which supports the following:
- ARM V7S and V7L page table format independent of ARM CPU page table format
- 4K/64K/1M/16M mappings (V7S)
- 4K/64K/2M/32M/1G mappings (V7L)
- ATOS used for unit testing of driver
- Sharing of page tables among SMMUs
- Verbose context bank fault reporting
- Verbose global fault reporting
- Support for clocks and GDSC
- map/unmap range
- Domain specific enabling of coherent Hardware Table Walk (HTW)
The last patch adds a new IOMMU domain attribute allowing us to set whether hardware table walks should go to cache or not.
Matt Wagantall (1):
iopoll: Introduce memory-mapped IO polling macros
Olav Haugan (6):
iommu: msm: Rename iommu driver files
iommu-api: Add map_range/unmap_range functions
iommu: msm: Add MSM IOMMUv1 driver
iommu: msm: Add support for V7L page table format
defconfig: msm: Enable Qualcomm SMMUv1 driver
iommu-api: Add domain attribute to enable coherent HTW
.../devicetree/bindings/iommu/msm,iommu_v1.txt | 60 +
arch/arm/configs/qcom_defconfig | 3 +-
drivers/iommu/Kconfig | 57 +-
drivers/iommu/Makefile | 8 +-
drivers/iommu/iommu.c | 24 +
drivers/iommu/{msm_iommu.c => msm_iommu-v0.c} | 2 +-
drivers/iommu/msm_iommu-v1.c | 1529 +++++++++++++
drivers/iommu/msm_iommu.c | 771 +------
.../iommu/{msm_iommu_dev.c => msm_iommu_dev-v0.c} | 2 +-
drivers/iommu/msm_iommu_dev-v1.c | 345 +++
.../{msm_iommu_hw-8xxx.h => msm_iommu_hw-v0.h} | 0
drivers/iommu/msm_iommu_hw-v1.h | 2322 ++++++++++++++++++++
drivers/iommu/msm_iommu_pagetable.c | 600 +++++
drivers/iommu/msm_iommu_pagetable.h | 33 +
drivers/iommu/msm_iommu_pagetable_lpae.c | 717 ++++++
drivers/iommu/msm_iommu_priv.h | 65 +
include/linux/iommu.h | 25 +
include/linux/iopoll.h | 114 +
include/linux/qcom_iommu.h | 221 ++
19 files changed, 6236 insertions(+), 662 deletions(-)
create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu_v1.txt
copy drivers/iommu/{msm_iommu.c => msm_iommu-v0.c} (99%)
create mode 100644 drivers/iommu/msm_iommu-v1.c
rename drivers/iommu/{msm_iommu_dev.c => msm_iommu_dev-v0.c} (99%)
create mode 100644 drivers/iommu/msm_iommu_dev-v1.c
rename drivers/iommu/{msm_iommu_hw-8xxx.h => msm_iommu_hw-v0.h} (100%)
create mode 100644 drivers/iommu/msm_iommu_hw-v1.h
create mode 100644 drivers/iommu/msm_iommu_pagetable.c
create mode 100644 drivers/iommu/msm_iommu_pagetable.h
create mode 100644 drivers/iommu/msm_iommu_pagetable_lpae.c
create mode 100644 drivers/iommu/msm_iommu_priv.h
create mode 100644 include/linux/iopoll.h
create mode 100644 include/linux/qcom_iommu.h--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 1/7 iommu: msm: Rename iommu driver files
Rename the MSM IOMMU driver for MSM8960 SoC to "-v0" version to align with hardware version number for next generation MSM IOMMU (v1).
---
arch/arm/configs/qcom_defconfig | 2 +-
drivers/iommu/Kconfig | 11 +++++++++--
drivers/iommu/Makefile | 2 +-
drivers/iommu/{msm_iommu.c => msm_iommu-v0.c} | 2 +-
drivers/iommu/{msm_iommu_dev.c => msm_iommu_dev-v0.c} | 2 +-
drivers/iommu/{msm_iommu_hw-8xxx.h => msm_iommu_hw-v0.h} | 0
6 files changed, 13 insertions(+), 6 deletions(-)
rename drivers/iommu/{msm_iommu.c => msm_iommu-v0.c} (99%)
rename drivers/iommu/{msm_iommu_dev.c => msm_iommu_dev-v0.c} (99%)
rename drivers/iommu/{msm_iommu_hw-8xxx.h => msm_iommu_hw-v0.h} (100%)arch/arm/configs/qcom_defconfig +1 -1
@@ -136,7 +136,7 @@ CONFIG_COMMON_CLK_QCOM=y CONFIG_MSM_GCC_8660=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y -CONFIG_MSM_IOMMU=y +CONFIG_MSM_IOMMU_V0=y CONFIG_GENERIC_PHY=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y
drivers/iommu/Kconfig +9 -2
@@ -28,12 +28,19 @@ config FSL_PAMU transaction types. # MSM IOMMU support + +# MSM_IOMMU always gets selected by whoever wants it. config MSM_IOMMU - bool "MSM IOMMU Support" + bool + +# MSM IOMMUv0 support +config MSM_IOMMU_V0 + bool "MSM IOMMUv0 Support" depends on ARCH_MSM8X60 || ARCH_MSM8960 select IOMMU_API + select MSM_IOMMU help - Support for the IOMMUs found on certain Qualcomm SOCs. + Support for the IOMMUs (v0) found on certain Qualcomm SOCs. These IOMMUs allow virtualization of the address space used by most cores within the multimedia subsystem.
drivers/iommu/Makefile +1 -1
@@ -1,7 +1,7 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o -obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o msm_iommu_dev.o +obj-$(CONFIG_MSM_IOMMU_V0) += msm_iommu-v0.o msm_iommu_dev-v0.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
drivers/iommu/msm_iommu-v0.c renamed from drivers/iommu/msm_iommu.c +1 -1
@@ -31,7 +31,7 @@#include <asm/cacheflush.h> #include <asm/sizes.h> -#include "msm_iommu_hw-8xxx.h" +#include "msm_iommu_hw-v0.h" #include "msm_iommu.h" #define MRC (reg, processor, op1, crn, crm, op2) \
drivers/iommu/msm_iommu_dev-v0.c renamed from drivers/iommu/msm_iommu_dev.c +1 -1
@@ -27,7 +27,7 @@#include <linux/err.h> #include <linux/slab.h> -#include "msm_iommu_hw-8xxx.h" +#include "msm_iommu_hw-v0.h" #include "msm_iommu.h" struct iommu_ctx_iter_data {
drivers/iommu/msm_iommu_hw-v0.h renamed from drivers/iommu/msm_iommu_hw-8xxx.h +0 -0
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
In reply to Olav HauganMapping and unmapping are more often than not in the critical path. map_range and unmap_range allows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.
Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)
drivers/iommu/iommu.c +24 -0
@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap); +int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range); + +int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range); +int iommu_domain_window_enable (struct iommu_domain *domain,u32 wnd_nr,phys_addr_t paddr,u64 size,int prot) {
include/linux/iommu.h +24 -0
@@ -22,6 +22,7 @@#include <linux/errno.h> #include <linux/err.h> #include <linux/types.h> +#include <linux/scatterlist.h> #include <trace/events/iommu.h> #define IOMMU_READ (1 << 0)
@@ -93,6 +94,8 @@ enum iommu_attr {* @detach_dev: detach device from an iommu domain * @map: map a physically contiguous memory region to an iommu domain * @unmap: unmap a physically contiguous memory region from an iommu domain +* @map_range: map a scatter-gather list of physically contiguous memory chunks to an iommu domain +* @unmap_range: unmap a scatter-gather list of physically contiguous memory chunks from an iommu domain * @iova_to_phys: translate iova to physical address * @domain_has_cap: domain capabilities query * @add_device: add device to iommu grouping
@@ -110,6 +113,10 @@ struct iommu_ops { phys_addr_t paddr, size_t size, int prot);size_t (*unmap)(struct iommu_domain *domain,unsigned long iova,size_t size); +int (*map_range)(struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot); +int (*unmap_range)(struct iommu_domain *domain,unsigned int iova, +unsigned int len);phys_addr_t (*iova_to_phys)(struct iommu_domain *domain,dma_addr_t iova);int (*domain_has_cap)(struct iommu_domain *domain,unsigned long cap);
@@ -153,6 +160,10 @@ extern int iommu_map(struct iommu_domain *domain, unsigned long iova, phys_addr_t paddr, size_t size, int prot);extern size_t iommu_unmap (struct iommu_domain *domain,unsigned long iova,size_t size); +extern int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot); +extern int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len);extern phys_addr_t iommu_iova_to_phys (struct iommu_domain *domain,dma_addr_t iova);extern int iommu_domain_has_cap (struct iommu_domain *domain,unsigned long cap);
@@ -280,6 +291,19 @@ static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,return -ENODEV ; } +static inline int iommu_map_range (struct iommu_domain *domain, +unsigned int iova,struct scatterlist *sg, +unsigned int len,int prot) +{ +return -ENODEV ; +} + +static inline int iommu_unmap_range (struct iommu_domain *domain, +unsigned int iova,unsigned int len) +{ +return -ENODEV ; +} +static inline int iommu_domain_window_enable (struct iommu_domain *domain,u32 wnd_nr,phys_addr_t paddr,u64 size,int prot)
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
On Mon, Jun 30, 2014 at 09:51:51AM -0700, Olav Haugan wrote:
[...]
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 905
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ;
Should we perhaps make this mandatory? For drivers that don't provide it we could implement a generic helper that wraps iommu_{map,unmap}().
Quoted 8 lines
drivers/iommu/iommu.c +8
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range); + +int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 10 lines
drivers/iommu/iommu.c +10
-0+ unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);
Could these be renamed iommu_{map,unmap}_sg() instead to make it more obvious what exactly they map? And perhaps this could take an sg_table instead, which already provides a count and is a very common structure used in drivers (and the DMA mapping API).
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140630/40852b16/attachment-0001.sig>
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
In reply to Olav HauganHi Olav,
Quoted 8 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.
Quoted 4 lines
Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
I like the idea of this, although it does mean that drivers implementing the range mapping functions need more featureful page-table manipulation code than currently required.
For example, iommu_map uses iommu_pgsize to guarantee that mappings are created in blocks of the largest support page size. This can be used to simplify iterating in the SMMU driver (although the ARM SMMU driver doesn't yet make use of this, I think Varun would add this when he adds support for sections).
Given that we're really trying to kill the TLBI here, why not implement something like iommu_unmap_nosync (unmap without DSB; TLBI) and iommu_sync (DSB; TLBI) instead? If we guarantee that ranges must be unmapped before being remapped, then there shouldn't be a TLBI on the map path anyway.
Will
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 34 lines
-----Original Message-----
From: iommu-bounces at lists.linux-foundation.org [mailto:iommu- bounces at lists.linux-foundation.org] On Behalf Of Will Deacon
Sent: Tuesday, July 01, 2014 3:04 PM
To: Olav Haugan
Cc: linux-arm-msm at vger.kernel.org; iommu at lists.linux-foundation.org; thierry.reding at gmail.com; vgandhi at codeaurora.org; linux-arm- kernel at lists.infradead.org
Subject: Re: [RFC/PATCH 2/7] iommu-api: Add map_range/unmap_range functionsHi Olav,
Quoted 3 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMUpage tables.
Quoted 9 lines
Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.
Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
I like the idea of this, although it does mean that drivers implementing the range mapping functions need more featureful page-table manipulation code than currently required.
Quoted 5 lines
For example,
iommu_mapusesiommu_pgsizeto guarantee that mappings are created in blocks of the largest support page size. This can be used to simplify iterating in the SMMU driver (although the ARM SMMU driver doesn't yet make use of this, I think Varun would add this when he adds support for sections).
Yes, this would be supported.
-Varun
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
In reply to Olav HauganHi Olav,
Quoted 28 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +1
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap); +int iommu_map_range(struct iommu_domain *domain, unsigned int iova,
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 10 lines
drivers/iommu/iommu.c +10
-0+ struct scatterlist *sg, unsigned int len, int prot) +{ + if (unlikely(domain->ops->map_range == NULL)) + return -ENODEV; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);
We have the similar one internally, which is named, "iommu_map_sg()", called from DMA API.
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);
Can the existing iommu_unmap() do the same?
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);
Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.
Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;
Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?
I believe iommu_unmap() behaves a bit differently because it will keep on calling domain->ops->unmap() until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.
I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new map_range API.
Thanks,
Olav Haugan
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?
Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.
+1 for map_range().. I've seen for gpu workloads, at least, it is the
downstream map_range() API is quite beneficial. It was worth at
least a few fps in xonotic.
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
BR,
-R
Quoted 11 lines
Thanks,
Olav Haugan
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to majordomo at vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.
Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
Thanks,
Olav
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 86 lines · Olav Haugan
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
Quoted 3 lines
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
What I mean by batching up is mapping and unmapping multiple sglists each at different iova's with minmal cpu cache and iommu tlb flushes..
Ideally we'd let the IOMMU driver be clever and build out all 2nd level tables before inserting into first level tables (to minimize cpu cache flushing).. also, there is probably a reasonable chance that we'd be mapping a new buffer into existing location, so there might be some potential to reuse existing 2nd level tables (and save a tiny bit of free/alloc). I've not thought too much about how that would look in code.. might be kinda, umm, fun..
But at an API level, we should be able to do a bunch of map/unmap_range's with one flush.
Maybe it could look like a sequence of iommu_{map,unmap}_range() followed by iommu_flush()?
BR,
-R
Quoted 7 lines
Thanks,
Olav
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 102 lines · Rob Clark
Quoted 86 lines · Olav Haugan
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
Quoted 3 lines
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
What I mean by batching up is mapping and unmapping multiple sglists each at different iova's with minmal cpu cache and iommu tlb flushes..
Ideally we'd let the IOMMU driver be clever and build out all 2nd level tables before inserting into first level tables (to minimize cpu cache flushing).. also, there is probably a reasonable chance that we'd be mapping a new buffer into existing location, so there might be some potential to reuse existing 2nd level tables (and save a tiny bit of free/alloc). I've not thought too much about how that would look in code.. might be kinda, umm, fun..
Quoted 5 lines
But at an API level, we should be able to do a bunch of map/unmap_range's with one flush.
Maybe it could look like a sequence of iommu_{map,unmap}_range() followed by
iommu_flush()?
Doesn't that mean that the IOMMU driver would have to keep track of all mappings until it sees an iommu_flush()? That sounds like it could be a lot of work and complicated code.
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140710/5d9ecb22/attachment-0001.sig>
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 106 lines · Thierry Reding
Quoted 105 lines · Rob Clark
Quoted 86 lines · Olav Haugan
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 922
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
Quoted 3 lines
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
What I mean by batching up is mapping and unmapping multiple sglists each at different iova's with minmal cpu cache and iommu tlb flushes..
Ideally we'd let the IOMMU driver be clever and build out all 2nd level tables before inserting into first level tables (to minimize cpu cache flushing).. also, there is probably a reasonable chance that we'd be mapping a new buffer into existing location, so there might be some potential to reuse existing 2nd level tables (and save a tiny bit of free/alloc). I've not thought too much about how that would look in code.. might be kinda, umm, fun..
But at an API level, we should be able to do a bunch of map/unmap_range's with one flush.
Quoted 6 lines
Quoted 2 lines
Maybe it could look like a sequence of iommu_{map,unmap}_range() followed by
iommu_flush()?Doesn't that mean that the IOMMU driver would have to keep track of all mappings until it sees an
iommu_flush()? That sounds like it could be a lot of work and complicated code.
Well, depends on how elaborate you want to get. If you don't want to be too fancy, it may just be a matter of not doing TLB flush until iommu_flush(). If you want to get fancy and minimize cpu flushes too, then iommu driver would have to do some more tracking to build up a transaction internally. I'm not really sure how you avoid that.
I'm not quite sure how frequent it would be that separate buffers touch the same 2nd level table, so it might be sufficient to treat it like N map_range and unmap_range's followed by one TLB flush. I would, I think, need to implement a prototype or at least instrument the iommu driver somehow to generate some statistics.
I've nearly got qcom-iommu-v0 working here on top of upstream + small set of patches.. but once that is a bit more complete, experimenting with some of this will be on my TODO list to see what amount of crazy/complicated brings worthwhile performance benefits.
BR,
-R
Quoted 1 line
Thierry
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
In reply to Rob ClarkQuoted 102 lines · Rob Clark
Quoted 86 lines · Olav Haugan
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
Quoted 3 lines
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
What I mean by batching up is mapping and unmapping multiple sglists each at different iova's with minmal cpu cache and iommu tlb flushes..
Ideally we'd let the IOMMU driver be clever and build out all 2nd level tables before inserting into first level tables (to minimize cpu cache flushing).. also, there is probably a reasonable chance that we'd be mapping a new buffer into existing location, so there might be some potential to reuse existing 2nd level tables (and save a tiny bit of free/alloc). I've not thought too much about how that would look in code.. might be kinda, umm, fun..
Quoted 6 lines
But at an API level, we should be able to do a bunch of map/unmap_range's with one flush.
Maybe it could look like a sequence of iommu_{map,unmap}_range() followed by
iommu_flush()?
So we could add another argument ("options") in the range api that allows you to indicate whether you want to invalidate TLB or not.
Thanks,
Olav
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 106 lines · Olav Haugan
Quoted 105 lines · Rob Clark
Quoted 86 lines · Olav Haugan
Quoted 79 lines · Rob Clark
Quoted 65 lines · Olav Haugan
Hi Hiroshi,
Quoted 31 lines · Hiroshi Doyu
Hi Olav,
Quoted 27 lines · Olav Haugan
Mapping and unmapping are more often than not in the critical path.
map_rangeandunmap_rangeallows SMMU driver implementations to optimize the process of mapping and unmapping buffers into the SMMU page tables. Instead of mapping one physical address, do TLB operation (expensive), mapping, do TLB operation, mapping, do TLB operation the driver can map a scatter-gatherlist of physically contiguous pages into one virtual address space and then at the end do one TLB operation.Additionally, the mapping operation would be faster in general since clients does not have to keep calling map API over and over again for each physically contiguous chunk of memory that needs to be mapped to a virtually contiguous region.
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/iommu.c | 24 ++++++++++++++++++++++++ include/linux/iommu.h | 24 ++++++++++++++++++++++++ 2 files changed, 48 insertions(+)drivers/iommu/iommu.c +0
-0@@ -898,6 +898,30 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)EXPORT_SYMBOL_GPL (iommu_unmap);Quoted 14 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 911
Quoted 11 lines
drivers/iommu/iommu.c +11
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range);We have the similar one internally, which is named, "
iommu_map_sg()", called from DMA API.Great, so this new API will be useful to more people!
Quoted 5 lines
Quoted 5 lines
drivers/iommu/iommu.c +5
-0+int iommu_unmap_range (struct iommu_domain *domain,unsigned int iova, +unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ;Quoted 8 lines
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 922
Quoted 6 lines
drivers/iommu/iommu.c +6
-0+ +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Can the existing
iommu_unmap()do the same?Quoted 8 lines
I believe
iommu_unmap()behaves a bit differently because it will keep on callingdomain->ops->unmap()until everything is unmapped instead of letting the iommu implementation take care of unmapping everything in one call.I am abandoning the patch series since our driver was not accepted. However, if there are no objections I will resubmit this patch (PATCH 2/7) as an independent patch to add this new
map_rangeAPI.+1 for
map_range().. I've seen for gpu workloads, at least, it is the
downstreammap_range()API is quite beneficial. It was worth at
least a few fps in xonotic.Quoted 5 lines
And, possibly getting off the subject a bit, but I was wondering about the possibility of going one step further and batching up mapping and/or unmapping multiple buffers (ranges) at once. I have a pretty convenient sync point in drm/msm to flush out multiple mappings before kicking gpu.
Quoted 3 lines
I think you should be able to do that with this API already - at least the mapping part since we are passing in a sg list (this could be a chained sglist).
What I mean by batching up is mapping and unmapping multiple sglists each at different iova's with minmal cpu cache and iommu tlb flushes..
Ideally we'd let the IOMMU driver be clever and build out all 2nd level tables before inserting into first level tables (to minimize cpu cache flushing).. also, there is probably a reasonable chance that we'd be mapping a new buffer into existing location, so there might be some potential to reuse existing 2nd level tables (and save a tiny bit of free/alloc). I've not thought too much about how that would look in code.. might be kinda, umm, fun..
But at an API level, we should be able to do a bunch of map/unmap_range's with one flush.
Quoted 6 lines
Quoted 3 lines
Maybe it could look like a sequence of iommu_{map,unmap}_range() followed by
iommu_flush()?So we could add another argument ("options") in the range api that allows you to indicate whether you want to invalidate TLB or not.
sounds reasonable.. I'm pretty sure we want explict-flush to be an opt-in behaviour.
BR,
-R
Quoted 7 lines
Thanks,
Olav
--
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Joerg Roedel
maintainerPATCH 2/7 iommu-api: Add map_range/unmap_range functions
In reply to Olav HauganQuoted 13 lines · Olav Haugan
drivers/iommu/iommu.c +13
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range); + +int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,
drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 10 lines
drivers/iommu/iommu.c +10
-0+ unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);
Before introducing these new API functions there should be a fall-back for IOMMU drivers that do (not yet) implement the map_range and unmap_range call-backs.
The last thing we want is this kind of functional partitioning between different IOMMU drivers.
Joerg
PATCH 2/7 iommu-api: Add map_range/unmap_range functions
Quoted 29 lines · Joerg Roedel
Quoted 13 lines · Olav Haugan
drivers/iommu/iommu.c +13
-0+int iommu_map_range (struct iommu_domain *domain,unsigned int iova, +struct scatterlist *sg,unsigned int len,int prot) +{ +if (unlikely (domain->ops->map_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->map_range (domain, iova, sg, len, prot); +} +EXPORT_SYMBOL_GPL (iommu_map_range); + +int iommu_unmap_range(struct iommu_domain *domain, unsigned int iova,drivers/iommu/iommu.c size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size) · line 923
Quoted 10 lines
drivers/iommu/iommu.c +10
-0+ unsigned int len) +{ +if (unlikely (domain->ops->unmap_range ==NULL )) +return -ENODEV ; + +BUG_ON (iova & (~PAGE_MASK )); + +return domain->ops->unmap_range (domain, iova, len); +} +EXPORT_SYMBOL_GPL (iommu_unmap_range);Before introducing these new API functions there should be a fall-back for IOMMU drivers that do (not yet) implement the
map_rangeandunmap_rangecall-backs.
Quoted 2 lines
The last thing we want is this kind of functional partitioning between different IOMMU drivers.
Yes, I can definitely add a fallback instead of returning -ENODEV.
Thanks,
Olav
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 3/7 iopoll: Introduce memory-mapped IO polling macros
In reply to Olav HauganFrom: Matt Wagantall <[email protected]>
It is sometimes necessary to poll a memory-mapped register until its value satisfies some condition. Introduce a family of convenience macros that do this. Tight-loop and sleeping versions are provided with and without timeouts.
--- include/linux/iopoll.h | 114 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 include/linux/iopoll.h
include/linux/iopoll.h new file +114 -0
@@ -0,0 +1,114 @@ +/* +* Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 2 and +* only version 2 as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +*/ + +#ifndef _LINUX_IOPOLL_H +#define _LINUX_IOPOLL_H + +#include <linux/kernel.h> +#include <linux/types.h> +#include <linux/hrtimer.h> +#include <linux/delay.h> +#include <asm-generic/errno.h> +#include <asm/io.h> + +/** +* readl_poll_timeout - Periodically poll an address until a condition is met or a timeout occurs +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops) +* @timeout_us: Timeout in uS, 0 means never timeout +* +* Returns 0 on success and -ETIMEDOUT upon a timeout. In either +* case, the last read value at @addr is stored in @val. Must not +* be called from atomic context if sleep_us or timeout_us are used. +*/ +#define readl_poll_timeout (addr, val, cond, sleep_us, timeout_us) \ +({ \ + ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ + might_sleep_if(timeout_us); \ + for (;;) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ + (val) = readl(addr); \ + break; \ + } \ + if (sleep_us) \ + usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +/** +* readl_poll_timeout_noirq - Periodically poll an address until a condition is met or a timeout occurs +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @max_reads: Maximum number of reads before giving up +* @time_between_us: Time to udelay() between successive reads +* +* Returns 0 on success and -ETIMEDOUT upon a timeout. +*/ +#define readl_poll_timeout_noirq (addr, val, cond, max_reads, time_between_us) \ +({ \ + int count; \ + for (count = (max_reads); count > 0; count--) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + udelay(time_between_us); \ + } \ + (cond) ? 0 : -ETIMEDOUT; \ +}) + +/** +* readl_poll - Periodically poll an address until a condition is met +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops) +* +* Must not be called from atomic context if sleep_us is used. +*/ +#define readl_poll (addr, val, cond, sleep_us) \ + readl_poll_timeout(addr, val, cond, sleep_us, 0) + +/** +* readl_tight_poll_timeout - Tight-loop on an address until a condition is met or a timeout occurs +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @timeout_us: Timeout in uS, 0 means never timeout +* +* Returns 0 on success and -ETIMEDOUT upon a timeout. In either +* case, the last read value at @addr is stored in @val. Must not +* be called from atomic context if timeout_us is used. +*/ +#define readl_tight_poll_timeout (addr, val, cond, timeout_us) \ + readl_poll_timeout(addr, val, cond, 0, timeout_us) + +/** +* readl_tight_poll - Tight-loop on an address until a condition is met +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* +* May be called from atomic context. +*/ +#define readl_tight_poll (addr, val, cond) \ + readl_poll_timeout(addr, val, cond, 0, 0) + +#endif /* _LINUX_IOPOLL_H */
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 3/7 iopoll: Introduce memory-mapped IO polling macros
On Mon, Jun 30, 2014 at 09:51:52AM -0700, Olav Haugan wrote:
[...]
Quoted 1 line
include/linux/iopoll.h +0
-0
[...]
Quoted 6 lines
+/**
+ *readl_poll_timeout- Periodically poll an address until a condition is met or a timeout occurs
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops)
s/uS/us/ here and elsewhere. S is the symbol for Siemens.
Quoted 13 lines
+ * @timeout_us: Timeout in uS, 0 means never timeout
+ *
+ * Returns 0 on success and-ETIMEDOUTupon a timeout. In either
+ * case, the last read value at @addr is stored in @val. Must not
+ * be called from atomic context ifsleep_usortimeout_usare used.
+ */include/linux/iopoll.h +7
-0+#define readl_poll_timeout (addr, val, cond, sleep_us, timeout_us) \ +({ \ + ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ + might_sleep_if(timeout_us); \ + for (;;) { \ + (val) = readl(addr); \ + if (cond) \
include/linux/iopoll.h line 53
Quoted 10 lines
include/linux/iopoll.h +10
-0+break ; \ +if (timeout_us &&ktime_compare (ktime_get (), timeout) >0 ) { \ + (val) =readl (addr); \ +break ; \ + } \ +if (sleep_us) \ +usleep_range (DIV_ROUND_UP (sleep_us,4 ), sleep_us); \ + } \ + (cond) ?0 : -ETIMEDOUT ; \ +})
Why can't these be functions?
Thierry
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20140630/67f196b9/attachment.sig>
PATCH 3/7 iopoll: Introduce memory-mapped IO polling macros
In reply to Olav HauganHi Matt,
Quoted 6 lines · Olav Haugan
From: Matt Wagantall <[email protected]>
It is sometimes necessary to poll a memory-mapped register until its value satisfies some condition. Introduce a family of convenience macros that do this. Tight-loop and sleeping versions are provided with and without timeouts.
We could certainly use something like this in the SMMU and GICv3 drivers, so I agree that it makes sense for this to be in generic code.
Quoted 7 lines
+/**
+ *readl_poll_timeout- Periodically poll an address until a condition is met or a timeout occurs
+ * @addr: Address to poll
+ * @val: Variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops)
+ * @timeout_us: Timeout in uS, 0 means never timeout
I think 0 should actually mean `use the default timeout', which could be something daft like 1s. Removing the timeout is asking for kernel lock-ups. We could also have a version without the timeout parameter at all, which acts like a timeout of 0.
Quoted 19 lines
+ *
+ * Returns 0 on success and-ETIMEDOUTupon a timeout. In either
+ * case, the last read value at @addr is stored in @val. Must not
+ * be called from atomic context ifsleep_usortimeout_usare used.
+ */include/linux/iopoll.h new file +14
-0+#define readl_poll_timeout (addr, val, cond, sleep_us, timeout_us) \ +({ \ + ktime_t timeout = ktime_add_us(ktime_get(), timeout_us); \ + might_sleep_if(timeout_us); \ + for (;;) { \ + (val) = readl(addr); \ + if (cond) \ + break; \ + if (timeout_us && ktime_compare(ktime_get(), timeout) > 0) { \ + (val) = readl(addr); \ + break; \ + } \ + if (sleep_us) \ + usleep_range(DIV_ROUND_UP(sleep_us, 4), sleep_us); \
include/linux/iopoll.h line 60
Quoted 10 lines
include/linux/iopoll.h new file +10
-0+ } \ + (cond) ?0 : -ETIMEDOUT ; \ +}) + +/** +* readl_poll_timeout_noirq - Periodically poll an address until a condition is met or a timeout occurs +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @max_reads: Maximum number of reads before giving up
I don't think max_reads is a useful tunable.
Quoted 5 lines
+ * @time_between_us: Time to
udelay()between successive reads
+ *
+ * Returns 0 on success and-ETIMEDOUTupon a timeout.
+ */
+#definereadl_poll_timeout_noirq(addr, val, cond, max_reads, time_between_us)\
Maybe readl_poll_[timeout_]atomic is a better name?
Quoted 12 lines
include/linux/iopoll.h new file +12
-0+({ \ +int count; \ +for (count = (max_reads); count >0 ; count--) { \ + (val) =readl (addr); \ +if (cond) \ +break ; \ +udelay (time_between_us); \ + } \ + (cond) ?0 : -ETIMEDOUT ; \ +}) + +/**
include/linux/iopoll.h line 87
Quoted 10 lines
include/linux/iopoll.h new file +10
-0+* readl_poll - Periodically poll an address until a condition is met +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @sleep_us: Maximum time to sleep between reads in uS (0 tight-loops) +* +* Must not be called from atomic context if sleep_us is used. +*/ +#define readl_poll (addr, val, cond, sleep_us) \ + readl_poll_timeout(addr, val, cond, sleep_us, 0)
Good idea ;)
Quoted 14 lines
include/linux/iopoll.h new file +14
-0+/** +* readl_tight_poll_timeout - Tight-loop on an address until a condition is met or a timeout occurs +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* @timeout_us: Timeout in uS, 0 means never timeout +* +* Returns 0 on success and -ETIMEDOUT upon a timeout. In either +* case, the last read value at @addr is stored in @val. Must not +* be called from atomic context if timeout_us is used. +*/ +#define readl_tight_poll_timeout (addr, val, cond, timeout_us) \ + readl_poll_timeout(addr, val, cond, 0, timeout_us) +
include/linux/iopoll.h line 112
Quoted 10 lines
include/linux/iopoll.h new file +10
-0+/** +* readl_tight_poll - Tight-loop on an address until a condition is met +* @addr: Address to poll +* @val: Variable to read the value into +* @cond: Break condition (usually involving @val) +* +* May be called from atomic context. +*/ +#define readl_tight_poll (addr, val, cond) \ + readl_poll_timeout(addr, val, cond, 0, 0)
This would be readl_poll_timeout_atomic if you went with my suggestion (i.e. readl_poll_timeout would have an unconditional might_sleep).
What do you reckon?
Will
A message that is not in the archive (sent off-list or not yet received): 1404147116-4598-1-git-send-email-ohaugan-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org
PATCH 4/7 iommu: msm: Add MSM IOMMUv1 driver
MSM IOMMUv1 driver supports Qualcomm SoC MSM8974 and MSM8084.
The IOMMU driver supports the following features:
- ARM V7S page table format independent of ARM CPU page table format
- 4K/64K/1M/16M mappings (V7S)
- ATOS used for unit testing of driver
- Sharing of page tables among SMMUs
- Verbose context bank fault reporting
- Verbose global fault reporting
- Support for clocks and GDSC
- map/unmap range
- Domain specific enabling of coherent Hardware Table Walk (HTW)
--- .../devicetree/bindings/iommu/msm,iommu_v1.txt | 56 + drivers/iommu/Kconfig | 36 + drivers/iommu/Makefile | 2 + drivers/iommu/msm_iommu-v1.c | 1448 +++++++++++++ drivers/iommu/msm_iommu.c | 149 ++ drivers/iommu/msm_iommu_dev-v1.c | 340 +++ drivers/iommu/msm_iommu_hw-v1.h | 2236 ++++++++++++++++++++ drivers/iommu/msm_iommu_pagetable.c | 600 ++++++ drivers/iommu/msm_iommu_pagetable.h | 33 + drivers/iommu/msm_iommu_priv.h | 55 + include/linux/qcom_iommu.h | 221 ++ 11 files changed, 5176 insertions(+) create mode 100644 Documentation/devicetree/bindings/iommu/msm,iommu_v1.txt create mode 100644 drivers/iommu/msm_iommu-v1.c create mode 100644 drivers/iommu/msm_iommu.c create mode 100644 drivers/iommu/msm_iommu_dev-v1.c create mode 100644 drivers/iommu/msm_iommu_hw-v1.h create mode 100644 drivers/iommu/msm_iommu_pagetable.c create mode 100644 drivers/iommu/msm_iommu_pagetable.h create mode 100644 drivers/iommu/msm_iommu_priv.h create mode 100644 include/linux/qcom_iommu.h
Documentation/devicetree/bindings/iommu/msm,iommu_v1.txt new file +56 -0
@@ -0,0 +1,56 @@ +* Qualcomm MSM IOMMU v1 + +Required properties: +- compatible : + - "qcom,msm-smmu-v1" +- reg : - offset and length of the register set for the device. + - Optional offset and length for clock halt register that + needs to be turned on for access to this IOMMU. +- reg-names: "iommu_base", "clk_halt_reg_base" (optional) +- #global-interrupts : The number of global interrupts exposed by the + device. +- interrupts : Interrupt list, with the first #global-irqs entries + corresponding to the global interrupts and any + following entries corresponding to context interrupts, + specified in order of their indexing by the SMMU. + +Optional properties: +- label: Symbolic name for this IOMMU instance used for debugging purposes. + For example when a page fault occurs on the jpeg iommu the text + "jpeg_iommu" will be printed letting people know which IOMMU is complaining. +- qcom,vdd-supply: Regulator needed to access IOMMU +- qcom,alt-vdd-supply : Alternative regulator needed to access IOMMU + configuration registers. +- qcom,iommu-bfb-regs : An array of unsigned 32-bit integers corresponding to + Burst Fetch Buffers (BFB) register addresses that need to be configured + for performance tuning purposes. BFB holds cached values of TLB/PTE entries + in the SMMU. BFB registers controls the configuration of the TLB/PTE fetching + mechanism in the SMMU. In general these values comes from performance + modelling team. + If this property is present, the qcom,iommu-bfb-data must also be + present. Register addresses are specified as an offset from the base of the + IOMMU hardware block. This property may be omitted if no BFB register + configuration needs to be done for a particular IOMMU hardware instance. The + registers specified by this property shall fall within the IOMMU + implementation-defined register region. +- qcom,iommu-bfb-data : An array of unsigned 32-bit integers representing the + values to be programmed into the corresponding registers given by the + qcom,iommu-bfb-regs property. If this property is present, the + qcom,iommu-bfb-regs property shall also be present, and the lengths of both + properties shall be the same. + +Example: + + qcom,iommu@fda64000 { + compatible = "qcom,msm-smmu-v1"; + reg = <0xfda64000 0x10000>; + reg-names = "iommu_base"; + vdd-supply = <&gdsc_iommu>; + qcom,iommu-bfb-regs = <0x204c 0x2050>; + qcom,iommu-bfb-data = <0xffff 0xffce>; + label = "iommu_0"; + #global-interrupts = <2>; + interrupts = <0 229 0>, + <0 231 0>, + <0 70 0>; + };
drivers/iommu/Kconfig +36 -0
@@ -50,6 +50,42 @@ config IOMMU_PGTABLES_L2 def_bool y depends on MSM_IOMMU && MMU && SMP && CPU_DCACHE_DISABLE=n +# MSM IOMMUv1 support +config MSM_IOMMU_V1 + bool "MSM IOMMUv1 Support" + depends on ARCH_MSM8974 || ARCH_MSM8226 || ARCH_APQ8084 || ARCH_MSM8994 + select IOMMU_API + select MSM_IOMMU + help + Support for the IOMMUs (v1) found on certain Qualcomm SOCs. + These IOMMUs allow virtualization of the address space used by most + cores within the multimedia subsystem. + + If unsure, say N here. + +config MSM_IOMMU_VBIF_CHECK + bool "Enable support for VBIF check when IOMMU gets stuck" + depends on MSM_IOMMU + help + Utilize the Virtual Bus Interface (VBIF) to get more debug + information. Enables an extra check in the IOMMU driver that logs + debugging information when TLB sync or iommu halt issue occurs. + This helps in debugging such issues. + + If unsure, say N here. + +config IOMMU_FORCE_4K_MAPPINGS + bool "Turns off mapping optimization and map only 4K pages" + depends on MSM_IOMMU + help + Say Y here if you want the IOMMU driver to map buffers with + 4KB mapping only. With this, we don't get performance gains + by optimizing mapping. This is a debug feature and should be + used only when we want to profile the performance in the + worst case scenario. + + If unsure, say N here. + # AMD IOMMU support config AMD_IOMMU bool "AMD IOMMU support"
drivers/iommu/Makefile +2 -0
@@ -2,6 +2,8 @@ obj-$(CONFIG_IOMMU_API) += iommu.o obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU_V0) += msm_iommu-v0.o msm_iommu_dev-v0.o +obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu.o +obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu_pagetable.o obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
drivers/iommu/msm_iommu-v1.c new file +1448 -0
1,448 lines not on this page · raw message
drivers/iommu/msm_iommu.c new file +149 -0
149 lines not on this page · raw message
drivers/iommu/msm_iommu_dev-v1.c new file +340 -0
340 lines not on this page · raw message
drivers/iommu/msm_iommu_hw-v1.h new file +2236 -0
957 lines not on this page · raw message
drivers/iommu/msm_iommu_pagetable.c new file +600 -0
600 lines not on this page · raw message
drivers/iommu/msm_iommu_pagetable.h new file +33 -0
Lines of this file are not shown. View the raw message.
drivers/iommu/msm_iommu_priv.h new file +55 -0
55 lines not on this page · raw message
include/linux/qcom_iommu.h new file +221 -0
221 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
Part of the diff is not shown here. View the raw message.
PATCH 4/7 iommu: msm: Add MSM IOMMUv1 driver
Hi Olav,
Quoted 16 lines · Olav Haugan
MSM IOMMUv1 driver supports Qualcomm SoC MSM8974 and MSM8084.
The IOMMU driver supports the following features:
- ARM V7S page table format independent of ARM CPU page table format
- 4K/64K/1M/16M mappings (V7S)
- ATOS used for unit testing of driver
- Sharing of page tables among SMMUs
- Verbose context bank fault reporting
- Verbose global fault reporting
- Support for clocks and GDSC
- map/unmap range
- Domain specific enabling of coherent Hardware Table Walk (HTW)Signed-off-by Olav Haugan <[email protected]>
Quoted 13 lines
--- .../devicetree/bindings/iommu/msm,iommu_v1.txt | 56 + drivers/iommu/Kconfig | 36 + drivers/iommu/Makefile | 2 + drivers/iommu/msm_iommu-v1.c | 1448 +++++++++++++ drivers/iommu/msm_iommu.c | 149 ++ drivers/iommu/msm_iommu_dev-v1.c | 340 +++ drivers/iommu/msm_iommu_hw-v1.h | 2236 ++++++++++++++++++++ drivers/iommu/msm_iommu_pagetable.c | 600 ++++++ drivers/iommu/msm_iommu_pagetable.h | 33 + drivers/iommu/msm_iommu_priv.h | 55 + include/linux/qcom_iommu.h | 221 ++ 11 files changed, 5176 insertions(+)
This patch is *huge*! It may get bounced from some lists (I think the linux-arm-kernel lists has a ~100k limit), so it might be worth trying to do this incrementally.
That said, a quick glance at your code indicates that this IOMMU is compliant with the ARM SMMU architecture, and we already have a driver for that. Please can you rework this series to build on top of the code in mainline already, rather than simply duplicating it? We need fewer IOMMU drivers, not more!
It's also worth talking to Varun Sethi, as he was already looking at implementing block mappings in the existing driver.
Thanks,
Will
PATCH 4/7 iommu: msm: Add MSM IOMMUv1 driver
Quoted 33 lines · Will Deacon
Hi Olav,
Quoted 16 lines · Olav Haugan
MSM IOMMUv1 driver supports Qualcomm SoC MSM8974 and MSM8084.
The IOMMU driver supports the following features:
- ARM V7S page table format independent of ARM CPU page table format
- 4K/64K/1M/16M mappings (V7S)
- ATOS used for unit testing of driver
- Sharing of page tables among SMMUs
- Verbose context bank fault reporting
- Verbose global fault reporting
- Support for clocks and GDSC
- map/unmap range
- Domain specific enabling of coherent Hardware Table Walk (HTW)Signed-off-by Olav Haugan <[email protected]>Quoted 13 lines
--- .../devicetree/bindings/iommu/msm,iommu_v1.txt | 56 + drivers/iommu/Kconfig | 36 + drivers/iommu/Makefile | 2 + drivers/iommu/msm_iommu-v1.c | 1448 +++++++++++++ drivers/iommu/msm_iommu.c | 149 ++ drivers/iommu/msm_iommu_dev-v1.c | 340 +++ drivers/iommu/msm_iommu_hw-v1.h | 2236 ++++++++++++++++++++ drivers/iommu/msm_iommu_pagetable.c | 600 ++++++ drivers/iommu/msm_iommu_pagetable.h | 33 + drivers/iommu/msm_iommu_priv.h | 55 + include/linux/qcom_iommu.h | 221 ++ 11 files changed, 5176 insertions(+)
Quoted 3 lines
This patch is *huge*! It may get bounced from some lists (I think the linux-arm-kernel lists has a ~100k limit), so it might be worth trying to do this incrementally.
Yes, I noticed. Sorry about that.
Quoted 5 lines
That said, a quick glance at your code indicates that this IOMMU is compliant with the ARM SMMU architecture, and we already have a driver for that. Please can you rework this series to build on top of the code in mainline already, rather than simply duplicating it? We need fewer IOMMU drivers, not more!
Ok, I will rework.
Thanks,
Olav Haugan
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 5/7 iommu: msm: Add support for V7L page table format
In reply to Olav HauganAdd support for VMSA long descriptor page table format (V7L) supporting the following features:
- ARM V7L page table format independent of ARM CPU page table format
- 4K/64K/2M/32M/1G mappings (V7L)
--- .../devicetree/bindings/iommu/msm,iommu_v1.txt | 4 + drivers/iommu/Kconfig | 10 + drivers/iommu/Makefile | 4 + drivers/iommu/msm_iommu-v1.c | 65 ++ drivers/iommu/msm_iommu.c | 47 ++ drivers/iommu/msm_iommu_dev-v1.c | 5 + drivers/iommu/msm_iommu_hw-v1.h | 86 +++ drivers/iommu/msm_iommu_pagetable_lpae.c | 717 +++++++++++++++++++++ drivers/iommu/msm_iommu_priv.h | 12 +- 9 files changed, 949 insertions(+), 1 deletion(-) create mode 100644 drivers/iommu/msm_iommu_pagetable_lpae.c
Documentation/devicetree/bindings/iommu/msm,iommu_v1.txt +4 -0
@@ -38,6 +38,10 @@ Optional properties: qcom,iommu-bfb-regs property. If this property is present, the qcom,iommu-bfb-regs property shall also be present, and the lengths of both properties shall be the same. +- qcom,iommu-lpae-bfb-regs : See description for qcom,iommu-bfb-regs. This is + the same property except this is for IOMMU with LPAE enabled. +- qcom,iommu-lpae-bfb-data : See description for qcom,iommu-bfb-data. This is + the same property except this is for IOMMU with LPAE enabled. Example:
drivers/iommu/Kconfig +10 -0
@@ -63,6 +63,16 @@ config MSM_IOMMU_V1 If unsure, say N here. +config MSM_IOMMU_LPAE + bool "Enable support for LPAE in IOMMU" + depends on MSM_IOMMU + help + Enables Large Physical Address Extension (LPAE) for IOMMU. This allows + clients of IOMMU to access physical addresses that are greater than + 32 bits. + + If unsure, say N here. + config MSM_IOMMU_VBIF_CHECK bool "Enable support for VBIF check when IOMMU gets stuck" depends on MSM_IOMMU
drivers/iommu/Makefile +4 -0
@@ -3,7 +3,11 @@ obj-$(CONFIG_IOMMU_API) += iommu-traces.o obj-$(CONFIG_OF_IOMMU) += of_iommu.o obj-$(CONFIG_MSM_IOMMU_V0) += msm_iommu-v0.o msm_iommu_dev-v0.o obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu-v1.o msm_iommu_dev-v1.o msm_iommu.o +ifdef CONFIG_MSM_IOMMU_LPAE +obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu_pagetable_lpae.o +else obj-$(CONFIG_MSM_IOMMU_V1) += msm_iommu_pagetable.o +endif obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o obj-$(CONFIG_ARM_SMMU) += arm-smmu.o
drivers/iommu/msm_iommu-v1.c +65 -0
119 lines not on this page · raw message
drivers/iommu/msm_iommu.c +47 -0
66 lines not on this page · raw message
drivers/iommu/msm_iommu_dev-v1.c +5 -0
@@ -28,8 +28,13 @@#include "msm_iommu_hw-v1.h" +#ifdef CONFIG_MSM_IOMMU_LPAE +static const char *BFB_REG_NODE_NAME ="qcom,iommu-lpae-bfb-regs" ; +static const char *BFB_DATA_NODE_NAME ="qcom,iommu-lpae-bfb-data" ; +#else static const char *BFB_REG_NODE_NAME ="qcom,iommu-bfb-regs" ;static const char *BFB_DATA_NODE_NAME ="qcom,iommu-bfb-data" ; +#endif static int msm_iommu_parse_bfb_settings (struct platform_device *pdev,struct msm_iommu_drvdata *drvdata)
drivers/iommu/msm_iommu_hw-v1.h +86 -0
139 lines not on this page · raw message
drivers/iommu/msm_iommu_pagetable_lpae.c new file +717 -0
717 lines not on this page · raw message
drivers/iommu/msm_iommu_priv.h +11 -1
@@ -31,13 +31,23 @@* clients trying to unmap an address that is being used. * fl_table_shadow will use the lower 9 bits for the use count and the upper * bits for the second level page table address. +* sl_table_shadow uses the same concept as fl_table_shadow but for LPAE 2nd +* level page tables. */ +#ifdef CONFIG_MSM_IOMMU_LPAE +struct msm_iommu_pt { +u64 *fl_table; +u64 **sl_table_shadow; +int redirect; +u64 *unaligned_fl_table; +}; +#else struct msm_iommu_pt {u32 *fl_table;int redirect;u32 *fl_table_shadow; }; - +#endif /** * struct msm_iommu_priv - Container for page table attributes and other * private iommu domain information.
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 6/7 defconfig: msm: Enable Qualcomm SMMUv1 driver
In reply to Olav HauganEnable the Qualcomm SMMUv1 driver allowing bus masters to operate on physically discontigous memory.
--- arch/arm/configs/qcom_defconfig | 1 + 1 file changed, 1 insertion(+)
arch/arm/configs/qcom_defconfig +1 -0
@@ -137,6 +137,7 @@ CONFIG_MSM_GCC_8660=y CONFIG_MSM_MMCC_8960=y CONFIG_MSM_MMCC_8974=y CONFIG_MSM_IOMMU_V0=y +CONFIG_MSM_IOMMU_V1=y CONFIG_GENERIC_PHY=y CONFIG_EXT2_FS=y CONFIG_EXT2_FS_XATTR=y
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 7/7 iommu-api: Add domain attribute to enable coherent HTW
In reply to Olav HauganAdd a new iommu domain attribute that can be used to enable cache coherent hardware table walks (HTW) by the SMMU. HTW might be supported by the SMMU HW but depending on the use case and the usage of the SMMU in the SoC it might not be always beneficial to always turn on coherent HTW for all domains/iommu's.
--- drivers/iommu/msm_iommu-v1.c | 16 ++++++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 17 insertions(+)
drivers/iommu/msm_iommu-v1.c +16 -0
@@ -1456,8 +1456,16 @@ static int msm_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { s32 ret = 0; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + *int_ptr = priv->pt.redirect; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;
@@ -1471,8 +1479,16 @@ static int msm_domain_set_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) { s32 ret = 0; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + priv->pt.redirect = *int_ptr; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;
include/linux/iommu.h +1 -0
@@ -81,6 +81,7 @@ enum iommu_attr {DOMAIN_ATTR_FSL_PAMU_STASH ,DOMAIN_ATTR_FSL_PAMU_ENABLE ,DOMAIN_ATTR_FSL_PAMUV1 , +DOMAIN_ATTR_COHERENT_HTW , DOMAIN_ATTR_MAX, };
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 7/7 iommu-api: Add domain attribute to enable coherent HTW
Quoted 13 lines
-----Original Message-----
From: iommu-bounces at lists.linux-foundation.org [mailto:iommu- bounces at lists.linux-foundation.org] On Behalf Of Olav Haugan
Sent: Monday, June 30, 2014 10:22 PM
To: linux-arm-kernel at lists.infradead.org; iommu at lists.linux- foundation.org
Cc: linux-arm-msm at vger.kernel.org; will.deacon at arm.com; thierry.reding at gmail.com; vgandhi at codeaurora.org
Subject: [RFC/PATCH 7/7] iommu-api: Add domain attribute to enable coherent HTW
Quoted 6 lines
Add a new iommu domain attribute that can be used to enable cache coherent hardware table walks (HTW) by the SMMU. HTW might be supported by the SMMU HW but depending on the use case and the usage of the SMMU in the SoC it might not be always beneficial to always turn on coherent HTW for all domains/iommu's.
[Sethi Varun-B16395] Why won't you want to use the coherent table walk feature?
Quoted 49 lines
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/msm_iommu-v1.c | 16 ++++++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 17 insertions(+)drivers/iommu/msm_iommu-v1.c +16
-0@@ -1456,8 +1456,16 @@ static int msm_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) {s32 ret =0 ; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + *int_ptr = priv->pt.redirect; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;@@ -1471,8 +1479,16 @@ static int msm_domain_set_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) {s32 ret =0 ; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + priv->pt.redirect = *int_ptr; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;include/linux/iommu.h index renamed from include/linux/iommu.h +0
-063dca6d..6d9596d 100644
include/linux/iommu.h enum iommu_attr { · line 84
Quoted 4 lines
include/linux/iommu.h +1
-0@@ -81,6 +81,7 @@ enum iommu_attr {DOMAIN_ATTR_FSL_PAMU_STASH ,DOMAIN_ATTR_FSL_PAMU_ENABLE ,DOMAIN_ATTR_FSL_PAMUV1 , + DOMAIN_ATTR_COHERENT_HTW,
[Sethi Varun-B16395] Would it make sense to represent this as DOMAIN_ATTR_SMMU_COHERENT_HTW? I believe this is specific to SMMU.
-Varun
PATCH 7/7 iommu-api: Add domain attribute to enable coherent HTW
Quoted 13 lines · Varun Sethi
Quoted 13 lines
-----Original Message-----
From: iommu-bounces at lists.linux-foundation.org [mailto:iommu- bounces at lists.linux-foundation.org] On Behalf Of Olav Haugan
Sent: Monday, June 30, 2014 10:22 PM
To: linux-arm-kernel at lists.infradead.org; iommu at lists.linux- foundation.org
Cc: linux-arm-msm at vger.kernel.org; will.deacon at arm.com; thierry.reding at gmail.com; vgandhi at codeaurora.org
Subject: [RFC/PATCH 7/7] iommu-api: Add domain attribute to enable coherent HTW
Quoted 7 lines
Quoted 6 lines
Add a new iommu domain attribute that can be used to enable cache coherent hardware table walks (HTW) by the SMMU. HTW might be supported by the SMMU HW but depending on the use case and the usage of the SMMU in the SoC it might not be always beneficial to always turn on coherent HTW for all domains/iommu's.
[Sethi Varun-B16395] Why won't you want to use the coherent table walk feature?
Very good question. We have found that turning on IOMMU coherent HTW is not always beneficial to performance (performance either the same or slightly worse in some cases). Even if the perf. is the same we would like to avoid using precious L2 cache for no benefit to the IOMMU. Although our HW supports this feature we don't always want to turn this on for a specific use case/domain (bus master).
Quoted 46 lines
Quoted 46 lines
Signed-off-by Olav Haugan <[email protected]>--- drivers/iommu/msm_iommu-v1.c | 16 ++++++++++++++++ include/linux/iommu.h | 1 + 2 files changed, 17 insertions(+)drivers/iommu/msm_iommu-v1.c +16
-0@@ -1456,8 +1456,16 @@ static int msm_domain_get_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) {s32 ret =0 ; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + *int_ptr = priv->pt.redirect; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;@@ -1471,8 +1479,16 @@ static int msm_domain_set_attr(struct iommu_domain *domain, enum iommu_attr attr, void *data) {s32 ret =0 ; +struct msm_iommu_priv *priv = domain->priv;switch (attr) { +case DOMAIN_ATTR_COHERENT_HTW : + { +s32 *int_ptr = (s32 *) data; + + priv->pt.redirect = *int_ptr; +break ; + }default :pr_err ("Unsupported attribute type\n" ); ret = -EINVAL ;include/linux/iommu.h index renamed from include/linux/iommu.h +0
-063dca6d..6d9596d 100644
Quoted 8 lines
include/linux/iommu.h enum iommu_attr { · line 84
Quoted 7 lines
include/linux/iommu.h +1
-0@@ -81,6 +81,7 @@ enum iommu_attr {DOMAIN_ATTR_FSL_PAMU_STASH ,DOMAIN_ATTR_FSL_PAMU_ENABLE ,DOMAIN_ATTR_FSL_PAMUV1 , + DOMAIN_ATTR_COHERENT_HTW,[Sethi Varun-B16395] Would it make sense to represent this as
DOMAIN_ATTR_SMMU_COHERENT_HTW? I believe this is specific to SMMU.
Yes, it does.
Thanks,
Olav Haugan
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation
PATCH 7/7 iommu-api: Add domain attribute to enable coherent HTW
Quoted 20 lines · Olav Haugan
Quoted 19 lines · Varun Sethi
Quoted 19 lines
-----Original Message-----
From: iommu-bounces at lists.linux-foundation.org [mailto:iommu- bounces at lists.linux-foundation.org] On Behalf Of Olav Haugan
Sent: Monday, June 30, 2014 10:22 PM
To: linux-arm-kernel at lists.infradead.org; iommu at lists.linux- foundation.org
Cc: linux-arm-msm at vger.kernel.org; will.deacon at arm.com; thierry.reding at gmail.com; vgandhi at codeaurora.org
Subject: [RFC/PATCH 7/7] iommu-api: Add domain attribute to enable coherent HTWAdd a new iommu domain attribute that can be used to enable cache coherent hardware table walks (HTW) by the SMMU. HTW might be supported by the SMMU HW but depending on the use case and the usage of the SMMU in the SoC it might not be always beneficial to always turn on coherent HTW for all domains/iommu's.
Quoted 8 lines
Quoted 1 line
[Sethi Varun-B16395] Why won't you want to use the coherent table walk feature?
Very good question. We have found that turning on IOMMU coherent HTW is not always beneficial to performance (performance either the same or slightly worse in some cases). Even if the perf. is the same we would like to avoid using precious L2 cache for no benefit to the IOMMU. Although our HW supports this feature we don't always want to turn this on for a specific use case/domain (bus master).
Could we at least invert the feature flag, please? i.e. you set an attribute to *disable* coherent walks? I'd also be interested to see some performance numbers, as the added cacheflushing overhead from non-coherent walks is going to be non-trivial.
Will
PATCH 7/7 iommu-api: Add domain attribute to enable coherent HTW
Quoted 30 lines · Will Deacon
Quoted 20 lines · Olav Haugan
Quoted 19 lines · Varun Sethi
Quoted 19 lines
-----Original Message-----
From: iommu-bounces at lists.linux-foundation.org [mailto:iommu- bounces at lists.linux-foundation.org] On Behalf Of Olav Haugan
Sent: Monday, June 30, 2014 10:22 PM
To: linux-arm-kernel at lists.infradead.org; iommu at lists.linux- foundation.org
Cc: linux-arm-msm at vger.kernel.org; will.deacon at arm.com; thierry.reding at gmail.com; vgandhi at codeaurora.org
Subject: [RFC/PATCH 7/7] iommu-api: Add domain attribute to enable coherent HTWAdd a new iommu domain attribute that can be used to enable cache coherent hardware table walks (HTW) by the SMMU. HTW might be supported by the SMMU HW but depending on the use case and the usage of the SMMU in the SoC it might not be always beneficial to always turn on coherent HTW for all domains/iommu's.
Quoted 8 lines
Quoted 1 line
[Sethi Varun-B16395] Why won't you want to use the coherent table walk feature?
Very good question. We have found that turning on IOMMU coherent HTW is not always beneficial to performance (performance either the same or slightly worse in some cases). Even if the perf. is the same we would like to avoid using precious L2 cache for no benefit to the IOMMU. Although our HW supports this feature we don't always want to turn this on for a specific use case/domain (bus master).
Quoted 5 lines
Could we at least invert the feature flag, please? i.e. you set an attribute to *disable* coherent walks? I'd also be interested to see some performance numbers, as the added cacheflushing overhead from non-coherent walks is going to be non-trivial.
Yes, agree that we can do the inverse. On one SoC I saw about 5% degradation in performance with coherent table walk enabled for a specific bus master. However, we have seen improved performance also with other SMMUs/bus masters. It just depends on the SMMU/bus master and how it is being used. Hence the need to be able to disable this on a per-domain basis.
Thanks,
Olav Haugan
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, hosted by The Linux Foundation