Thread (14 messages) 14 messages, 6 authors, 2019-11-20

Re: [PATCH 1/3] dma-direct: unify the dma_capable definitions

From: Marek Szyprowski <m.szyprowski@samsung.com>
Date: 2019-11-19 09:27:41
Also in: linux-mips, linux-samsung-soc, linuxppc-dev

Hi Christoph,

On 13.11.2019 08:35, Christoph Hellwig wrote:
Currently each architectures that wants to override dma_to_phys and
phys_to_dma also has to provide dma_capable.  But there isn't really
any good reason for that.  powerpc and mips just have copies of the
generic one minus the latests fix, and the arm one was the inspiration
for said fix, but misses the bus_dma_mask handling.
Make all architectures use the generic version instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
This patch breaks DMAengine PL330 driver on Samsung Exynos SoCs:

[    3.602338] dma-pl330 12690000.pdma: overflow 0x13810020+1 of DMA 
mask ffffffff bus mask 0
[    3.605113] ------------[ cut here ]------------
[    3.609719] WARNING: CPU: 2 PID: 1 at kernel/dma/direct.c:36 
report_addr+0xc0/0xfc
[    3.617226] Modules linked in:
[    3.620271] CPU: 2 PID: 1 Comm: init Not tainted 
5.4.0-rc5-00056-gb037b220e71d #6911
[    3.627986] Hardware name: SAMSUNG EXYNOS (Flattened Device Tree)
[    3.634094] [<c01124e8>] (unwind_backtrace) from [<c010dfcc>] 
(show_stack+0x10/0x14)
[    3.641803] [<c010dfcc>] (show_stack) from [<c0ae9af8>] 
(dump_stack+0xa8/0xd4)
[    3.649002] [<c0ae9af8>] (dump_stack) from [<c012746c>] 
(__warn+0xf4/0x10c)
[    3.655940] [<c012746c>] (__warn) from [<c0127534>] 
(warn_slowpath_fmt+0xb0/0xb8)
[    3.663404] [<c0127534>] (warn_slowpath_fmt) from [<c01b4ff4>] 
(report_addr+0xc0/0xfc)
[    3.671303] [<c01b4ff4>] (report_addr) from [<c01b5264>] 
(dma_direct_map_resource+0x98/0xa0)
[    3.679739] [<c01b5264>] (dma_direct_map_resource) from [<c04fbb58>] 
(pl330_prep_slave_fifo+0xe4/0x128)
[    3.689099] [<c04fbb58>] (pl330_prep_slave_fifo) from [<c04fe2b8>] 
(pl330_prep_slave_sg+0x54/0x1cc)
[    3.698129] [<c04fe2b8>] (pl330_prep_slave_sg) from [<c053e5f0>] 
(s3c24xx_serial_start_tx_dma+0x118/0x1e8)
[    3.707764] [<c053e5f0>] (s3c24xx_serial_start_tx_dma) from 
[<c0535f70>] (uart_write+0xe4/0x1e0)
[    3.716532] [<c0535f70>] (uart_write) from [<c05186a0>] 
(n_tty_write+0x1c8/0x474)
[    3.723992] [<c05186a0>] (n_tty_write) from [<c05163c0>] 
(tty_write+0x154/0x314)
[    3.731380] [<c05163c0>] (tty_write) from [<c02a5748>] 
(__vfs_write+0x30/0x1d0)
[    3.738662] [<c02a5748>] (__vfs_write) from [<c02a851c>] 
(vfs_write+0xa4/0x180)
[    3.745949] [<c02a851c>] (vfs_write) from [<c02a8778>] 
(ksys_write+0x60/0xd8)
[    3.753069] [<c02a8778>] (ksys_write) from [<c0101000>] 
(ret_fast_syscall+0x0/0x28)
[    3.760705] Exception stack(0xee8dffa8 to 0xee8dfff0)
[    3.765739] ffa0:                   0000004a beca876c 00000002 
beca876c 0000004a 00000000
[    3.773900] ffc0: 0000004a beca876c b6f02cf0 00000004 beca876c 
0000004a 00000000 b6f99010
[    3.782056] ffe0: 0000006c beca8628 b6e1d000 b6e7a634
[    3.787092] irq event stamp: 289740
[    3.790571] hardirqs last  enabled at (289739): [<c0b0d0c4>] 
_raw_spin_unlock_irqrestore+0x6c/0x74
[    3.799503] hardirqs last disabled at (289740): [<c0b0caf8>] 
_raw_spin_lock_irqsave+0x1c/0x58
[    3.808011] softirqs last  enabled at (289576): [<c01026bc>] 
__do_softirq+0x4fc/0x5fc
[    3.815830] softirqs last disabled at (289567): [<c0130044>] 
irq_exit+0x16c/0x170
[    3.823286] ---[ end trace b1432c658797b861 ]---
[    3.827898] samsung-uart 13810000.serial: Unable to get desc for Tx
[    3.834624] samsung-uart 13810000.serial: Unable to get desc for Tx
[    3.840487] samsung-uart 13810000.serial: Unable to get desc for Tx

