Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1581185 > unrolled thread
| Started by | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| First post | 2017-02-15 11:10 +0100 |
| Last post | 2017-02-21 13:30 +0100 |
| Articles | 8 — 2 participants |
Back to article view | Back to linux.kernel
[PATCH 0/7] ARM: Fix dma_alloc_coherent() and friends for NOMMU Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-15 11:10 +0100
[PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-15 11:10 +0100
Re: [PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus Robin Murphy <robin.murphy@arm.com> - 2017-02-21 14:00 +0100
Re: [PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-21 14:10 +0100
[PATCH 5/7] ARM: NOMMU: Introduce dma operations for noMMU Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-15 11:10 +0100
Re: [PATCH 0/7] ARM: Fix dma_alloc_coherent() and friends for NOMMU Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-21 11:50 +0100
Re: [PATCH 0/7] ARM: Fix dma_alloc_coherent() and friends for NOMMU Robin Murphy <robin.murphy@arm.com> - 2017-02-21 13:20 +0100
Re: [PATCH 0/7] ARM: Fix dma_alloc_coherent() and friends for NOMMU Vladimir Murzin <vladimir.murzin@arm.com> - 2017-02-21 13:30 +0100
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-15 11:10 +0100 |
| Subject | [PATCH 0/7] ARM: Fix dma_alloc_coherent() and friends for NOMMU |
| Message-ID | <tb4H8-706-5@gated-at.bofh.it> |
Hi,
It seem that addition of cache support for M-class CPUs uncovered
latent bug in DMA usage. NOMMU memory model has been treated as being
always consistent; however, for R/M CPU classes memory can be covered
by MPU which in turn might configure RAM as Normal i.e. bufferable and
cacheable. It breaks dma_alloc_coherent() and friends, since data can
stuck in caches now or be buffered.
This patch set is trying to address the issue by providing region of
memory suitable for consistent DMA operations. It is supposed that
such region is marked by MPU as non-cacheable. Robin suggested to
advertise such memory as reserved shared-dma-pool, rather then using
homebrew command line option, and extend dma-coherent to provide
default DMA area in the similar way as it is done for CMA (PATCH
4/7). It allows us to offload all bookkeeping on generic coherent DMA
framework, and it seems that it might be reused by other architectures
like c6x and blackfin.
While reviewing/testing previous vesrions of the patch set it turned
out that dma-coherent does not take into account "dma-ranges" device
tree property, so it is addressed in PATCH 3/7.
For ARM, dedicated DMA region is required for cases other than:
- MMU/MPU is off
- cpu is v7m w/o cache support
- device is coherent
In case one of the above conditions is true dma operations are forced
to be coherent and wired with dma_noop_ops.
To make life easier NOMMU dma operations are kept in separate
compilation unit.
Since the issue was reported in the same time as Benjamin sent his
patch [1] to allow mmap for NOMMU, his case is also addressed in this
series (PATCH 1/7 and PATCH 2/7).
Thanks!
[1] http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1
Changelog:
RFC v6 -> v1
- dropped RFC tag
- added Alexandre's Tested-by
Vladimir Murzin (7):
dma: Take into account dma_pfn_offset
dma: Add simple dma_noop_mmap
drivers: dma-coherent: Account dma_pfn_offset when used with device
tree
drivers: dma-coherent: Introduce default DMA pool
ARM: NOMMU: Introduce dma operations for noMMU
ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus
ARM: dma-mapping: Remove traces of NOMMU code
.../bindings/reserved-memory/reserved-memory.txt | 3 +
arch/arm/include/asm/dma-mapping.h | 3 +-
arch/arm/mm/Kconfig | 2 +-
arch/arm/mm/Makefile | 5 +-
arch/arm/mm/dma-mapping-nommu.c | 253 +++++++++++++++++++++
arch/arm/mm/dma-mapping.c | 26 +--
drivers/base/dma-coherent.c | 76 ++++++-
lib/dma-noop.c | 29 ++-
8 files changed, 356 insertions(+), 41 deletions(-)
create mode 100644 arch/arm/mm/dma-mapping-nommu.c
--
2.0.0
[toc] | [next] | [standalone]
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-15 11:10 +0100 |
| Subject | [PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus |
| Message-ID | <tb4H8-706-15@gated-at.bofh.it> |
| In reply to | #1581185 |
Now, we have dedicated non-cacheable region for consistent DMA operations. However, that region can still be marked as bufferable by MPU, so it'd be safer to have barriers by default. Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> Tested-by: Andras Szemzo <sza@esh.hu> Tested-by: Alexandre TORGUE <alexandre.torgue@st.com> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> --- arch/arm/mm/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 0b79f12..64a1465c 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig @@ -1029,7 +1029,7 @@ config ARM_L1_CACHE_SHIFT config ARM_DMA_MEM_BUFFERABLE bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 - default y if CPU_V6 || CPU_V6K || CPU_V7 + default y if CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M help Historically, the kernel has used strongly ordered mappings to provide DMA coherent memory. With the advent of ARMv7, mapping -- 2.0.0
[toc] | [prev] | [next] | [standalone]
| From | Robin Murphy <robin.murphy@arm.com> |
|---|---|
| Date | 2017-02-21 14:00 +0100 |
| Subject | Re: [PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus |
| Message-ID | <tdicV-2HY-1@gated-at.bofh.it> |
| In reply to | #1581186 |
On 15/02/17 09:59, Vladimir Murzin wrote: > Now, we have dedicated non-cacheable region for consistent DMA > operations. However, that region can still be marked as bufferable by > MPU, so it'd be safer to have barriers by default. Makes sense - plenty of cases want their DMA buffers to still be write-combining (e.g. framebuffers have already been mentioned here), for which strongly-ordered mappings won't do. Plus you don't exactly have a choice if you've no MPU and have fixed Normal attributes for your RAM region. Reviewed-by: Robin Murphy <robin.murphy@arm.com> > Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> > Tested-by: Andras Szemzo <sza@esh.hu> > Tested-by: Alexandre TORGUE <alexandre.torgue@st.com> > Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> > --- > arch/arm/mm/Kconfig | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig > index 0b79f12..64a1465c 100644 > --- a/arch/arm/mm/Kconfig > +++ b/arch/arm/mm/Kconfig > @@ -1029,7 +1029,7 @@ config ARM_L1_CACHE_SHIFT > > config ARM_DMA_MEM_BUFFERABLE > bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 > - default y if CPU_V6 || CPU_V6K || CPU_V7 > + default y if CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M > help > Historically, the kernel has used strongly ordered mappings to > provide DMA coherent memory. With the advent of ARMv7, mapping >
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-21 14:10 +0100 |
| Subject | Re: [PATCH 6/7] ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus |
| Message-ID | <tdimD-30G-65@gated-at.bofh.it> |
| In reply to | #1585277 |
On 21/02/17 12:57, Robin Murphy wrote: > On 15/02/17 09:59, Vladimir Murzin wrote: >> Now, we have dedicated non-cacheable region for consistent DMA >> operations. However, that region can still be marked as bufferable by >> MPU, so it'd be safer to have barriers by default. > > Makes sense - plenty of cases want their DMA buffers to still be > write-combining (e.g. framebuffers have already been mentioned here), > for which strongly-ordered mappings won't do. Plus you don't exactly > have a choice if you've no MPU and have fixed Normal attributes for your > RAM region. > > Reviewed-by: Robin Murphy <robin.murphy@arm.com> Thanks! Vladimir > >> Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org> >> Tested-by: Andras Szemzo <sza@esh.hu> >> Tested-by: Alexandre TORGUE <alexandre.torgue@st.com> >> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com> >> --- >> arch/arm/mm/Kconfig | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig >> index 0b79f12..64a1465c 100644 >> --- a/arch/arm/mm/Kconfig >> +++ b/arch/arm/mm/Kconfig >> @@ -1029,7 +1029,7 @@ config ARM_L1_CACHE_SHIFT >> >> config ARM_DMA_MEM_BUFFERABLE >> bool "Use non-cacheable memory for DMA" if (CPU_V6 || CPU_V6K) && !CPU_V7 >> - default y if CPU_V6 || CPU_V6K || CPU_V7 >> + default y if CPU_V6 || CPU_V6K || CPU_V7 || CPU_V7M >> help >> Historically, the kernel has used strongly ordered mappings to >> provide DMA coherent memory. With the advent of ARMv7, mapping >> > >
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-15 11:10 +0100 |
| Subject | [PATCH 5/7] ARM: NOMMU: Introduce dma operations for noMMU |
| Message-ID | <tb4H8-706-21@gated-at.bofh.it> |
| In reply to | #1581185 |
R/M classes of cpus can have memory covered by MPU which in turn might
configure RAM as Normal i.e. bufferable and cacheable. It breaks
dma_alloc_coherent() and friends, since data can stuck in caches now
or be buffered.
This patch factors out DMA support for NOMMU configuration into
separate entity which provides dedicated dma_ops. We have to handle
there several cases:
- configurations with MMU/MPU setup
- configurations without MMU/MPU setup
- special case for M-class, since caches and MPU there are optional
In general we rely on default DMA area for coherent allocations or/and
per-device memory reserves suitable for coherent DMA, so if such
regions are set coherent allocations go from there.
In case MPU/MPU was not setup we fallback to normal page allocator for
DMA memory allocation.
In case we run M-class cpus, for configuration without cache support
(like Cortex-M3/M4) dma operations are forced to be coherent and wired
with dma-noop (such decision is made based on cacheid global
variable); however, if caches are detected there and no DMA coherent
region is given (either default or per-device), dma is disallowed even
MPU is not set - it is because M-class implement system memory map
which defines part of address space as Normal memory.
Reported-by: Alexandre Torgue <alexandre.torgue@st.com>
Reported-by: Andras Szemzo <sza@esh.hu>
Tested-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Tested-by: Andras Szemzo <sza@esh.hu>
Tested-by: Alexandre TORGUE <alexandre.torgue@st.com>
Reviewed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
arch/arm/include/asm/dma-mapping.h | 3 +-
arch/arm/mm/Makefile | 5 +-
arch/arm/mm/dma-mapping-nommu.c | 253 +++++++++++++++++++++++++++++++++++++
3 files changed, 257 insertions(+), 4 deletions(-)
create mode 100644 arch/arm/mm/dma-mapping-nommu.c
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bf02dbd..559faad 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -20,7 +20,8 @@ static inline struct dma_map_ops *__generic_dma_ops(struct device *dev)
{
if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
- return &arm_dma_ops;
+
+ return IS_ENABLED(CONFIG_MMU) ? &arm_dma_ops : &dma_noop_ops;
}
static inline struct dma_map_ops *get_dma_ops(struct device *dev)
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index 2ac7988..5796357 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -2,9 +2,8 @@
# Makefile for the linux arm-specific parts of the memory manager.
#
-obj-y := dma-mapping.o extable.o fault.o init.o \
- iomap.o
-
+obj-y := extable.o fault.o init.o iomap.o
+obj-y += dma-mapping$(MMUEXT).o
obj-$(CONFIG_MMU) += fault-armv.o flush.o idmap.o ioremap.o \
mmap.o pgd.o mmu.o pageattr.o
diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nommu.c
new file mode 100644
index 0000000..1f86580
--- /dev/null
+++ b/arch/arm/mm/dma-mapping-nommu.c
@@ -0,0 +1,253 @@
+/*
+ * Based on linux/arch/arm/mm/dma-mapping.c
+ *
+ * Copyright (C) 2000-2004 Russell King
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/export.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
+
+#include <asm/cachetype.h>
+#include <asm/cacheflush.h>
+#include <asm/outercache.h>
+#include <asm/cp15.h>
+
+#include "dma.h"
+
+/*
+ * dma_noop_ops is used if
+ * - MMU/MPU is off
+ * - cpu is v7m w/o cache support
+ * - device is coherent
+ * otherwise arm_nommu_dma_ops is used.
+ *
+ * arm_nommu_dma_ops rely on consistent DMA memory (please, refer to
+ * [1] on how to declare such memory).
+ *
+ * [1] Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
+ */
+
+static void *arm_nommu_dma_alloc(struct device *dev, size_t size,
+ dma_addr_t *dma_handle, gfp_t gfp,
+ unsigned long attrs)
+
+{
+ struct dma_map_ops *ops = &dma_noop_ops;
+
+ /*
+ * We are here because:
+ * - no consistent DMA region has been defined, so we can't
+ * continue.
+ * - there is no space left in consistent DMA region, so we
+ * only can fallback to generic allocator if we are
+ * advertised that consistency is not required.
+ */
+
+ if (attrs & DMA_ATTR_NON_CONSISTENT)
+ return ops->alloc(dev, size, dma_handle, gfp, attrs);
+
+ WARN_ON_ONCE(1);
+ return NULL;
+}
+
+static void arm_nommu_dma_free(struct device *dev, size_t size,
+ void *cpu_addr, dma_addr_t dma_addr,
+ unsigned long attrs)
+{
+ struct dma_map_ops *ops = &dma_noop_ops;
+
+ if (attrs & DMA_ATTR_NON_CONSISTENT)
+ ops->free(dev, size, cpu_addr, dma_addr, attrs);
+ else
+ WARN_ON_ONCE(1);
+
+ return;
+}
+
+static int arm_nommu_dma_mmap(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ unsigned long attrs)
+{
+ struct dma_map_ops *ops = &dma_noop_ops;
+ int ret;
+
+ if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
+ return ret;
+
+ if (attrs & DMA_ATTR_NON_CONSISTENT)
+ return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
+
+ WARN_ON_ONCE(1);
+ return -ENXIO;
+}
+
+static void __dma_page_cpu_to_dev(phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
+{
+ dmac_map_area(__va(paddr), size, dir);
+
+ if (dir == DMA_FROM_DEVICE)
+ outer_inv_range(paddr, paddr + size);
+ else
+ outer_clean_range(paddr, paddr + size);
+}
+
+static void __dma_page_dev_to_cpu(phys_addr_t paddr, size_t size,
+ enum dma_data_direction dir)
+{
+ if (dir != DMA_TO_DEVICE) {
+ outer_inv_range(paddr, paddr + size);
+ dmac_unmap_area(__va(paddr), size, dir);
+ }
+}
+
+static dma_addr_t arm_nommu_dma_map_page(struct device *dev, struct page *page,
+ unsigned long offset, size_t size,
+ enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ dma_addr_t handle = page_to_phys(page) + offset;
+
+ __dma_page_cpu_to_dev(handle, size, dir);
+
+ return handle;
+}
+
+static void arm_nommu_dma_unmap_page(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ __dma_page_dev_to_cpu(handle, size, dir);
+}
+
+
+static int arm_nommu_dma_map_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ int i;
+ struct scatterlist *sg;
+
+ for_each_sg(sgl, sg, nents, i) {
+ sg_dma_address(sg) = sg_phys(sg);
+ sg_dma_len(sg) = sg->length;
+ __dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
+ }
+
+ return nents;
+}
+
+static void arm_nommu_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir,
+ unsigned long attrs)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ __dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+static void arm_nommu_dma_sync_single_for_device(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ __dma_page_cpu_to_dev(handle, size, dir);
+}
+
+static void arm_nommu_dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ __dma_page_cpu_to_dev(handle, size, dir);
+}
+
+static void arm_nommu_dma_sync_sg_for_device(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ __dma_page_cpu_to_dev(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+static void arm_nommu_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sgl,
+ int nents, enum dma_data_direction dir)
+{
+ struct scatterlist *sg;
+ int i;
+
+ for_each_sg(sgl, sg, nents, i)
+ __dma_page_dev_to_cpu(sg_dma_address(sg), sg_dma_len(sg), dir);
+}
+
+struct dma_map_ops arm_nommu_dma_ops = {
+ .alloc = arm_nommu_dma_alloc,
+ .free = arm_nommu_dma_free,
+ .mmap = arm_nommu_dma_mmap,
+ .map_page = arm_nommu_dma_map_page,
+ .unmap_page = arm_nommu_dma_unmap_page,
+ .map_sg = arm_nommu_dma_map_sg,
+ .unmap_sg = arm_nommu_dma_unmap_sg,
+ .sync_single_for_device = arm_nommu_dma_sync_single_for_device,
+ .sync_single_for_cpu = arm_nommu_dma_sync_single_for_cpu,
+ .sync_sg_for_device = arm_nommu_dma_sync_sg_for_device,
+ .sync_sg_for_cpu = arm_nommu_dma_sync_sg_for_cpu,
+};
+EXPORT_SYMBOL(arm_nommu_dma_ops);
+
+static struct dma_map_ops *arm_nommu_get_dma_map_ops(bool coherent)
+{
+ return coherent ? &dma_noop_ops : &arm_nommu_dma_ops;
+}
+
+void arch_setup_dma_ops(struct device *dev, u64 dma_base, u64 size,
+ const struct iommu_ops *iommu, bool coherent)
+{
+ struct dma_map_ops *dma_ops;
+
+ if (IS_ENABLED(CONFIG_CPU_V7M)) {
+ /*
+ * Cache support for v7m is optional, so can be treated as
+ * coherent if no cache has been detected. Note that it is not
+ * enough to check if MPU is in use or not since in absense of
+ * MPU system memory map is used.
+ */
+ dev->archdata.dma_coherent = (cacheid) ? coherent : true;
+ } else {
+ /*
+ * Assume coherent DMA in case MMU/MPU has not been set up.
+ */
+ dev->archdata.dma_coherent = (get_cr() & CR_M) ? coherent : true;
+ }
+
+ dma_ops = arm_nommu_get_dma_map_ops(dev->archdata.dma_coherent);
+
+ set_dma_ops(dev, dma_ops);
+}
+
+void arch_teardown_dma_ops(struct device *dev)
+{
+}
+
+int dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+EXPORT_SYMBOL(dma_supported);
+
+#define PREALLOC_DMA_DEBUG_ENTRIES 4096
+
+static int __init dma_debug_do_init(void)
+{
+ dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
+ return 0;
+}
+core_initcall(dma_debug_do_init);
--
2.0.0
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-21 11:50 +0100 |
| Message-ID | <tdgb7-1jD-13@gated-at.bofh.it> |
| In reply to | #1581185 |
Gentle ping! Cc: Joerg Roedel <jroedel@suse.de> Cc: Christian Borntraeger <borntraeger@de.ibm.com> Cc: Michal Nazarewicz <mina86@mina86.com> Cc: Marek Szyprowski <m.szyprowski@samsung.com> Cc: Alan Stern <stern@rowland.harvard.edu> Cc: Yoshinori Sato <ysato@users.sourceforge.jp> Cc: Rich Felker <dalias@libc.org> Cc: Roger Quadros <rogerq@ti.com> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Cc: Rob Herring <robh+dt@kernel.org> Cc: Mark Rutland <mark.rutland@arm.com> On 15/02/17 09:59, Vladimir Murzin wrote: > Hi, > > It seem that addition of cache support for M-class CPUs uncovered > latent bug in DMA usage. NOMMU memory model has been treated as being > always consistent; however, for R/M CPU classes memory can be covered > by MPU which in turn might configure RAM as Normal i.e. bufferable and > cacheable. It breaks dma_alloc_coherent() and friends, since data can > stuck in caches now or be buffered. > > This patch set is trying to address the issue by providing region of > memory suitable for consistent DMA operations. It is supposed that > such region is marked by MPU as non-cacheable. Robin suggested to > advertise such memory as reserved shared-dma-pool, rather then using > homebrew command line option, and extend dma-coherent to provide > default DMA area in the similar way as it is done for CMA (PATCH > 4/7). It allows us to offload all bookkeeping on generic coherent DMA > framework, and it seems that it might be reused by other architectures > like c6x and blackfin. > > While reviewing/testing previous vesrions of the patch set it turned > out that dma-coherent does not take into account "dma-ranges" device > tree property, so it is addressed in PATCH 3/7. > > For ARM, dedicated DMA region is required for cases other than: > - MMU/MPU is off > - cpu is v7m w/o cache support > - device is coherent > > In case one of the above conditions is true dma operations are forced > to be coherent and wired with dma_noop_ops. > > To make life easier NOMMU dma operations are kept in separate > compilation unit. > > Since the issue was reported in the same time as Benjamin sent his > patch [1] to allow mmap for NOMMU, his case is also addressed in this > series (PATCH 1/7 and PATCH 2/7). > > Thanks! > > [1] http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1 > > Changelog: > RFC v6 -> v1 > - dropped RFC tag > - added Alexandre's Tested-by > > Vladimir Murzin (7): > dma: Take into account dma_pfn_offset > dma: Add simple dma_noop_mmap > drivers: dma-coherent: Account dma_pfn_offset when used with device > tree > drivers: dma-coherent: Introduce default DMA pool > ARM: NOMMU: Introduce dma operations for noMMU > ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus > ARM: dma-mapping: Remove traces of NOMMU code > > .../bindings/reserved-memory/reserved-memory.txt | 3 + > arch/arm/include/asm/dma-mapping.h | 3 +- > arch/arm/mm/Kconfig | 2 +- > arch/arm/mm/Makefile | 5 +- > arch/arm/mm/dma-mapping-nommu.c | 253 +++++++++++++++++++++ > arch/arm/mm/dma-mapping.c | 26 +-- > drivers/base/dma-coherent.c | 76 ++++++- > lib/dma-noop.c | 29 ++- > 8 files changed, 356 insertions(+), 41 deletions(-) > create mode 100644 arch/arm/mm/dma-mapping-nommu.c >
[toc] | [prev] | [next] | [standalone]
| From | Robin Murphy <robin.murphy@arm.com> |
|---|---|
| Date | 2017-02-21 13:20 +0100 |
| Message-ID | <tdhAe-2rg-7@gated-at.bofh.it> |
| In reply to | #1585204 |
Hi Vladimir, On 21/02/17 10:41, Vladimir Murzin wrote: > Gentle ping! What's your plan for this series? Are you looking for acks on the common parts to take it through the ARM tree, or Russell's ack on the ARM parts for it to go through mm? Either way, I expect the merge window is probably consuming most folks' attention just now. Robin. > Cc: Joerg Roedel <jroedel@suse.de> > Cc: Christian Borntraeger <borntraeger@de.ibm.com> > Cc: Michal Nazarewicz <mina86@mina86.com> > Cc: Marek Szyprowski <m.szyprowski@samsung.com> > Cc: Alan Stern <stern@rowland.harvard.edu> > Cc: Yoshinori Sato <ysato@users.sourceforge.jp> > Cc: Rich Felker <dalias@libc.org> > Cc: Roger Quadros <rogerq@ti.com> > Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> > Cc: Rob Herring <robh+dt@kernel.org> > Cc: Mark Rutland <mark.rutland@arm.com> > > On 15/02/17 09:59, Vladimir Murzin wrote: >> Hi, >> >> It seem that addition of cache support for M-class CPUs uncovered >> latent bug in DMA usage. NOMMU memory model has been treated as being >> always consistent; however, for R/M CPU classes memory can be covered >> by MPU which in turn might configure RAM as Normal i.e. bufferable and >> cacheable. It breaks dma_alloc_coherent() and friends, since data can >> stuck in caches now or be buffered. >> >> This patch set is trying to address the issue by providing region of >> memory suitable for consistent DMA operations. It is supposed that >> such region is marked by MPU as non-cacheable. Robin suggested to >> advertise such memory as reserved shared-dma-pool, rather then using >> homebrew command line option, and extend dma-coherent to provide >> default DMA area in the similar way as it is done for CMA (PATCH >> 4/7). It allows us to offload all bookkeeping on generic coherent DMA >> framework, and it seems that it might be reused by other architectures >> like c6x and blackfin. >> >> While reviewing/testing previous vesrions of the patch set it turned >> out that dma-coherent does not take into account "dma-ranges" device >> tree property, so it is addressed in PATCH 3/7. >> >> For ARM, dedicated DMA region is required for cases other than: >> - MMU/MPU is off >> - cpu is v7m w/o cache support >> - device is coherent >> >> In case one of the above conditions is true dma operations are forced >> to be coherent and wired with dma_noop_ops. >> >> To make life easier NOMMU dma operations are kept in separate >> compilation unit. >> >> Since the issue was reported in the same time as Benjamin sent his >> patch [1] to allow mmap for NOMMU, his case is also addressed in this >> series (PATCH 1/7 and PATCH 2/7). >> >> Thanks! >> >> [1] http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1 >> >> Changelog: >> RFC v6 -> v1 >> - dropped RFC tag >> - added Alexandre's Tested-by >> >> Vladimir Murzin (7): >> dma: Take into account dma_pfn_offset >> dma: Add simple dma_noop_mmap >> drivers: dma-coherent: Account dma_pfn_offset when used with device >> tree >> drivers: dma-coherent: Introduce default DMA pool >> ARM: NOMMU: Introduce dma operations for noMMU >> ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus >> ARM: dma-mapping: Remove traces of NOMMU code >> >> .../bindings/reserved-memory/reserved-memory.txt | 3 + >> arch/arm/include/asm/dma-mapping.h | 3 +- >> arch/arm/mm/Kconfig | 2 +- >> arch/arm/mm/Makefile | 5 +- >> arch/arm/mm/dma-mapping-nommu.c | 253 +++++++++++++++++++++ >> arch/arm/mm/dma-mapping.c | 26 +-- >> drivers/base/dma-coherent.c | 76 ++++++- >> lib/dma-noop.c | 29 ++- >> 8 files changed, 356 insertions(+), 41 deletions(-) >> create mode 100644 arch/arm/mm/dma-mapping-nommu.c >> >
[toc] | [prev] | [next] | [standalone]
| From | Vladimir Murzin <vladimir.murzin@arm.com> |
|---|---|
| Date | 2017-02-21 13:30 +0100 |
| Message-ID | <tdhJT-2uG-5@gated-at.bofh.it> |
| In reply to | #1585262 |
Hi Robin, On 21/02/17 12:16, Robin Murphy wrote: > Hi Vladimir, > > On 21/02/17 10:41, Vladimir Murzin wrote: >> Gentle ping! > > What's your plan for this series? Are you looking for acks on the common > parts to take it through the ARM tree, or Russell's ack on the ARM parts > for it to go through mm? Nothing particular in my mind - either way would work me. So far I have not heard feedback on common parts and it is not clear to me who should give Ack on them :( > > Either way, I expect the merge window is probably consuming most folks' > attention just now. I see. Cheers Vladimir > > Robin. > >> Cc: Joerg Roedel <jroedel@suse.de> >> Cc: Christian Borntraeger <borntraeger@de.ibm.com> >> Cc: Michal Nazarewicz <mina86@mina86.com> >> Cc: Marek Szyprowski <m.szyprowski@samsung.com> >> Cc: Alan Stern <stern@rowland.harvard.edu> >> Cc: Yoshinori Sato <ysato@users.sourceforge.jp> >> Cc: Rich Felker <dalias@libc.org> >> Cc: Roger Quadros <rogerq@ti.com> >> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org> >> Cc: Rob Herring <robh+dt@kernel.org> >> Cc: Mark Rutland <mark.rutland@arm.com> >> >> On 15/02/17 09:59, Vladimir Murzin wrote: >>> Hi, >>> >>> It seem that addition of cache support for M-class CPUs uncovered >>> latent bug in DMA usage. NOMMU memory model has been treated as being >>> always consistent; however, for R/M CPU classes memory can be covered >>> by MPU which in turn might configure RAM as Normal i.e. bufferable and >>> cacheable. It breaks dma_alloc_coherent() and friends, since data can >>> stuck in caches now or be buffered. >>> >>> This patch set is trying to address the issue by providing region of >>> memory suitable for consistent DMA operations. It is supposed that >>> such region is marked by MPU as non-cacheable. Robin suggested to >>> advertise such memory as reserved shared-dma-pool, rather then using >>> homebrew command line option, and extend dma-coherent to provide >>> default DMA area in the similar way as it is done for CMA (PATCH >>> 4/7). It allows us to offload all bookkeeping on generic coherent DMA >>> framework, and it seems that it might be reused by other architectures >>> like c6x and blackfin. >>> >>> While reviewing/testing previous vesrions of the patch set it turned >>> out that dma-coherent does not take into account "dma-ranges" device >>> tree property, so it is addressed in PATCH 3/7. >>> >>> For ARM, dedicated DMA region is required for cases other than: >>> - MMU/MPU is off >>> - cpu is v7m w/o cache support >>> - device is coherent >>> >>> In case one of the above conditions is true dma operations are forced >>> to be coherent and wired with dma_noop_ops. >>> >>> To make life easier NOMMU dma operations are kept in separate >>> compilation unit. >>> >>> Since the issue was reported in the same time as Benjamin sent his >>> patch [1] to allow mmap for NOMMU, his case is also addressed in this >>> series (PATCH 1/7 and PATCH 2/7). >>> >>> Thanks! >>> >>> [1] http://www.armlinux.org.uk/developer/patches/viewpatch.php?id=8633/1 >>> >>> Changelog: >>> RFC v6 -> v1 >>> - dropped RFC tag >>> - added Alexandre's Tested-by >>> >>> Vladimir Murzin (7): >>> dma: Take into account dma_pfn_offset >>> dma: Add simple dma_noop_mmap >>> drivers: dma-coherent: Account dma_pfn_offset when used with device >>> tree >>> drivers: dma-coherent: Introduce default DMA pool >>> ARM: NOMMU: Introduce dma operations for noMMU >>> ARM: NOMMU: Set ARM_DMA_MEM_BUFFERABLE for M-class cpus >>> ARM: dma-mapping: Remove traces of NOMMU code >>> >>> .../bindings/reserved-memory/reserved-memory.txt | 3 + >>> arch/arm/include/asm/dma-mapping.h | 3 +- >>> arch/arm/mm/Kconfig | 2 +- >>> arch/arm/mm/Makefile | 5 +- >>> arch/arm/mm/dma-mapping-nommu.c | 253 +++++++++++++++++++++ >>> arch/arm/mm/dma-mapping.c | 26 +-- >>> drivers/base/dma-coherent.c | 76 ++++++- >>> lib/dma-noop.c | 29 ++- >>> 8 files changed, 356 insertions(+), 41 deletions(-) >>> create mode 100644 arch/arm/mm/dma-mapping-nommu.c >>> >> > >
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web