Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1511281 > unrolled thread

[PATCH v3 0/6] sparc: Enable sun4v hypervisor PCI IOMMU v2 APIs and ATU

Started byTushar Dave <tushar.n.dave@oracle.com>
First post2016-10-28 19:20 +0200
Last post2016-10-28 19:20 +0200
Articles 3 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH v3 0/6] sparc: Enable sun4v hypervisor PCI IOMMU v2 APIs and ATU Tushar Dave <tushar.n.dave@oracle.com> - 2016-10-28 19:20 +0200
    [PATCH v3 6/6] sparc64: Enable 64-bit DMA Tushar Dave <tushar.n.dave@oracle.com> - 2016-10-28 19:20 +0200
    [PATCH v3 4/6] sparc64: Bind PCIe devices to use IOMMU v2 service Tushar Dave <tushar.n.dave@oracle.com> - 2016-10-28 19:20 +0200

#1511281 — [PATCH v3 0/6] sparc: Enable sun4v hypervisor PCI IOMMU v2 APIs and ATU

FromTushar Dave <tushar.n.dave@oracle.com>
Date2016-10-28 19:20 +0200
Subject[PATCH v3 0/6] sparc: Enable sun4v hypervisor PCI IOMMU v2 APIs and ATU
Message-ID<sxiYW-2LI-5@gated-at.bofh.it>
ATU (Address Translation Unit) is a new IOMMU in SPARC supported with
sun4v hypervisor PCI IOMMU v2 APIs.

Current SPARC IOMMU supports only 32bit address ranges and one TSB
per PCIe root complex that has a 2GB per root complex DVMA space
limit. The limit has become a scalability bottleneck nowadays that
a typical 10G/40G NIC can consume 500MB DVMA space per instance.
When DVMA resource is exhausted, devices will not be usable
since the driver can't allocate DVMA.

For example, we recently experienced legacy IOMMU limitation while
using i40e driver in system with large number of CPUs (e.g. 128).
Four ports of i40e, each request 128 QP (Queue Pairs). Each queue has
512 (default) descriptors. So considering only RX queues (because RX
premap DMA buffers), i40e takes 4*128*512 number of DMA entries in
IOMMU table. Legacy IOMMU can have at max (2G/8K)- 1 entries available
in table. So bringing up four instance of i40e alone saturate existing
IOMMU resource.

ATU removes bottleneck by allowing guest os to create IOTSB of size
32G (or more) with 64bit address ranges available in ATU HW. 32G is
more than enough DVMA space to be shared by all PCIe devices under
root complex contrast to 2G space provided by legacy IOMMU.

ATU allows PCIe devices to use 64bit DMA addressing. Devices
which choose to use 32bit DMA mask will continue to work with the
existing legacy IOMMU.

The patch set is tested on sun4v (T1000, T2000, T3, T4, T5, T7, S7)
and sun4u SPARC.

Thanks.
-Tushar

v2->v3:
- Patch #5 addresses comment by Joe Perches.
 -- use %s, __func__ instead of embedding the function name.

v1->v2:
- Patch #2 addresses comments by Dave M.
 -- use page allocator to allocate IOTSB.
 -- use true/false with boolean variables.


Dave Kleikamp (1):
  sparc64: Add FORCE_MAX_ZONEORDER and default to 13

Tushar Dave (5):
  sparc64: Add ATU (new IOMMU) support
  sparc64: Initialize iommu_map_table and iommu_pool
  sparc64: Bind PCIe devices to use IOMMU v2 service
  sparc64: Enable sun4v dma ops to use IOMMU v2 APIs
  sparc64: Enable 64-bit DMA

 arch/sparc/Kconfig                  |  22 ++
 arch/sparc/include/asm/hypervisor.h | 343 +++++++++++++++++++++++++++++
 arch/sparc/include/asm/iommu_64.h   |  28 +++
 arch/sparc/kernel/hvapi.c           |   1 +
 arch/sparc/kernel/iommu.c           |   8 +-
 arch/sparc/kernel/pci_sun4v.c       | 418 +++++++++++++++++++++++++++++++-----
 arch/sparc/kernel/pci_sun4v.h       |  21 ++
 arch/sparc/kernel/pci_sun4v_asm.S   |  68 ++++++
 8 files changed, 849 insertions(+), 60 deletions(-)

-- 
1.9.1

[toc] | [next] | [standalone]


#1511282 — [PATCH v3 6/6] sparc64: Enable 64-bit DMA

FromTushar Dave <tushar.n.dave@oracle.com>
Date2016-10-28 19:20 +0200
Subject[PATCH v3 6/6] sparc64: Enable 64-bit DMA
Message-ID<sxiYW-2LI-29@gated-at.bofh.it>
In reply to#1511281
ATU 64bit addressing allows PCIe devices with 64bit DMA capabilities
to use ATU for 64bit DMA.

Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com>
Reviewed-by: chris hyser <chris.hyser@oracle.com>
Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
 arch/sparc/Kconfig        | 4 ++++
 arch/sparc/kernel/iommu.c | 8 ++++++--
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index 5202eb4..60145c9 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -93,6 +93,10 @@ config ARCH_ATU
 	bool
 	default y if SPARC64
 
+config ARCH_DMA_ADDR_T_64BIT
+	bool
+	default y if ARCH_ATU
+
 config IOMMU_HELPER
 	bool
 	default y if SPARC64
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5c615ab..852a329 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -760,8 +760,12 @@ int dma_supported(struct device *dev, u64 device_mask)
 	struct iommu *iommu = dev->archdata.iommu;
 	u64 dma_addr_mask = iommu->dma_addr_mask;
 