I'm checking now which part of it causes the issue.

quoted hunk ↗ jump to hunk
---
  arch/arm/include/asm/dma-direct.h     | 19 -------------------
  arch/mips/include/asm/dma-direct.h    |  8 --------
  arch/powerpc/include/asm/dma-direct.h |  9 ---------
  include/linux/dma-direct.h            |  2 +-
  4 files changed, 1 insertion(+), 37 deletions(-)
diff --git a/arch/arm/include/asm/dma-direct.h b/arch/arm/include/asm/dma-direct.h
index b67e5fc1fe43..7c3001a6a775 100644
--- a/arch/arm/include/asm/dma-direct.h
+++ b/arch/arm/include/asm/dma-direct.h
@@ -14,23 +14,4 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
  	return __pfn_to_phys(dma_to_pfn(dev, dev_addr)) + offset;
  }
  
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	u64 limit, mask;
-
-	if (!dev->dma_mask)
-		return 0;
-
-	mask = *dev->dma_mask;
-
-	limit = (mask + 1) & ~mask;
-	if (limit && size > limit)
-		return 0;
-
-	if ((addr | (addr + size - 1)) & ~mask)
-		return 0;
-
-	return 1;
-}
-
  #endif /* ASM_ARM_DMA_DIRECT_H */
diff --git a/arch/mips/include/asm/dma-direct.h b/arch/mips/include/asm/dma-direct.h
index b5c240806e1b..14e352651ce9 100644
--- a/arch/mips/include/asm/dma-direct.h
+++ b/arch/mips/include/asm/dma-direct.h
@@ -2,14 +2,6 @@
  #ifndef _MIPS_DMA_DIRECT_H
  #define _MIPS_DMA_DIRECT_H 1
  
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <= *dev->dma_mask;
-}
-
  dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr);
  phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t daddr);
  
diff --git a/arch/powerpc/include/asm/dma-direct.h b/arch/powerpc/include/asm/dma-direct.h
index a2912b47102c..e29e8a236b8d 100644
--- a/arch/powerpc/include/asm/dma-direct.h
+++ b/arch/powerpc/include/asm/dma-direct.h
@@ -2,15 +2,6 @@
  #ifndef ASM_POWERPC_DMA_DIRECT_H
  #define ASM_POWERPC_DMA_DIRECT_H 1
  
-static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
-{
-	if (!dev->dma_mask)
-		return false;
-
-	return addr + size - 1 <=
-		min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
-}
-
  static inline dma_addr_t __phys_to_dma(struct device *dev, phys_addr_t paddr)
  {
  	if (!dev)
diff --git a/include/linux/dma-direct.h b/include/linux/dma-direct.h
index 6db863c3eb93..991f8aa2676e 100644
--- a/include/linux/dma-direct.h
+++ b/include/linux/dma-direct.h
@@ -24,6 +24,7 @@ static inline phys_addr_t __dma_to_phys(struct device *dev, dma_addr_t dev_addr)
  
  	return paddr + ((phys_addr_t)dev->dma_pfn_offset << PAGE_SHIFT);
  }
+#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
  
  static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
  {
@@ -38,7 +39,6 @@ static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
  
  	return end <= min_not_zero(*dev->dma_mask, dev->bus_dma_mask);
  }
-#endif /* !CONFIG_ARCH_HAS_PHYS_TO_DMA */
  
  #ifdef CONFIG_ARCH_HAS_FORCE_DMA_UNENCRYPTED
  bool force_dma_unencrypted(struct device *dev);
Best regards
-- 
Marek Szyprowski, PhD
Samsung R&D Institute Poland


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help