Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1205647 > unrolled thread
| Started by | Christoph Hellwig <hch@lst.de> |
|---|---|
| First post | 2015-08-12 09:20 +0200 |
| Last post | 2015-08-12 20:00 +0200 |
| Articles | 20 — 6 participants |
Back to article view | Back to linux.kernel
RFC: prepare for struct scatterlist entries without page backing Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 22/31] metag: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 07/31] alpha/pci_iommu: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 28/31] powerpc: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 23/31] sh: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 16/31] s390: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
Re: [PATCH 16/31] s390: handle page-less SG entries Sebastian Ott <sebott@linux.vnet.ibm.com> - 2015-08-12 14:00 +0200
[PATCH 11/31] sparc/iommu: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:20 +0200
[PATCH 03/31] dma-debug: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:30 +0200
[PATCH 06/31] alpha/pci-noop: handle page-less SG entries Christoph Hellwig <hch@lst.de> - 2015-08-12 09:30 +0200
[PATCH 02/31] scatterlist: use sg_phys() Christoph Hellwig <hch@lst.de> - 2015-08-12 09:30 +0200
[PATCH 01/31] scatterlist: add sg_pfn and sg_has_page helpers Christoph Hellwig <hch@lst.de> - 2015-08-12 09:30 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Boaz Harrosh <boaz@plexistor.com> - 2015-08-12 14:50 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Julian Calaby <julian.calaby@gmail.com> - 2015-08-13 01:40 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Christoph Hellwig <hch@lst.de> - 2015-08-13 16:40 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Julian Calaby <julian.calaby@gmail.com> - 2015-08-14 01:50 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Christoph Hellwig <hch@lst.de> - 2015-08-13 16:50 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Boaz Harrosh <boaz@plexistor.com> - 2015-08-13 17:50 +0200
Re: RFC: prepare for struct scatterlist entries without page backing James Bottomley <James.Bottomley@HansenPartnership.com> - 2015-08-12 19:10 +0200
Re: RFC: prepare for struct scatterlist entries without page backing Grant Grundler <grantgrundler@gmail.com> - 2015-08-12 20:00 +0200
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | RFC: prepare for struct scatterlist entries without page backing |
| Message-ID | <pWykF-5Aj-9@gated-at.bofh.it> |
Dan Williams started to look into addressing I/O to and from Persistent Memory in his series from June: http://thread.gmane.org/gmane.linux.kernel.cross-arch/27944 I've started looking into DMA mapping of these SGLs specifically instead of the map_pfn method in there. In addition to supporting NVDIMM backed I/O I also suspect this would be highly useful for media drivers that go through nasty hoops to be able to DMA from/to their ioremapped regions, with vb2_dc_get_userptr in drivers/media/v4l2-core/videobuf2-dma-contig.c being a prime example for the unsafe hacks currently used. It turns out most DMA mapping implementation can handle SGLs without page structures with some fairly simple mechanical work. Most of it is just about consistently using sg_phys. For implementations that need to flush caches we need a new helper that skips these cache flushes if a entry doesn't have a kernel virtual address. However the ccio (parisc) and sba_iommu (parisc & ia64) IOMMUs seem to be operate mostly on virtual addresses. It's a fairly odd concept that I don't fully grasp, so I'll need some help with those if we want to bring this forward. Additional this series skips ARM entirely for now. The reason is that most arm implementations of the .map_sg operation just iterate over all entries and call ->map_page for it, which means we'd need to convert those to a ->map_pfn similar to Dan's previous approach. -- 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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 22/31] metag: handle page-less SG entries |
| Message-ID | <pWyun-5LM-43@gated-at.bofh.it> |
| In reply to | #1205647 |
Make all cache invalidation conditional on sg_has_page().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/metag/include/asm/dma-mapping.h | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/arch/metag/include/asm/dma-mapping.h b/arch/metag/include/asm/dma-mapping.h
index eb5cdec..2ae9057 100644
--- a/arch/metag/include/asm/dma-mapping.h
+++ b/arch/metag/include/asm/dma-mapping.h
@@ -55,10 +55,9 @@ dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
WARN_ON(nents == 0 || sglist[0].length == 0);
for_each_sg(sglist, sg, nents, i) {
- BUG_ON(!sg_page(sg));
-
sg->dma_address = sg_phys(sg);
- dma_sync_for_device(sg_virt(sg), sg->length, direction);
+ if (sg_has_page(sg))
+ dma_sync_for_device(sg_virt(sg), sg->length, direction);
}
return nents;
@@ -94,10 +93,9 @@ dma_unmap_sg(struct device *dev, struct scatterlist *sglist, int nhwentries,
WARN_ON(nhwentries == 0 || sglist[0].length == 0);
for_each_sg(sglist, sg, nhwentries, i) {
- BUG_ON(!sg_page(sg));
-
sg->dma_address = sg_phys(sg);
- dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+ if (sg_has_page(sg))
+ dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
}
}
@@ -140,8 +138,10 @@ dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sglist, int nelems,
int i;
struct scatterlist *sg;
- for_each_sg(sglist, sg, nelems, i)
- dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+ for_each_sg(sglist, sg, nelems, i) {
+ if (sg_has_page(sg))
+ dma_sync_for_cpu(sg_virt(sg), sg->length, direction);
+ }
}
static inline void
@@ -151,8 +151,10 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sglist,
int i;
struct scatterlist *sg;
- for_each_sg(sglist, sg, nelems, i)
- dma_sync_for_device(sg_virt(sg), sg->length, direction);
+ for_each_sg(sglist, sg, nelems, i) {
+ if (sg_has_page(sg))
+ dma_sync_for_device(sg_virt(sg), sg->length, direction);
+ }
}
static inline int
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 07/31] alpha/pci_iommu: handle page-less SG entries |
| Message-ID | <pWyun-5LM-45@gated-at.bofh.it> |
| In reply to | #1205647 |
Use sg_phys() instead of virt_to_phys(sg_virt(sg)) so that we don't
require a kernel virtual address, and switch a few debug printfs to
print physical instead of virtual addresses.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/alpha/kernel/pci_iommu.c | 36 +++++++++++++++---------------------
1 file changed, 15 insertions(+), 21 deletions(-)
diff --git a/arch/alpha/kernel/pci_iommu.c b/arch/alpha/kernel/pci_iommu.c
index eddee77..5d46b49 100644
--- a/arch/alpha/kernel/pci_iommu.c
+++ b/arch/alpha/kernel/pci_iommu.c
@@ -248,20 +248,17 @@ static int pci_dac_dma_supported(struct pci_dev *dev, u64 mask)
until either pci_unmap_single or pci_dma_sync_single is performed. */
static dma_addr_t
-pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
+pci_map_single_1(struct pci_dev *pdev, unsigned long paddr, size_t size,
int dac_allowed)
{
struct pci_controller *hose = pdev ? pdev->sysdata : pci_isa_hose;
dma_addr_t max_dma = pdev ? pdev->dma_mask : ISA_DMA_MASK;
struct pci_iommu_arena *arena;
long npages, dma_ofs, i;
- unsigned long paddr;
dma_addr_t ret;
unsigned int align = 0;
struct device *dev = pdev ? &pdev->dev : NULL;
- paddr = __pa(cpu_addr);
-
#if !DEBUG_NODIRECT
/* First check to see if we can use the direct map window. */
if (paddr + size + __direct_map_base - 1 <= max_dma
@@ -269,7 +266,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
ret = paddr + __direct_map_base;
DBGA2("pci_map_single: [%p,%zx] -> direct %llx from %pf\n",
- cpu_addr, size, ret, __builtin_return_address(0));
+ paddr, size, ret, __builtin_return_address(0));
return ret;
}
@@ -280,7 +277,7 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
ret = paddr + alpha_mv.pci_dac_offset;
DBGA2("pci_map_single: [%p,%zx] -> DAC %llx from %pf\n",
- cpu_addr, size, ret, __builtin_return_address(0));
+ paddr, size, ret, __builtin_return_address(0));
return ret;
}
@@ -309,15 +306,15 @@ pci_map_single_1(struct pci_dev *pdev, void *cpu_addr, size_t size,
return 0;
}
+ offset = paddr & ~PAGE_MASK;
paddr &= PAGE_MASK;
for (i = 0; i < npages; ++i, paddr += PAGE_SIZE)
arena->ptes[i + dma_ofs] = mk_iommu_pte(paddr);
- ret = arena->dma_base + dma_ofs * PAGE_SIZE;
- ret += (unsigned long)cpu_addr & ~PAGE_MASK;
+ ret = arena->dma_base + dma_ofs * PAGE_SIZE + offset;
DBGA2("pci_map_single: [%p,%zx] np %ld -> sg %llx from %pf\n",
- cpu_addr, size, npages, ret, __builtin_return_address(0));
+ paddr, size, npages, ret, __builtin_return_address(0));
return ret;
}
@@ -357,7 +354,7 @@ static dma_addr_t alpha_pci_map_page(struct device *dev, struct page *page,
BUG_ON(dir == PCI_DMA_NONE);
dac_allowed = pdev ? pci_dac_dma_supported(pdev, pdev->dma_mask) : 0;
- return pci_map_single_1(pdev, (char *)page_address(page) + offset,
+ return pci_map_single_1(pdev, page_to_phys(page) + offset,
size, dac_allowed);
}
@@ -453,7 +450,7 @@ try_again:
}
memset(cpu_addr, 0, size);
- *dma_addrp = pci_map_single_1(pdev, cpu_addr, size, 0);
+ *dma_addrp = pci_map_single_1(pdev, __pa(cpu_addr), size, 0);
if (*dma_addrp == 0) {
free_pages((unsigned long)cpu_addr, order);
if (alpha_mv.mv_pci_tbi || (gfp & GFP_DMA))
@@ -497,9 +494,6 @@ static void alpha_pci_free_coherent(struct device *dev, size_t size,
Write dma_length of each leader with the combined lengths of
the mergable followers. */
-#define SG_ENT_VIRT_ADDRESS(SG) (sg_virt((SG)))
-#define SG_ENT_PHYS_ADDRESS(SG) __pa(SG_ENT_VIRT_ADDRESS(SG))
-
static void
sg_classify(struct device *dev, struct scatterlist *sg, struct scatterlist *end,
int virt_ok)
@@ -512,13 +506,13 @@ sg_classify(struct device *dev, struct scatterlist *sg, struct scatterlist *end,
leader = sg;
leader_flag = 0;
leader_length = leader->length;
- next_paddr = SG_ENT_PHYS_ADDRESS(leader) + leader_length;
+ next_paddr = sg_phys(leader) + leader_length;
/* we will not marge sg without device. */
max_seg_size = dev ? dma_get_max_seg_size(dev) : 0;
for (++sg; sg < end; ++sg) {
unsigned long addr, len;
- addr = SG_ENT_PHYS_ADDRESS(sg);
+ addr = sg_phys(sg);
len = sg->length;
if (leader_length + len > max_seg_size)
@@ -555,7 +549,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
struct scatterlist *out, struct pci_iommu_arena *arena,
dma_addr_t max_dma, int dac_allowed)
{
- unsigned long paddr = SG_ENT_PHYS_ADDRESS(leader);
+ unsigned long paddr = sg_phys(leader);
long size = leader->dma_length;
struct scatterlist *sg;
unsigned long *ptes;
@@ -621,7 +615,7 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
#endif
size = sg->length;
- paddr = SG_ENT_PHYS_ADDRESS(sg);
+ paddr = sg_phys(sg);
while (sg+1 < end && (int) sg[1].dma_address == -1) {
size += sg[1].length;
@@ -636,11 +630,11 @@ sg_fill(struct device *dev, struct scatterlist *leader, struct scatterlist *end,
#if DEBUG_ALLOC > 0
DBGA(" (%ld) [%p,%x] np %ld\n",
- last_sg - leader, SG_ENT_VIRT_ADDRESS(last_sg),
+ last_sg - leader, sg_phys(last_sg),
last_sg->length, npages);
while (++last_sg <= sg) {
DBGA(" (%ld) [%p,%x] cont\n",
- last_sg - leader, SG_ENT_VIRT_ADDRESS(last_sg),
+ last_sg - leader, sg_phys(last_sg),
last_sg->length);
}
#endif
@@ -668,7 +662,7 @@ static int alpha_pci_map_sg(struct device *dev, struct scatterlist *sg,
if (nents == 1) {
sg->dma_length = sg->length;
sg->dma_address
- = pci_map_single_1(pdev, SG_ENT_VIRT_ADDRESS(sg),
+ = pci_map_single_1(pdev, sg_phys(sg),
sg->length, dac_allowed);
return sg->dma_address != 0;
}
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 28/31] powerpc: handle page-less SG entries |
| Message-ID | <pWyum-5LM-21@gated-at.bofh.it> |
| In reply to | #1205647 |
Make all cache invalidation conditional on sg_has_page().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/powerpc/kernel/dma.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 35e4dcc..cece40b 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -135,7 +135,10 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg) + get_dma_offset(dev);
sg->dma_length = sg->length;
- __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
+ if (sg_has_page(sg)) {
+ __dma_sync_page(sg_page(sg), sg->offset, sg->length,
+ direction);
+ }
}
return nents;
@@ -200,7 +203,10 @@ static inline void dma_direct_sync_sg(struct device *dev,
int i;
for_each_sg(sgl, sg, nents, i)
- __dma_sync_page(sg_page(sg), sg->offset, sg->length, direction);
+ if (sg_has_page(sg)) {
+ __dma_sync_page(sg_page(sg), sg->offset, sg->length,
+ direction);
+ }
}
static inline void dma_direct_sync_single(struct device *dev,
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 23/31] sh: handle page-less SG entries |
| Message-ID | <pWyun-5LM-47@gated-at.bofh.it> |
| In reply to | #1205647 |
Make all cache invalidation conditional on sg_has_page().
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/sh/kernel/dma-nommu.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/arch/sh/kernel/dma-nommu.c b/arch/sh/kernel/dma-nommu.c
index 5b0bfcd..3b64dc7 100644
--- a/arch/sh/kernel/dma-nommu.c
+++ b/arch/sh/kernel/dma-nommu.c
@@ -33,9 +33,8 @@ static int nommu_map_sg(struct device *dev, struct scatterlist *sg,
WARN_ON(nents == 0 || sg[0].length == 0);
for_each_sg(sg, s, nents, i) {
- BUG_ON(!sg_page(s));
-
- dma_cache_sync(dev, sg_virt(s), s->length, dir);
+ if (sg_has_page(s))
+ dma_cache_sync(dev, sg_virt(s), s->length, dir);
s->dma_address = sg_phys(s);
s->dma_length = s->length;
@@ -57,8 +56,10 @@ static void nommu_sync_sg(struct device *dev, struct scatterlist *sg,
struct scatterlist *s;
int i;
- for_each_sg(sg, s, nelems, i)
- dma_cache_sync(dev, sg_virt(s), s->length, dir);
+ for_each_sg(sg, s, nelems, i) {
+ if (sg_has_page(s))
+ dma_cache_sync(dev, sg_virt(s), s->length, dir);
+ }
}
#endif
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 16/31] s390: handle page-less SG entries |
| Message-ID | <pWyun-5LM-49@gated-at.bofh.it> |
| In reply to | #1205647 |
Use sg_phys() instead of page_to_phys(sg_page(sg)) so that we don't
require a page structure for all DMA memory.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/s390/pci/pci_dma.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
index 6fd8d58..aae5a47 100644
--- a/arch/s390/pci/pci_dma.c
+++ b/arch/s390/pci/pci_dma.c
@@ -272,14 +272,13 @@ int dma_set_mask(struct device *dev, u64 mask)
}
EXPORT_SYMBOL_GPL(dma_set_mask);
-static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
- unsigned long offset, size_t size,
+static dma_addr_t s390_dma_map_phys(struct device *dev, unsigned long pa,
+ size_t size,
enum dma_data_direction direction,
struct dma_attrs *attrs)
{
struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
unsigned long nr_pages, iommu_page_index;
- unsigned long pa = page_to_phys(page) + offset;
int flags = ZPCI_PTE_VALID;
dma_addr_t dma_addr;
@@ -301,7 +300,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
atomic64_add(nr_pages, &zdev->mapped_pages);
- return dma_addr + (offset & ~PAGE_MASK);
+ return dma_addr + (pa & ~PAGE_MASK);
}
out_free:
@@ -312,6 +311,16 @@ out_err:
return DMA_ERROR_CODE;
}
+static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction direction,
+ struct dma_attrs *attrs)
+{
+ unsigned long pa = page_to_phys(page) + offset;
+
+ return s390_dma_map_phys(dev, pa, size, direction, attrs);
+}
+
static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
size_t size, enum dma_data_direction direction,
struct dma_attrs *attrs)
@@ -384,8 +393,7 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg,
int i;
for_each_sg(sg, s, nr_elements, i) {
- struct page *page = sg_page(s);
- s->dma_address = s390_dma_map_pages(dev, page, s->offset,
+ s->dma_address = s390_dma_map_phys(dev, sg_phys(s),
s->length, dir, NULL);
if (!dma_mapping_error(dev, s->dma_address)) {
s->dma_length = s->length;
--
1.9.1
--
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]
| From | Sebastian Ott <sebott@linux.vnet.ibm.com> |
|---|---|
| Date | 2015-08-12 14:00 +0200 |
| Subject | Re: [PATCH 16/31] s390: handle page-less SG entries |
| Message-ID | <pWCRl-3tG-49@gated-at.bofh.it> |
| In reply to | #1205652 |
On Wed, 12 Aug 2015, Christoph Hellwig wrote:
> Use sg_phys() instead of page_to_phys(sg_page(sg)) so that we don't
> require a page structure for all DMA memory.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
> ---
> arch/s390/pci/pci_dma.c | 20 ++++++++++++++------
> 1 file changed, 14 insertions(+), 6 deletions(-)
>
> diff --git a/arch/s390/pci/pci_dma.c b/arch/s390/pci/pci_dma.c
> index 6fd8d58..aae5a47 100644
> --- a/arch/s390/pci/pci_dma.c
> +++ b/arch/s390/pci/pci_dma.c
> @@ -272,14 +272,13 @@ int dma_set_mask(struct device *dev, u64 mask)
> }
> EXPORT_SYMBOL_GPL(dma_set_mask);
>
> -static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
> - unsigned long offset, size_t size,
> +static dma_addr_t s390_dma_map_phys(struct device *dev, unsigned long pa,
> + size_t size,
> enum dma_data_direction direction,
> struct dma_attrs *attrs)
> {
> struct zpci_dev *zdev = get_zdev(to_pci_dev(dev));
> unsigned long nr_pages, iommu_page_index;
> - unsigned long pa = page_to_phys(page) + offset;
> int flags = ZPCI_PTE_VALID;
> dma_addr_t dma_addr;
>
> @@ -301,7 +300,7 @@ static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
>
> if (!dma_update_trans(zdev, pa, dma_addr, size, flags)) {
> atomic64_add(nr_pages, &zdev->mapped_pages);
> - return dma_addr + (offset & ~PAGE_MASK);
> + return dma_addr + (pa & ~PAGE_MASK);
> }
>
> out_free:
> @@ -312,6 +311,16 @@ out_err:
> return DMA_ERROR_CODE;
> }
>
> +static dma_addr_t s390_dma_map_pages(struct device *dev, struct page *page,
> + unsigned long offset, size_t size,
> + enum dma_data_direction direction,
> + struct dma_attrs *attrs)
> +{
> + unsigned long pa = page_to_phys(page) + offset;
> +
> + return s390_dma_map_phys(dev, pa, size, direction, attrs);
> +}
> +
> static void s390_dma_unmap_pages(struct device *dev, dma_addr_t dma_addr,
> size_t size, enum dma_data_direction direction,
> struct dma_attrs *attrs)
> @@ -384,8 +393,7 @@ static int s390_dma_map_sg(struct device *dev, struct scatterlist *sg,
> int i;
>
> for_each_sg(sg, s, nr_elements, i) {
> - struct page *page = sg_page(s);
> - s->dma_address = s390_dma_map_pages(dev, page, s->offset,
> + s->dma_address = s390_dma_map_phys(dev, sg_phys(s),
> s->length, dir, NULL);
> if (!dma_mapping_error(dev, s->dma_address)) {
> s->dma_length = s->length;
> --
> 1.9.1
>
> --
> 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/
>
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:20 +0200 |
| Subject | [PATCH 11/31] sparc/iommu: handle page-less SG entries |
| Message-ID | <pWyun-5LM-51@gated-at.bofh.it> |
| In reply to | #1205647 |
Use sg_phys() instead of __pa(sg_virt(sg)) so that we don't
require a kernel virtual address.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/sparc/kernel/iommu.c | 2 +-
arch/sparc/kernel/iommu_common.h | 4 +---
arch/sparc/kernel/pci_sun4v.c | 2 +-
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/arch/sparc/kernel/iommu.c b/arch/sparc/kernel/iommu.c
index 5320689..2ad89d2 100644
--- a/arch/sparc/kernel/iommu.c
+++ b/arch/sparc/kernel/iommu.c
@@ -486,7 +486,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
continue;
}
/* Allocate iommu entries for that segment */
- paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
+ paddr = sg_phys(s);
npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages,
&handle, (unsigned long)(-1), 0);
diff --git a/arch/sparc/kernel/iommu_common.h b/arch/sparc/kernel/iommu_common.h
index b40cec2..8e2c211 100644
--- a/arch/sparc/kernel/iommu_common.h
+++ b/arch/sparc/kernel/iommu_common.h
@@ -33,15 +33,13 @@
*/
#define IOMMU_PAGE_SHIFT 13
-#define SG_ENT_PHYS_ADDRESS(SG) (__pa(sg_virt((SG))))
-
static inline int is_span_boundary(unsigned long entry,
unsigned long shift,
unsigned long boundary_size,
struct scatterlist *outs,
struct scatterlist *sg)
{
- unsigned long paddr = SG_ENT_PHYS_ADDRESS(outs);
+ unsigned long paddr = sg_phys(outs);
int nr = iommu_num_pages(paddr, outs->dma_length + sg->length,
IO_PAGE_SIZE);
diff --git a/arch/sparc/kernel/pci_sun4v.c b/arch/sparc/kernel/pci_sun4v.c
index d2fe57d..a7a6e41 100644
--- a/arch/sparc/kernel/pci_sun4v.c
+++ b/arch/sparc/kernel/pci_sun4v.c
@@ -370,7 +370,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
continue;
}
/* Allocate iommu entries for that segment */
- paddr = (unsigned long) SG_ENT_PHYS_ADDRESS(s);
+ paddr = sg_phys(s);
npages = iommu_num_pages(paddr, slen, IO_PAGE_SIZE);
entry = iommu_tbl_range_alloc(dev, &iommu->tbl, npages,
&handle, (unsigned long)(-1), 0);
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:30 +0200 |
| Subject | [PATCH 03/31] dma-debug: handle page-less SG entries |
| Message-ID | <pWyE2-5X6-9@gated-at.bofh.it> |
| In reply to | #1205647 |
Use sg_pfn to get a the PFN and skip checks that require a kernel
virtual address.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
lib/dma-debug.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/dma-debug.c b/lib/dma-debug.c
index dace71f..a215a80 100644
--- a/lib/dma-debug.c
+++ b/lib/dma-debug.c
@@ -1368,7 +1368,7 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
entry->type = dma_debug_sg;
entry->dev = dev;
- entry->pfn = page_to_pfn(sg_page(s));
+ entry->pfn = sg_pfn(s);
entry->offset = s->offset,
entry->size = sg_dma_len(s);
entry->dev_addr = sg_dma_address(s);
@@ -1376,7 +1376,7 @@ void debug_dma_map_sg(struct device *dev, struct scatterlist *sg,
entry->sg_call_ents = nents;
entry->sg_mapped_ents = mapped_ents;
- if (!PageHighMem(sg_page(s))) {
+ if (sg_has_page(s) && !PageHighMem(sg_page(s))) {
check_for_stack(dev, sg_virt(s));
check_for_illegal_area(dev, sg_virt(s), sg_dma_len(s));
}
@@ -1419,7 +1419,7 @@ void debug_dma_unmap_sg(struct device *dev, struct scatterlist *sglist,
struct dma_debug_entry ref = {
.type = dma_debug_sg,
.dev = dev,
- .pfn = page_to_pfn(sg_page(s)),
+ .pfn = sg_pfn(s),
.offset = s->offset,
.dev_addr = sg_dma_address(s),
.size = sg_dma_len(s),
@@ -1580,7 +1580,7 @@ void debug_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
struct dma_debug_entry ref = {
.type = dma_debug_sg,
.dev = dev,
- .pfn = page_to_pfn(sg_page(s)),
+ .pfn = sg_pfn(s),
.offset = s->offset,
.dev_addr = sg_dma_address(s),
.size = sg_dma_len(s),
@@ -1613,7 +1613,7 @@ void debug_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
struct dma_debug_entry ref = {
.type = dma_debug_sg,
.dev = dev,
- .pfn = page_to_pfn(sg_page(s)),
+ .pfn = sg_pfn(s),
.offset = s->offset,
.dev_addr = sg_dma_address(s),
.size = sg_dma_len(s),
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:30 +0200 |
| Subject | [PATCH 06/31] alpha/pci-noop: handle page-less SG entries |
| Message-ID | <pWyE2-5X6-19@gated-at.bofh.it> |
| In reply to | #1205647 |
Use sg_phys() instead of virt_to_phys(sg_virt(sg)) so that we don't
require a kernel virtual address.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
arch/alpha/kernel/pci-noop.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/alpha/kernel/pci-noop.c b/arch/alpha/kernel/pci-noop.c
index df24b76..7319151 100644
--- a/arch/alpha/kernel/pci-noop.c
+++ b/arch/alpha/kernel/pci-noop.c
@@ -145,11 +145,7 @@ static int alpha_noop_map_sg(struct device *dev, struct scatterlist *sgl, int ne
struct scatterlist *sg;
for_each_sg(sgl, sg, nents, i) {
- void *va;
-
- BUG_ON(!sg_page(sg));
- va = sg_virt(sg);
- sg_dma_address(sg) = (dma_addr_t)virt_to_phys(va);
+ sg_dma_address(sg) = (dma_addr_t)sg_phys(sg);
sg_dma_len(sg) = sg->length;
}
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:30 +0200 |
| Subject | [PATCH 02/31] scatterlist: use sg_phys() |
| Message-ID | <pWyE3-5X6-35@gated-at.bofh.it> |
| In reply to | #1205647 |
From: Dan Williams <dan.j.williams@intel.com>
Coccinelle cleanup to replace open coded sg to physical address
translations. This is in preparation for introducing scatterlists that
reference __pfn_t.
// sg_phys.cocci: convert usage page_to_phys(sg_page(sg)) to sg_phys(sg)
// usage: make coccicheck COCCI=sg_phys.cocci MODE=patch
virtual patch
@@
struct scatterlist *sg;
@@
- page_to_phys(sg_page(sg)) + sg->offset
+ sg_phys(sg)
@@
struct scatterlist *sg;
@@
- page_to_phys(sg_page(sg))
+ sg_phys(sg) & PAGE_MASK
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
arch/arm/mm/dma-mapping.c | 2 +-
arch/microblaze/kernel/dma.c | 3 +--
drivers/iommu/intel-iommu.c | 4 ++--
drivers/iommu/iommu.c | 2 +-
drivers/staging/android/ion/ion_chunk_heap.c | 4 ++--
5 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index cba12f3..3d3d6aa 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1520,7 +1520,7 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
return -ENOMEM;
for (count = 0, s = sg; count < (size >> PAGE_SHIFT); s = sg_next(s)) {
- phys_addr_t phys = page_to_phys(sg_page(s));
+ phys_addr_t phys = sg_phys(s) & PAGE_MASK;
unsigned int len = PAGE_ALIGN(s->offset + s->length);
if (!is_coherent &&
diff --git a/arch/microblaze/kernel/dma.c b/arch/microblaze/kernel/dma.c
index bf4dec2..c89da63 100644
--- a/arch/microblaze/kernel/dma.c
+++ b/arch/microblaze/kernel/dma.c
@@ -61,8 +61,7 @@ static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
/* FIXME this part of code is untested */
for_each_sg(sgl, sg, nents, i) {
sg->dma_address = sg_phys(sg);
- __dma_sync(page_to_phys(sg_page(sg)) + sg->offset,
- sg->length, direction);
+ __dma_sync(sg_phys(sg), sg->length, direction);
}
return nents;
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
index 0649b94..3541d65 100644
--- a/drivers/iommu/intel-iommu.c
+++ b/drivers/iommu/intel-iommu.c
@@ -2097,7 +2097,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
sg_res = aligned_nrpages(sg->offset, sg->length);
sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + sg->offset;
sg->dma_length = sg->length;
- pteval = page_to_phys(sg_page(sg)) | prot;
+ pteval = (sg_phys(sg) & PAGE_MASK) | prot;
phys_pfn = pteval >> VTD_PAGE_SHIFT;
}
@@ -3623,7 +3623,7 @@ static int intel_nontranslate_map_sg(struct device *hddev,
for_each_sg(sglist, sg, nelems, i) {
BUG_ON(!sg_page(sg));
- sg->dma_address = page_to_phys(sg_page(sg)) + sg->offset;
+ sg->dma_address = sg_phys(sg);
sg->dma_length = sg->length;
}
return nelems;
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index f286090..049df49 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -1408,7 +1408,7 @@ size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
min_pagesz = 1 << __ffs(domain->ops->pgsize_bitmap);
for_each_sg(sg, s, nents, i) {
- phys_addr_t phys = page_to_phys(sg_page(s)) + s->offset;
+ phys_addr_t phys = sg_phys(s);
/*
* We are mapping on IOMMU page boundaries, so offset within
diff --git a/drivers/staging/android/ion/ion_chunk_heap.c b/drivers/staging/android/ion/ion_chunk_heap.c
index 5474615..f7b6ef9 100644
--- a/drivers/staging/android/ion/ion_chunk_heap.c
+++ b/drivers/staging/android/ion/ion_chunk_heap.c
@@ -81,7 +81,7 @@ static int ion_chunk_heap_allocate(struct ion_heap *heap,
err:
sg = table->sgl;
for (i -= 1; i >= 0; i--) {
- gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
+ gen_pool_free(chunk_heap->pool, sg_phys(sg) & PAGE_MASK,
sg->length);
sg = sg_next(sg);
}
@@ -109,7 +109,7 @@ static void ion_chunk_heap_free(struct ion_buffer *buffer)
DMA_BIDIRECTIONAL);
for_each_sg(table->sgl, sg, table->nents, i) {
- gen_pool_free(chunk_heap->pool, page_to_phys(sg_page(sg)),
+ gen_pool_free(chunk_heap->pool, sg_phys(sg) & PAGE_MASK,
sg->length);
}
chunk_heap->allocated -= allocated_size;
--
1.9.1
--
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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-12 09:30 +0200 |
| Subject | [PATCH 01/31] scatterlist: add sg_pfn and sg_has_page helpers |
| Message-ID | <pWyE3-5X6-39@gated-at.bofh.it> |
| In reply to | #1205647 |
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
include/linux/scatterlist.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 9b1ef0c..b1056bf 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -230,6 +230,16 @@ static inline dma_addr_t sg_phys(struct scatterlist *sg)
return page_to_phys(sg_page(sg)) + sg->offset;
}
+static inline unsigned long sg_pfn(struct scatterlist *sg)
+{
+ return page_to_pfn(sg_page(sg));
+}
+
+static inline bool sg_has_page(struct scatterlist *sg)
+{
+ return true;
+}
+
/**
* sg_virt - Return virtual address of an sg entry
* @sg: SG entry
--
1.9.1
--
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]
| From | Boaz Harrosh <boaz@plexistor.com> |
|---|---|
| Date | 2015-08-12 14:50 +0200 |
| Message-ID | <pWDDI-4EJ-5@gated-at.bofh.it> |
| In reply to | #1205647 |
On 08/12/2015 10:05 AM, Christoph Hellwig wrote: > Dan Williams started to look into addressing I/O to and from > Persistent Memory in his series from June: > > http://thread.gmane.org/gmane.linux.kernel.cross-arch/27944 > > I've started looking into DMA mapping of these SGLs specifically instead > of the map_pfn method in there. In addition to supporting NVDIMM backed > I/O I also suspect this would be highly useful for media drivers that > go through nasty hoops to be able to DMA from/to their ioremapped regions, > with vb2_dc_get_userptr in drivers/media/v4l2-core/videobuf2-dma-contig.c > being a prime example for the unsafe hacks currently used. > The support I have suggested and submitted for zone-less sections. (In my add_persistent_memory() patchset) Would work perfectly well and transparent for all such multimedia cases. (All hacks removed). In fact I have loaded pmem (with-pages) on a VRAM a few times and it is great easy fun. (I wanted to experiment with cached memory over a pcie) > It turns out most DMA mapping implementation can handle SGLs without > page structures with some fairly simple mechanical work. Most of it > is just about consistently using sg_phys. For implementations that > need to flush caches we need a new helper that skips these cache > flushes if a entry doesn't have a kernel virtual address. > > However the ccio (parisc) and sba_iommu (parisc & ia64) IOMMUs seem > to be operate mostly on virtual addresses. It's a fairly odd concept > that I don't fully grasp, so I'll need some help with those if we want > to bring this forward. > > Additional this series skips ARM entirely for now. The reason is > that most arm implementations of the .map_sg operation just iterate > over all entries and call ->map_page for it, which means we'd need > to convert those to a ->map_pfn similar to Dan's previous approach. > All this endless work for nothing more than uglyfing the Kernel, and It will never end. When a real and fully working solution is right here for more then a year. If you are really up for a deep audit and a mammoth testing effort, why not do a more worthy, and order of magnitude smaller work and support 2M and 1G variable sized "pages". All the virtual-vs-phisical-vs-caching just works. Most of the core work is there. Block layer and lots of other subsytems already support sending a single page-pointer with bvec_offset bvec_len bigger then 4K. Other system will be small fixes sprinkled around but not at all this endless stream of subsystem after another of patches. And for why. The novelty of pages is the section object, the section is reached from page* from virtual as well as physical planes. And is a center that translate from all plains to all plains. You keep this concept only make 2M-page sections and 1G-page sections. It is a bit of work but is worth while, and accelerating tremendously lots of workloads. Not like this abomination which only branches things more and more, and making things fatter and slower. It all feels like a typhoon, the inertia of tones and tons of men hours work, in a huge wave. How will you ever stop such a rushing mass. I'm trying to dock under but, surly it makes me sad. Thanks Boaz -- 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]
| From | Julian Calaby <julian.calaby@gmail.com> |
|---|---|
| Date | 2015-08-13 01:40 +0200 |
| Message-ID | <pWNMJ-2tG-1@gated-at.bofh.it> |
| In reply to | #1206055 |
Hi, On Wed, Aug 12, 2015 at 10:42 PM, Boaz Harrosh <boaz@plexistor.com> wrote: > On 08/12/2015 10:05 AM, Christoph Hellwig wrote: >> It turns out most DMA mapping implementation can handle SGLs without >> page structures with some fairly simple mechanical work. Most of it >> is just about consistently using sg_phys. For implementations that >> need to flush caches we need a new helper that skips these cache >> flushes if a entry doesn't have a kernel virtual address. >> >> However the ccio (parisc) and sba_iommu (parisc & ia64) IOMMUs seem >> to be operate mostly on virtual addresses. It's a fairly odd concept >> that I don't fully grasp, so I'll need some help with those if we want >> to bring this forward. >> >> Additional this series skips ARM entirely for now. The reason is >> that most arm implementations of the .map_sg operation just iterate >> over all entries and call ->map_page for it, which means we'd need >> to convert those to a ->map_pfn similar to Dan's previous approach. >> > [snip] > > It is a bit of work but is worth while, and accelerating tremendously > lots of workloads. Not like this abomination which only branches > things more and more, and making things fatter and slower. As a random guy reading a big bunch of patches on code I know almost nothing about, parts of this comment really resonated with me: overall, we seem to be adding a lot of if statements to code that appears to be in a hot path. I.e. ~90% of this patch set seems to be just mechanically dropping BUG_ON()s and converting open coded stuff to use accessor functions (which should be macros or get inlined, right?) - and the remaining bit is not flushing if we don't have a physical page somewhere. Would it make sense to split this patch set into a few bits: one to drop all the useless BUG_ON()s, one to convert all the open coded stuff to accessor functions, then another to do the actual page-less sg stuff? Thanks, -- Julian Calaby Email: julian.calaby@gmail.com Profile: http://www.google.com/profiles/julian.calaby/ -- 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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-13 16:40 +0200 |
| Subject | Re: RFC: prepare for struct scatterlist entries without page backing |
| Message-ID | <pX1PI-652-19@gated-at.bofh.it> |
| In reply to | #1206413 |
On Thu, Aug 13, 2015 at 09:37:37AM +1000, Julian Calaby wrote: > I.e. ~90% of this patch set seems to be just mechanically dropping > BUG_ON()s and converting open coded stuff to use accessor functions > (which should be macros or get inlined, right?) - and the remaining > bit is not flushing if we don't have a physical page somewhere. Which is was 90%. By lines changed most actually is the diffs for the cache flushing. > Would it make sense to split this patch set into a few bits: one to > drop all the useless BUG_ON()s, one to convert all the open coded > stuff to accessor functions, then another to do the actual page-less > sg stuff? Without the ifs the BUG_ON() actually are useful to assert we never feed the sort of physical addresses we can't otherwise support, so I don't think that part is doable. A simple series to make more use of sg_phys and add sg_pfn might still be useful, though. -- 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]
| From | Julian Calaby <julian.calaby@gmail.com> |
|---|---|
| Date | 2015-08-14 01:50 +0200 |
| Message-ID | <pXapX-1zR-1@gated-at.bofh.it> |
| In reply to | #1206865 |
Hi Christoph, On Fri, Aug 14, 2015 at 12:35 AM, Christoph Hellwig <hch@lst.de> wrote: > On Thu, Aug 13, 2015 at 09:37:37AM +1000, Julian Calaby wrote: >> I.e. ~90% of this patch set seems to be just mechanically dropping >> BUG_ON()s and converting open coded stuff to use accessor functions >> (which should be macros or get inlined, right?) - and the remaining >> bit is not flushing if we don't have a physical page somewhere. > > Which is was 90%. By lines changed most actually is the diffs for > the cache flushing. I was talking in terms of changes made, not lines changed: by my recollection, about a third of the patches didn't touch flush calls and most of the lines changed looked like refactoring so that making the flush call conditional would be easier. I guess it smelled like you were doing lots of distinct changes in a single patch and I got my numbers wrong. >> Would it make sense to split this patch set into a few bits: one to >> drop all the useless BUG_ON()s, one to convert all the open coded >> stuff to accessor functions, then another to do the actual page-less >> sg stuff? > > Without the ifs the BUG_ON() actually are useful to assert we > never feed the sort of physical addresses we can't otherwise support, > so I don't think that part is doable. My point is that there's a couple of patches that only remove BUG_ON()s, which implies that for that particular driver it doesn't matter if there's a physical page or not, so therefore that code is purely "documentation". Thanks, -- Julian Calaby Email: julian.calaby@gmail.com Profile: http://www.google.com/profiles/julian.calaby/ -- 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]
| From | Christoph Hellwig <hch@lst.de> |
|---|---|
| Date | 2015-08-13 16:50 +0200 |
| Subject | Re: RFC: prepare for struct scatterlist entries without page backing |
| Message-ID | <pX1Zn-6gD-1@gated-at.bofh.it> |
| In reply to | #1206055 |
On Wed, Aug 12, 2015 at 03:42:47PM +0300, Boaz Harrosh wrote:
> The support I have suggested and submitted for zone-less sections.
> (In my add_persistent_memory() patchset)
>
> Would work perfectly well and transparent for all such multimedia cases.
> (All hacks removed). In fact I have loaded pmem (with-pages) on a VRAM
> a few times and it is great easy fun. (I wanted to experiment with cached
> memory over a pcie)
And everyone agree that it was both buggy and incomplete.
Dan has done a respin of the page backed nvdimm work with most of
these comments addressed.
I have to say I hate both pfn-based I/O [1] and page backed nvdimms with
passion, so we're looking into the lesser evil with an open mind.
[1] not the SGL part posted here, which I think is quite sane. The bio
side is much worse, though.
--
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]
| From | Boaz Harrosh <boaz@plexistor.com> |
|---|---|
| Date | 2015-08-13 17:50 +0200 |
| Message-ID | <pX2Vs-7C5-11@gated-at.bofh.it> |
| In reply to | #1206868 |
On 08/13/2015 05:40 PM, Christoph Hellwig wrote: > On Wed, Aug 12, 2015 at 03:42:47PM +0300, Boaz Harrosh wrote: >> The support I have suggested and submitted for zone-less sections. >> (In my add_persistent_memory() patchset) >> >> Would work perfectly well and transparent for all such multimedia cases. >> (All hacks removed). In fact I have loaded pmem (with-pages) on a VRAM >> a few times and it is great easy fun. (I wanted to experiment with cached >> memory over a pcie) > > And everyone agree that it was both buggy and incomplete. > What? No one ever said anything about bugs. Is the first ever I hear of it. I was always in the notion that no one even tried it out. I'm smoking these page-full nvidimms for more than a year. With RDMA to pears and swap out to disks. So is not that bad I would say > Dan has done a respin of the page backed nvdimm work with most of > these comments addressed. > I would love some comments. All I got so far is silence. (And I do not like Dan's patches comments will come next week) > I have to say I hate both pfn-based I/O [1] and page backed nvdimms with > passion, so we're looking into the lesser evil with an open mind. > > [1] not the SGL part posted here, which I think is quite sane. The bio > side is much worse, though. > What can I say. I like the page-backed nvdimms. And the long term for me is 2M pages. I hope we can sit one day soon and you explain to me whats evil about it. I would really really like to understand Thanks though Boaz -- 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]
| From | James Bottomley <James.Bottomley@HansenPartnership.com> |
|---|---|
| Date | 2015-08-12 19:10 +0200 |
| Message-ID | <pWHHl-2fW-17@gated-at.bofh.it> |
| In reply to | #1205647 |
On Wed, 2015-08-12 at 09:05 +0200, Christoph Hellwig wrote: > Dan Williams started to look into addressing I/O to and from > Persistent Memory in his series from June: > > http://thread.gmane.org/gmane.linux.kernel.cross-arch/27944 > > I've started looking into DMA mapping of these SGLs specifically instead > of the map_pfn method in there. In addition to supporting NVDIMM backed > I/O I also suspect this would be highly useful for media drivers that > go through nasty hoops to be able to DMA from/to their ioremapped regions, > with vb2_dc_get_userptr in drivers/media/v4l2-core/videobuf2-dma-contig.c > being a prime example for the unsafe hacks currently used. > > It turns out most DMA mapping implementation can handle SGLs without > page structures with some fairly simple mechanical work. Most of it > is just about consistently using sg_phys. For implementations that > need to flush caches we need a new helper that skips these cache > flushes if a entry doesn't have a kernel virtual address. > > However the ccio (parisc) and sba_iommu (parisc & ia64) IOMMUs seem > to be operate mostly on virtual addresses. It's a fairly odd concept > that I don't fully grasp, so I'll need some help with those if we want > to bring this forward. I can explain that. I think this doesn't apply to ia64 because it's cache is PIPT, but on parisc, we have a VIPT cache. On normal physically indexed architectures, when the iommu sees a DMA transfer to/from physical memory, it also notifies the CPU to flush the internal CPU caches of those lines. This is usually an interlocking step of the transfer to make sure the page is coherent before transfer to/from the device (it's why the ia32 for instance is a coherent architecture). Because the system is physically indexed, there's no need to worry about aliases. On Virtually Indexed systems, like parisc, there is an aliasing problem. The CCIO iommu unit (and all other iommu systems on parisc) have what's called a local coherence index (LCI). You program it as part of the IOMMU page table and it tells the system which Virtual line in the cache to flush as part of the IO transaction, thus still ensuring cache coherence. That's why we have to know the virtual as well as physical addresses for the page. The problem we have in Linux is that we have two virtual addresses, which are often incoherent aliases: the user virtual address and a kernel virtual address but we can only make the page coherent with a single alias (only one LCI). The way I/O on Linux currently works is that get_user_pages actually flushes the user virtual address, so that's expected to be coherent, so the address we program into the VCI is the kernel virtual address. Usually nothing in the kernel has ever touched the page, so there's nothing to flush, but we do it just in case. In theory, for these non kernel page backed SG entries, we can make the process more efficient by not flushing in gup and instead programming the user virtual address into the local coherence index. However, simply zeroing the LCI will also work (except that poor VI zero line will get flushed repeatedly, so it's probably best to pick a known untouched line in the kernel). James -- 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]
| From | Grant Grundler <grantgrundler@gmail.com> |
|---|---|
| Date | 2015-08-12 20:00 +0200 |
| Message-ID | <pWItH-3b8-1@gated-at.bofh.it> |
| In reply to | #1206280 |
On Wed, Aug 12, 2015 at 10:00 AM, James Bottomley <James.Bottomley@hansenpartnership.com> wrote: > On Wed, 2015-08-12 at 09:05 +0200, Christoph Hellwig wrote: ... >> However the ccio (parisc) and sba_iommu (parisc & ia64) IOMMUs seem >> to be operate mostly on virtual addresses. It's a fairly odd concept >> that I don't fully grasp, so I'll need some help with those if we want >> to bring this forward. James explained the primary function of IOMMUs on parisc (DMA-Cache coherency) much better than I ever could. Three more observations: 1) the IOMMU can be bypassed by 64-bit DMA devices on IA64. 2) IOMMU enables 32-bit DMA devices to reach > 32-bit physical memory and thus avoiding bounce buffers. parisc and older IA-64 have some 32-bit PCI devices - e.g. IDE boot HDD. 3) IOMMU acts as a proxy for IO devices by fetching cachelines of data for PA-RISC systems whose memory controllers ONLY serve cacheline sized transactions. ie. 32-bit DMA results in the IOMMU fetching the cacheline and updating just the 32-bits in a DMA cache coherent fashion. Bonus thought: 4) IOMMU can improve DMA performance in some cases using "hints" provided by the OS (e.g. prefetching DMA data or using READ_CURRENT bus transactions instead of normal memory fetches.) cheers, grant -- 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