Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1511281 > unrolled thread
| Started by | Tushar Dave <tushar.n.dave@oracle.com> |
|---|---|
| First post | 2016-10-28 19:20 +0200 |
| Last post | 2016-10-28 19:20 +0200 |
| Articles | 3 — 1 participant |
Back to article view | Back to linux.kernel
[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
| From | Tushar Dave <tushar.n.dave@oracle.com> |
|---|---|
| Date | 2016-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]
| From | Tushar Dave <tushar.n.dave@oracle.com> |
|---|---|
| Date | 2016-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]
| From | Tushar Dave <tushar.n.dave@oracle.com> |
|---|---|
| Date | 2016-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