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


Groups > linux.kernel > #1238426 > unrolled thread

[PATCH 0/2] Fix NVMe driver support on Power with 32-bit DMA

Started byNishanth Aravamudan <nacc@linux.vnet.ibm.com>
First post2015-10-02 19:20 +0200
Last post2015-10-03 10:30 +0200
Articles 18 — 4 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/2] Fix NVMe driver support on Power with 32-bit DMA Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 19:20 +0200
    [PATCH 1/2] powerpc/iommu: expose IOMMU page shift Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 19:20 +0200
      [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 19:30 +0200
        Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power Christoph Hellwig <hch@infradead.org> - 2015-10-02 19:30 +0200
          Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 19:50 +0200
            Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power Christoph Hellwig <hch@infradead.org> - 2015-10-02 19:50 +0200
    [PATCH 2/5 v2] powerpc/dma-mapping: override dma_get_page_shift Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:20 +0200
      [PATCH 3/5 v2] powerpc/dma: implement per-platform dma_get_page_shift Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:20 +0200
        [PATCH 4/5 v2] pseries/iommu: implement DDW-aware dma_get_page_shift Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:30 +0200
          [PATCH 5/5 v2] drivers/nvme: default to the IOMMU page size Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:40 +0200
          Re: [PATCH 4/5 v2] pseries/iommu: implement DDW-aware  dma_get_page_shift kbuild test robot <lkp@intel.com> - 2015-10-02 22:40 +0200
    [PATCH 1/5 v2] dma-mapping: add generic dma_get_page_shift API Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:20 +0200
    [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 22:20 +0200
      Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-02 23:10 +0200
        Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2015-10-02 23:40 +0200
          Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Nishanth Aravamudan <nacc@linux.vnet.ibm.com> - 2015-10-03 00:00 +0200
      Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Benjamin Herrenschmidt <benh@kernel.crashing.org> - 2015-10-02 23:30 +0200
        Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA Christoph Hellwig <hch@infradead.org> - 2015-10-03 10:30 +0200

#1238426 — [PATCH 0/2] Fix NVMe driver support on Power with 32-bit DMA

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 19:20 +0200
Subject[PATCH 0/2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qfc9X-1mW-5@gated-at.bofh.it>
We received a bug report recently when DDW (64-bit direct DMA on Power)
is not enabled for NVMe devices. In that case, we fall back to 32-bit
DMA via the IOMMU, which is always done via 4K TCEs (Translation Control
Entries).

The NVMe device driver, though, assumes that the DMA alignment for the
PRP entries will match the device's page size, and that the DMA aligment
matches the kernel's page aligment. On Power, the the IOMMU page size,
as mentioned above, can be 4K, while the device can have a page size of
8K, while the kernel has a page size of 64K. This eventually trips the
BUG_ON in nvme_setup_prps(), as we have a 'dma_len' that is a multiple
of 4K but not 8K (e.g., 0xF000).

In this particular case, and generally, we want to use the IOMMU's page
size for the default device page size, rather than the kernel's page
size.

This series consists of two patches, one of which exposes the IOMMU's
page shift on Power (currently only the page size is exposed, and it
seems unnecessary to ilog2 that value in the driver). The second patch
leverages this value on Power in the NVMe driver.

With these patches, a NVMe device survives our internal hardware
exerciser; the kernel BUGs within a few seconds without the patch.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1238431 — [PATCH 1/2] powerpc/iommu: expose IOMMU page shift

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 19:20 +0200
Subject[PATCH 1/2] powerpc/iommu: expose IOMMU page shift
Message-ID<qfc9Y-1mW-23@gated-at.bofh.it>
In reply to#1238426
We will leverage this macro in the NVMe driver, which needs to know the
configured IOMMU page shift to properly configure its device's page
size.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

---
Given this is available, it seems reasonable to expose -- and it doesn't
really make sense to make the driver do a log2 call on the existing
IOMMU_PAGE_SIZE() value.

diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h
index ca18cff..6fdf857 100644
--- a/arch/powerpc/include/asm/iommu.h
+++ b/arch/powerpc/include/asm/iommu.h
@@ -36,6 +36,7 @@
 #define IOMMU_PAGE_MASK_4K       (~((1 << IOMMU_PAGE_SHIFT_4K) - 1))
 #define IOMMU_PAGE_ALIGN_4K(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE_4K)
 
+#define IOMMU_PAGE_SHIFT(tblptr) (tblptr)->it_page_shift
 #define IOMMU_PAGE_SIZE(tblptr) (ASM_CONST(1) << (tblptr)->it_page_shift)
 #define IOMMU_PAGE_MASK(tblptr) (~((1 << (tblptr)->it_page_shift) - 1))
 #define IOMMU_PAGE_ALIGN(addr, tblptr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE(tblptr))

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238434 — [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 19:30 +0200
Subject[PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power
Message-ID<qfcjE-1AV-3@gated-at.bofh.it>
In reply to#1238431
We received a bug report recently when DDW (64-bit direct DMA on Power)
is not enabled for NVMe devices. In that case, we fall back to 32-bit
DMA via the IOMMU, which is always done via 4K TCEs (Translation Control
Entries).

The NVMe device driver, though, assumes that the DMA alignment for the
PRP entries will match the device's page size, and that the DMA aligment
matches the kernel's page aligment. On Power, the the IOMMU page size,
as mentioned above, can be 4K, while the device can have a page size of
8K, while the kernel has a page size of 64K. This eventually trips the
BUG_ON in nvme_setup_prps(), as we have a 'dma_len' that is a multiple
of 4K but not 8K (e.g., 0xF000).

In this particular case, and generally, we want to use the IOMMU's page
size for the default device page size, rather than the kernel's page
size.

With this patch, a NVMe device survives our internal hardware
exerciser; the kernel BUGs within a few seconds without the patch.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index 7920c27..969a95e 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -42,6 +42,7 @@
 #include <linux/types.h>
 #include <scsi/sg.h>
 #include <asm-generic/io-64-nonatomic-lo-hi.h>
+#include <asm/iommu.h>
 
 #define NVME_MINORS		(1U << MINORBITS)
 #define NVME_Q_DEPTH		1024
@@ -1680,6 +1681,11 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 	unsigned page_shift = PAGE_SHIFT;
 	unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
 	unsigned dev_page_max = NVME_CAP_MPSMAX(cap) + 12;
+#ifdef CONFIG_PPC64
+	struct iommu_table *tbl = get_iommu_table_base(dev->dev);
+	if (tbl)
+		page_shift = IOMMU_PAGE_SHIFT(tbl);
+#endif
 
 	if (page_shift < dev_page_min) {
 		dev_err(dev->dev,

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238436 — Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power

FromChristoph Hellwig <hch@infradead.org>
Date2015-10-02 19:30 +0200
SubjectRe: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power
Message-ID<qfcjF-1AV-13@gated-at.bofh.it>
In reply to#1238434
Hi Nishanth,

please expose this value through the generic DMA API instead of adding
architecture specific hacks to drivers.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238466 — Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 19:50 +0200
SubjectRe: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power
Message-ID<qfcCZ-1XK-1@gated-at.bofh.it>
In reply to#1238436
On 02.10.2015 [10:25:44 -0700], Christoph Hellwig wrote:
> Hi Nishanth,
> 
> please expose this value through the generic DMA API instead of adding
> architecture specific hacks to drivers.

Ok, I'm happy to do that instead -- what I struggled with is that I
don't have enough knowledge of the various architectures to provide the
right default implementation. It should be sufficient for the default to
return PAGE_SHIFT, and on Power just override that to return the IOMMU
table's page size? Since the only user will be the NVMe driver
currently, that should be fine?

Sorry for the less-than-ideal patch!

-Nish

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238471 — Re: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power

FromChristoph Hellwig <hch@infradead.org>
Date2015-10-02 19:50 +0200
SubjectRe: [PATCH 2/2] drivers/nvme: default to the IOMMU page size on Power
Message-ID<qfcD0-1XK-15@gated-at.bofh.it>
In reply to#1238466
On Fri, Oct 02, 2015 at 10:39:47AM -0700, Nishanth Aravamudan wrote:
> Ok, I'm happy to do that instead -- what I struggled with is that I
> don't have enough knowledge of the various architectures to provide the
> right default implementation. It should be sufficient for the default to
> return PAGE_SHIFT, and on Power just override that to return the IOMMU
> table's page size? Since the only user will be the NVMe driver
> currently, that should be fine?

I think that's fine.

> Sorry for the less-than-ideal patch!

Np, it's a reasonable first attempt that we just need to refine.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238571 — [PATCH 2/5 v2] powerpc/dma-mapping: override dma_get_page_shift

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:20 +0200
Subject[PATCH 2/5 v2] powerpc/dma-mapping: override dma_get_page_shift
Message-ID<qfeYa-5qP-3@gated-at.bofh.it>
In reply to#1238426
On Power, the kernel's page size can differ from the IOMMU's page size,
so we need to override the generic implementation, which always returns
the kernel's page size. Lookup the IOMMU's page size from struct
iommu_table, if available. Fallback to the kernel's page size,
otherwise.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 7f522c0..c5638f4 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -125,6 +125,9 @@ static inline void set_dma_offset(struct device *dev, dma_addr_t off)
 #define HAVE_ARCH_DMA_SET_MASK 1
 extern int dma_set_mask(struct device *dev, u64 dma_mask);
 
+#define HAVE_ARCH_DMA_GET_PAGE_SHIFT 1
+extern unsigned long dma_get_page_shift(struct device *dev);
+
 #include <asm-generic/dma-mapping-common.h>
 
 extern int __dma_set_mask(struct device *dev, u64 dma_mask);
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 59503ed..e805af2 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -335,6 +335,15 @@ int dma_set_mask(struct device *dev, u64 dma_mask)
 }
 EXPORT_SYMBOL(dma_set_mask);
 
+unsigned long dma_get_page_shift(struct device *dev)
+{
+	struct iommu_table *tbl = get_iommu_table_base(dev);
+	if (tbl)
+		return tbl->it_page_shift;
+	return PAGE_SHIFT;
+}
+EXPORT_SYMBOL(dma_get_page_shift);
+
 u64 __dma_get_required_mask(struct device *dev)
 {
 	struct dma_map_ops *dma_ops = get_dma_ops(dev);

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238575 — [PATCH 3/5 v2] powerpc/dma: implement per-platform dma_get_page_shift

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:20 +0200
Subject[PATCH 3/5 v2] powerpc/dma: implement per-platform dma_get_page_shift
Message-ID<qfeYb-5qP-11@gated-at.bofh.it>
In reply to#1238571
The IOMMU page size is not always stored in struct iommu on Power.
Specifically if a device is configured for DDW (Dynamic DMA Windows aka.
64-bit direct DMA), the used TCE (Translation Control Entry) size is
stored in a special device property created at run-time by the DDW
configuration code. DDW is a pseries-specific feature, so allow
platforms to override the implementation of dma_get_page_shift if
desired.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h
index cab6753..5c372e3 100644
--- a/arch/powerpc/include/asm/machdep.h
+++ b/arch/powerpc/include/asm/machdep.h
@@ -78,9 +78,10 @@ struct machdep_calls {
 #endif
 #endif /* CONFIG_PPC64 */
 
-	/* Platform set_dma_mask and dma_get_required_mask overrides */
+	/* Platform overrides */
 	int		(*dma_set_mask)(struct device *dev, u64 dma_mask);
 	u64		(*dma_get_required_mask)(struct device *dev);
+	unsigned long	(*dma_get_page_shift)(struct device *dev);
 
 	int		(*probe)(void);
 	void		(*setup_arch)(void); /* Optional, may be NULL */
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index e805af2..c363896 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -338,6 +338,8 @@ EXPORT_SYMBOL(dma_set_mask);
 unsigned long dma_get_page_shift(struct device *dev)
 {
 	struct iommu_table *tbl = get_iommu_table_base(dev);
+	if (ppc_md.dma_get_page_shift)
+		return ppc_md.dma_get_page_shift(dev);
 	if (tbl)
 		return tbl->it_page_shift;
 	return PAGE_SHIFT;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238596 — [PATCH 4/5 v2] pseries/iommu: implement DDW-aware dma_get_page_shift

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:30 +0200
Subject[PATCH 4/5 v2] pseries/iommu: implement DDW-aware dma_get_page_shift
Message-ID<qff7R-5Cf-41@gated-at.bofh.it>
In reply to#1238575
When DDW (Dynamic DMA Windows) are present for a device, we have stored
the TCE (Translation Control Entry) size in a special device tree
property. Check if we have enabled DDW for the device and return the TCE
size from that property if present. If the property isn't present,
fallback to looking the value up in struct iommu_table. If we don't find
a iommu_table, fallback to the kernel's page size.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 0946b98..1bf6471 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -1292,6 +1292,40 @@ static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
 	return dma_iommu_ops.get_required_mask(dev);
 }
 
+static unsigned long dma_get_page_shift_pSeriesLP(struct device *dev)
+{
+	struct iommu_table *tbl;
+
+	if (!disable_ddw && dev_is_pci(dev)) {
+		struct pci_dev *pdev = to_pci_dev(dev);
+		struct device_node *dn;
+
+		dn = pci_device_to_OF_node(pdev);
+
+		/* search upwards for ibm,dma-window */
+		for (; dn && PCI_DN(dn) && !PCI_DN(dn)->table_group;
+				dn = dn->parent)
+			if (of_get_property(dn, "ibm,dma-window", NULL))
+				break;
+		/*
+		 * if there is a DDW configuration, the TCE shift is stored in
+		 * the property
+		 */
+		if (dn && PCI_DN(dn)) {
+			const struct dynamic_dma_window_prop *direct64 =
+				of_get_property(dn, DIRECT64_PROPNAME, NULL);
+			if (direct64)
+				return be32_to_cpu(direct64->tce_shift);
+		}
+	}
+
+	tbl = get_iommu_table_base(dev);
+	if (tbl)
+		return tbl->it_page_shift;
+
+	return PAGE_SHIFT;
+}
+
 #else  /* CONFIG_PCI */
 #define pci_dma_bus_setup_pSeries	NULL
 #define pci_dma_dev_setup_pSeries	NULL
@@ -1299,6 +1333,7 @@ static u64 dma_get_required_mask_pSeriesLP(struct device *dev)
 #define pci_dma_dev_setup_pSeriesLP	NULL
 #define dma_set_mask_pSeriesLP		NULL
 #define dma_get_required_mask_pSeriesLP	NULL
+#define dma_get_page_shift_pSeriesLP	NULL
 #endif /* !CONFIG_PCI */
 
 static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action,
@@ -1395,6 +1430,7 @@ void iommu_init_early_pSeries(void)
 		pseries_pci_controller_ops.dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
 		ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
 		ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP;
+		ppc_md.dma_get_page_shift = dma_get_page_shift_pSeriesLP;
 	} else {
 		pseries_pci_controller_ops.dma_bus_setup = pci_dma_bus_setup_pSeries;
 		pseries_pci_controller_ops.dma_dev_setup = pci_dma_dev_setup_pSeries;

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238599 — [PATCH 5/5 v2] drivers/nvme: default to the IOMMU page size

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:40 +0200
Subject[PATCH 5/5 v2] drivers/nvme: default to the IOMMU page size
Message-ID<qffhv-5Ni-9@gated-at.bofh.it>
In reply to#1238596
We received a bug report recently when DDW (64-bit direct DMA on Power)
is not enabled for NVMe devices. In that case, we fall back to 32-bit
DMA via the IOMMU, which is always done via 4K TCEs (Translation Control
Entries).

The NVMe device driver, though, assumes that the DMA alignment for the
PRP entries will match the device's page size, and that the DMA aligment
matches the kernel's page aligment. On Power, the the IOMMU page size,
as mentioned above, can be 4K, while the device can have a page size of
8K, while the kernel has a page size of 64K. This eventually trips the
BUG_ON in nvme_setup_prps(), as we have a 'dma_len' that is a multiple
of 4K but not 8K (e.g., 0xF000).

In this particular case of page sizes, we clearly want to use the
IOMMU's page size in the driver. And generally, the NVMe driver in this
function should be using the IOMMU's page size for the default device
page size, rather than the kernel's page size.

With this patch, a NVMe device survives our internal hardware
exerciser; the kernel BUGs within a few seconds without the patch.

---
v1 -> v2:
  Based upon feedback from Christoph Hellwig, implement the IOMMU page
  size lookup as a generic DMA API, rather than an architecture-specific
  hack.

diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index b97fc3f..c561137 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -18,6 +18,7 @@
 #include <linux/blk-mq.h>
 #include <linux/cpu.h>
 #include <linux/delay.h>
+#include <linux/dma-mapping.h>
 #include <linux/errno.h>
 #include <linux/fs.h>
 #include <linux/genhd.h>
@@ -1713,7 +1714,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev)
 	u32 aqa;
 	u64 cap = readq(&dev->bar->cap);
 	struct nvme_queue *nvmeq;
-	unsigned page_shift = PAGE_SHIFT;
+	unsigned page_shift = dma_get_page_shift(dev->dev);
 	unsigned dev_page_min = NVME_CAP_MPSMIN(cap) + 12;
 	unsigned dev_page_max = NVME_CAP_MPSMAX(cap) + 12;
 

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238600 — Re: [PATCH 4/5 v2] pseries/iommu: implement DDW-aware dma_get_page_shift

Fromkbuild test robot <lkp@intel.com>
Date2015-10-02 22:40 +0200
SubjectRe: [PATCH 4/5 v2] pseries/iommu: implement DDW-aware dma_get_page_shift
Message-ID<qffhv-5Ni-5@gated-at.bofh.it>
In reply to#1238596

[Multipart message — attachments visible in raw view] — view raw

Hi Nishanth,

[auto build test results on v4.3-rc3 -- if it's inappropriate base, please ignore]

config: powerpc-defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All error/warnings (new ones prefixed by >>):

   arch/powerpc/platforms/pseries/iommu.c: In function 'iommu_init_early_pSeries':
>> arch/powerpc/platforms/pseries/iommu.c:1433:9: error: 'struct machdep_calls' has no member named 'dma_get_page_shift'
      ppc_md.dma_get_page_shift = dma_get_page_shift_pSeriesLP;
            ^

vim +1433 arch/powerpc/platforms/pseries/iommu.c

  1427	
  1428		if (firmware_has_feature(FW_FEATURE_LPAR)) {
  1429			pseries_pci_controller_ops.dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
  1430			pseries_pci_controller_ops.dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
  1431			ppc_md.dma_set_mask = dma_set_mask_pSeriesLP;
  1432			ppc_md.dma_get_required_mask = dma_get_required_mask_pSeriesLP;
> 1433			ppc_md.dma_get_page_shift = dma_get_page_shift_pSeriesLP;
  1434		} else {
  1435			pseries_pci_controller_ops.dma_bus_setup = pci_dma_bus_setup_pSeries;
  1436			pseries_pci_controller_ops.dma_dev_setup = pci_dma_dev_setup_pSeries;

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

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


#1238573 — [PATCH 1/5 v2] dma-mapping: add generic dma_get_page_shift API

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:20 +0200
Subject[PATCH 1/5 v2] dma-mapping: add generic dma_get_page_shift API
Message-ID<qfeYa-5qP-7@gated-at.bofh.it>
In reply to#1238426
Drivers like NVMe need to be able to determine the page size used for
DMA transfers. Add a new API that defaults to return PAGE_SHIFT on all
architectures.

Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>

diff --git a/include/asm-generic/dma-mapping-common.h b/include/asm-generic/dma-mapping-common.h
index b1bc954..86e4e97 100644
--- a/include/asm-generic/dma-mapping-common.h
+++ b/include/asm-generic/dma-mapping-common.h
@@ -355,4 +355,11 @@ static inline int dma_set_mask(struct device *dev, u64 mask)
 }
 #endif
 
+#ifndef HAVE_ARCH_DMA_GET_PAGE_SHIFT
+static inline unsigned long dma_get_page_shift(struct device *dev)
+{
+	return PAGE_SHIFT;
+}
+#endif
+
 #endif

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238576 — [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 22:20 +0200
Subject[PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qfeYa-5qP-5@gated-at.bofh.it>
In reply to#1238426
We received a bug report recently when DDW (64-bit direct DMA on Power)
is not enabled for NVMe devices. In that case, we fall back to 32-bit
DMA via the IOMMU, which is always done via 4K TCEs (Translation Control
Entries).
 
The NVMe device driver, though, assumes that the DMA alignment for the
PRP entries will match the device's page size, and that the DMA aligment
matches the kernel's page aligment. On Power, the the IOMMU page size,
as mentioned above, can be 4K, while the device can have a page size of
8K, while the kernel has a page size of 64K. This eventually trips the
BUG_ON in nvme_setup_prps(), as we have a 'dma_len' that is a multiple
of 4K but not 8K (e.g., 0xF000).
 
In this particular case, and generally, we want to use the IOMMU's page
size for the default device page size, rather than the kernel's page
size.
 
This series consists of five patches:

1) add a generic dma_get_page_shift implementation that just returns
PAGE_SHIFT
2) override the generic implementation on Power to use the IOMMU table's
page shift if available
3) allow further specific overriding on power with machdep platform
overrides
4) use the machdep override on pseries, as the DDW code puts the TCE
shift in a special property and there is no IOMMU table available
5) leverage the new API in the NVMe driver
 
With these patches, a NVMe device survives our internal hardware
exerciser; the kernel BUGs within a few seconds without the patch.

 arch/powerpc/include/asm/dma-mapping.h   |  3 +++
 arch/powerpc/include/asm/machdep.h       |  3 ++-
 arch/powerpc/kernel/dma.c                | 11 +++++++++++
 arch/powerpc/platforms/pseries/iommu.c   | 36 ++++++++++++++++++++++++++++++++++++
 drivers/block/nvme-core.c                |  3 ++-
 include/asm-generic/dma-mapping-common.h |  7 +++++++
 6 files changed, 61 insertions(+), 2 deletions(-)

v1 -> v2:
  Based upon feedback from Christoph Hellwig, rather than using an
  arch-specific hack, expose the DMA page shift via a generic DMA API and
  override it on Power as needed.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238618 — Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-02 23:10 +0200
SubjectRe: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qffKy-6Av-17@gated-at.bofh.it>
In reply to#1238576
On 03.10.2015 [06:51:06 +1000], Benjamin Herrenschmidt wrote:
> On Fri, 2015-10-02 at 13:09 -0700, Nishanth Aravamudan wrote:
> 
> > 1) add a generic dma_get_page_shift implementation that just returns
> > PAGE_SHIFT
> 
> So you chose to return the granularity of the iommu to the driver
> rather than providing a way for the driver to request a specific
> alignment for DMA mappings. Any specific reason ?

Right, I did start with your advice and tried that approach, but it
turned out I was wrong about the actual issue at the time. The problem
for NVMe isn't actually the starting address alignment (which it can
handle not being aligned to the device's page size). It doesn't handle
(addr + len % dev_page_size != 0). That is, it's really a length
alignment issue.

It seems incredibly device specific to have a an API into the DMA code
to request an end alignment -- no other device seems to have this
issue/design. If you think that's better, I can fiddle with that
instead.

Sorry, I should have called this out better as an alternative
consideration.

-Nish


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238631 — Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromBenjamin Herrenschmidt <benh@kernel.crashing.org>
Date2015-10-02 23:40 +0200
SubjectRe: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qfgdB-78j-19@gated-at.bofh.it>
In reply to#1238618
On Fri, 2015-10-02 at 14:04 -0700, Nishanth Aravamudan wrote:
> Right, I did start with your advice and tried that approach, but it
> turned out I was wrong about the actual issue at the time. The problem
> for NVMe isn't actually the starting address alignment (which it can
> handle not being aligned to the device's page size). It doesn't handle
> (addr + len % dev_page_size != 0). That is, it's really a length
> alignment issue.
> 
> It seems incredibly device specific to have a an API into the DMA code
> to request an end alignment -- no other device seems to have this
> issue/design. If you think that's better, I can fiddle with that
> instead.
> 
> Sorry, I should have called this out better as an alternative
> consideration.

Nah it's fine. Ok. Also adding the alignment requirement to the API
would have been a much more complex patch since it would have had to
be implemented for all archs.

I think your current solution is fine.

Cheers,
Ben.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238637 — Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromNishanth Aravamudan <nacc@linux.vnet.ibm.com>
Date2015-10-03 00:00 +0200
SubjectRe: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qfgwW-7vm-7@gated-at.bofh.it>
In reply to#1238631
On 03.10.2015 [07:35:09 +1000], Benjamin Herrenschmidt wrote:
> On Fri, 2015-10-02 at 14:04 -0700, Nishanth Aravamudan wrote:
> > Right, I did start with your advice and tried that approach, but it
> > turned out I was wrong about the actual issue at the time. The problem
> > for NVMe isn't actually the starting address alignment (which it can
> > handle not being aligned to the device's page size). It doesn't handle
> > (addr + len % dev_page_size != 0). That is, it's really a length
> > alignment issue.
> > 
> > It seems incredibly device specific to have a an API into the DMA code
> > to request an end alignment -- no other device seems to have this
> > issue/design. If you think that's better, I can fiddle with that
> > instead.
> > 
> > Sorry, I should have called this out better as an alternative
> > consideration.
> 
> Nah it's fine. Ok. Also adding the alignment requirement to the API
> would have been a much more complex patch since it would have had to
> be implemented for all archs.
> 
> I think your current solution is fine.

Great, thanks. Also, while it's possible an alignment API would be more
performant...we're already not using DDW on Power in this case,
performance is not a primary concern. We want to simply be
functional/correct in this configuration.

-Nish

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238624 — Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromBenjamin Herrenschmidt <benh@kernel.crashing.org>
Date2015-10-02 23:30 +0200
SubjectRe: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qffKy-6Av-19@gated-at.bofh.it>
In reply to#1238576
On Fri, 2015-10-02 at 13:09 -0700, Nishanth Aravamudan wrote:

> 1) add a generic dma_get_page_shift implementation that just returns
> PAGE_SHIFT

So you chose to return the granularity of the iommu to the driver
rather than providing a way for the driver to request a specific
alignment for DMA mappings. Any specific reason ?

Cheers,
Ben.

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

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


#1238773 — Re: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA

FromChristoph Hellwig <hch@infradead.org>
Date2015-10-03 10:30 +0200
SubjectRe: [PATCH 0/5 v2] Fix NVMe driver support on Power with 32-bit DMA
Message-ID<qfqmC-4NE-1@gated-at.bofh.it>
In reply to#1238624
On Sat, Oct 03, 2015 at 06:51:06AM +1000, Benjamin Herrenschmidt wrote:
> On Fri, 2015-10-02 at 13:09 -0700, Nishanth Aravamudan wrote:
> 
> > 1) add a generic dma_get_page_shift implementation that just returns
> > PAGE_SHIFT
> 
> So you chose to return the granularity of the iommu to the driver
> rather than providing a way for the driver to request a specific
> alignment for DMA mappings. Any specific reason ?

At least for NVMe that's the way to go - it allows to set a page set in
the device which should fit the IOMMU page size.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web