-	if (device_mask >= (1UL << 32UL))
-		return 0;
+	if (device_mask > DMA_BIT_MASK(32)) {
+		if (iommu->atu)
+			dma_addr_mask = iommu->atu->dma_addr_mask;
+		else
+			return 0;
+	}
 
 	if ((device_mask & dma_addr_mask) == dma_addr_mask)
 		return 1;
-- 
1.9.1

[toc] | [prev] | [next] | [standalone]


#1511284 — [PATCH v3 4/6] sparc64: Bind PCIe devices to use IOMMU v2 service

FromTushar Dave <tushar.n.dave@oracle.com>
Date2016-10-28 19:20 +0200
Subject[PATCH v3 4/6] sparc64: Bind PCIe devices to use IOMMU v2 service
Message-ID<sxiYW-2LI-25@gated-at.bofh.it>
In reply to#1511281
In order to use Hypervisor (HV) IOMMU v2 API for map/demap, each PCIe
device has to be bound to IOTSB using HV API pci_iotsb_bind().

Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com>
Reviewed-by: chris hyser <chris.hyser@oracle.com>
Acked-by: Sowmini Varadhan <sowmini.varadhan@oracle.com>
---
 arch/sparc/kernel/pci_sun4v.c     | 43 +++++++++++++++++++++++++++++++++++++++
 arch/sparc/kernel/pci_sun4v.h     |  3 +++
 arch/sparc/kernel/pci_sun4v_asm.S | 14 +++++++++++++
 3 files changed, 60 insertions(+)

diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index 242477c..d4208aa 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -216,6 +216,43 @@ static void *dma_4v_alloc_coherent(struct device *dev, size_t size,
 	return NULL;
 }
 
+unsigned long dma_4v_iotsb_bind(unsigned long devhandle,
+				unsigned long iotsb_num,
+				struct pci_bus *bus_dev)
+{
+	struct pci_dev *pdev;
+	unsigned long err;
+	unsigned int bus;
+	unsigned int device;
+	unsigned int fun;
+
+	list_for_each_entry(pdev, &bus_dev->devices, bus_list) {
+		if (pdev->subordinate) {
+			/* No need to bind pci bridge */
+			dma_4v_iotsb_bind(devhandle, iotsb_num,
+					  pdev->subordinate);
+		} else {
+			bus = bus_dev->number;
+			device = PCI_SLOT(pdev->devfn);
+			fun = PCI_FUNC(pdev->devfn);
+			err = pci_sun4v_iotsb_bind(devhandle, iotsb_num,
+						   HV_PCI_DEVICE_BUILD(bus,
+								       device,
+								       fun));
+
+			/* If bind fails for one device it is going to fail
+			 * for rest of the devices because we are sharing
+			 * IOTSB. So in case of failure simply return with
+			 * error.
+			 */
+			if (err)
+				return err;
+		}
+	}
+
+	return 0;
+}
+
 static void dma_4v_iommu_demap(void *demap_arg, unsigned long entry,
 			       unsigned long npages)
 {
@@ -629,6 +666,12 @@ static int pci_sun4v_atu_alloc_iotsb(struct pci_pbm_info *pbm)
 	}
 	iotsb->iotsb_num = iotsb_num;
 
+	err = dma_4v_iotsb_bind(pbm->devhandle, iotsb_num, pbm->pci_bus);
+	if (err) {
+		pr_err(PFX "pci_iotsb_bind failed error: %ld\n", err);
+		goto iotsb_conf_failed;
+	}
+
 	return 0;
 
 iotsb_conf_failed:
diff --git a/arch/sparc/kernel/pci_sun4v.h b/arch/sparc/kernel/pci_sun4v.h
index 0ef6d1c..1019e0f 100644
--- a/arch/sparc/kernel/pci_sun4v.h
+++ b/arch/sparc/kernel/pci_sun4v.h
@@ -96,4 +96,7 @@ unsigned long pci_sun4v_iotsb_conf(unsigned long devhandle,
 				   unsigned long page_size,
 				   unsigned long dvma_base,
 				   u64 *iotsb_num);
+unsigned long pci_sun4v_iotsb_bind(unsigned long devhandle,
+				   unsigned long iotsb_num,
+				   unsigned int pci_device);
 #endif /* !(_PCI_SUN4V_H) */
diff --git a/arch/sparc/kernel/pci_sun4v_asm.S b/arch/sparc/kernel/pci_sun4v_asm.S
index fd94d0e..22024a9 100644
--- a/arch/sparc/kernel/pci_sun4v_asm.S
+++ b/arch/sparc/kernel/pci_sun4v_asm.S
@@ -378,3 +378,17 @@ ENTRY(pci_sun4v_iotsb_conf)
 	retl
 	 stx	%o1, [%g1]
 ENDPROC(pci_sun4v_iotsb_conf)
+
+	/*
+	 * %o0:	devhandle
+	 * %o1:	iotsb_num/iotsb_handle
+	 * %o2:	pci_device
+	 *
+	 * returns %o0:	status
+	 */
+ENTRY(pci_sun4v_iotsb_bind)
+	mov	HV_FAST_PCI_IOTSB_BIND, %o5
+	ta	HV_FAST_TRAP
+	retl
+	 nop
+ENDPROC(pci_sun4v_iotsb_bind)
-- 
1.9.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web