linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] ARM: mm: dma: Update coherent streaming apis with missing memory barrier
@ 2014-04-21 18:03 Santosh Shilimkar
  2014-04-22 10:28 ` Will Deacon
  0 siblings, 1 reply; 36+ messages in thread
From: Santosh Shilimkar @ 2014-04-21 18:03 UTC (permalink / raw)
  To: linux-arm-kernel

ARM coherent CPU dma map APIS are assumed to be nops on cache coherent
machines. While this is true, one still needs to ensure that no
outstanding writes are pending in CPU write buffers. To take care
of that, we at least need a memory barrier to commit those changes
to main memory.

Patch is trying to fix those cases. Without such a patch, you will
end up patching device drivers to avoid the synchronisation issues.

Cc: Russell King <linux@arm.linux.org.uk>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Nicolas Pitre <nicolas.pitre@linaro.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
 arch/arm/mm/dma-mapping.c |   57 ++++++++++++++++++++++++++++++---------------
 1 file changed, 38 insertions(+), 19 deletions(-)

diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5260f43..7c9f55d 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -83,6 +83,8 @@ static dma_addr_t arm_coherent_dma_map_page(struct device *dev, struct page *pag
 	     unsigned long offset, size_t size, enum dma_data_direction dir,
 	     struct dma_attrs *attrs)
 {
+	/* Drain cpu write buffer to main memory */
+	wmb();
 	return pfn_to_dma(dev, page_to_pfn(page)) + offset;
 }
 
@@ -117,6 +119,13 @@ static void arm_dma_sync_single_for_cpu(struct device *dev,
 	__dma_page_dev_to_cpu(page, offset, size, dir);
 }
 
+static void arm_coherent_dma_sync_single_for_cpu(struct device *dev,
+		dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+	/* Drain cpu write buffer to main memory */
+	wmb();
+}
+
 static void arm_dma_sync_single_for_device(struct device *dev,
 		dma_addr_t handle, size_t size, enum dma_data_direction dir)
 {
@@ -125,6 +134,33 @@ static void arm_dma_sync_single_for_device(struct device *dev,
 	__dma_page_cpu_to_dev(page, offset, size, dir);
 }
 
+/**
+ * arm_dma_sync_sg_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @sg: list of buffers
+ * @nents: number of buffers to map (returned from dma_map_sg)
+ * @dir: DMA transfer direction (same as was passed to dma_map_sg)
+ */
+void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	struct dma_map_ops *ops = get_dma_ops(dev);
+	struct scatterlist *s;
+	int i;
+
+	for_each_sg(sg, s, nents, i)
+		ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
+					 dir);
+}
+
+void arm_coherent_dma_sync_sg_for_cpu(struct device *dev,
+			struct scatterlist *sg,
+			int nents, enum dma_data_direction dir)
+{
+	/* Drain cpu write buffer to main memory */
+	wmb();
+}
+
 struct dma_map_ops arm_dma_ops = {
 	.alloc			= arm_dma_alloc,
 	.free			= arm_dma_free,
@@ -154,6 +190,8 @@ struct dma_map_ops arm_coherent_dma_ops = {
 	.get_sgtable		= arm_dma_get_sgtable,
 	.map_page		= arm_coherent_dma_map_page,
 	.map_sg			= arm_dma_map_sg,
+	.sync_single_for_cpu	= arm_coherent_dma_sync_single_for_cpu,
+	.sync_sg_for_cpu	= arm_coherent_dma_sync_sg_for_cpu,
 	.set_dma_mask		= arm_dma_set_mask,
 };
 EXPORT_SYMBOL(arm_coherent_dma_ops);
@@ -994,25 +1032,6 @@ void arm_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
 }
 
 /**
- * arm_dma_sync_sg_for_cpu
- * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
- * @sg: list of buffers
- * @nents: number of buffers to map (returned from dma_map_sg)
- * @dir: DMA transfer direction (same as was passed to dma_map_sg)
- */
-void arm_dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg,
-			int nents, enum dma_data_direction dir)
-{
-	struct dma_map_ops *ops = get_dma_ops(dev);
-	struct scatterlist *s;
-	int i;
-
-	for_each_sg(sg, s, nents, i)
-		ops->sync_single_for_cpu(dev, sg_dma_address(s), s->length,
-					 dir);
-}
-
-/**
  * arm_dma_sync_sg_for_device
  * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
  * @sg: list of buffers
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2014-05-06 10:01 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-21 18:03 [PATCH] ARM: mm: dma: Update coherent streaming apis with missing memory barrier Santosh Shilimkar
2014-04-22 10:28 ` Will Deacon
2014-04-22 13:49   ` Santosh Shilimkar
2014-04-22 14:08     ` Arnd Bergmann
2014-04-22 14:36       ` Santosh Shilimkar
2014-04-22 19:53         ` Arnd Bergmann
2014-04-22 19:58           ` Santosh Shilimkar
2014-04-22 20:23             ` Arnd Bergmann
2014-04-22 20:30               ` Santosh Shilimkar
2014-04-23  9:02                 ` Will Deacon
2014-04-23 16:02                   ` Catalin Marinas
2014-04-23 17:17                     ` Will Deacon
2014-04-23 18:37                       ` Russell King - ARM Linux
2014-04-23 18:58                         ` Arnd Bergmann
2014-04-23 19:04                           ` Russell King - ARM Linux
2014-04-24 10:47                             ` Catalin Marinas
2014-04-24 11:15                               ` Russell King - ARM Linux
2014-04-24 11:21                                 ` Will Deacon
2014-04-24 13:38                                   ` Santosh Shilimkar
2014-04-24 14:09                                     ` Will Deacon
2014-04-24 14:44                                       ` Santosh Shilimkar
2014-04-24 19:12                                         ` Russell King - ARM Linux
2014-04-23 19:34                           ` Jason Gunthorpe
2014-04-24 10:58                           ` Will Deacon
2014-04-24 12:12                             ` Arnd Bergmann
2014-04-24 12:37                               ` Will Deacon
2014-04-24  9:54                         ` Catalin Marinas
2014-04-24 11:13                           ` Russell King - ARM Linux
2014-04-24  9:09                       ` Catalin Marinas
2014-04-24  9:16                         ` Russell King - ARM Linux
2014-04-24 10:13                           ` Catalin Marinas
2014-05-02 21:33                       ` Joel Fernandes
2014-05-06 10:01                         ` Will Deacon
2014-04-22 15:07     ` Catalin Marinas
2014-04-22 15:18       ` Santosh Shilimkar
2014-04-22 15:30         ` Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).