Skip to contentSkip to conversation

: ixp4xx: Fix 3.7 regression for IXP4xx ethernet driver

PATCH RESEND New Simon Kågström 4 participants 10 messages Mar 17, 2014 – Mar 20, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

v2 cover : ixp4xx: Fix 3.7 regression for IXP4xx ethernet driver

Hi!

These two patches fixes the regression introduced in 3.7 by commit 1a4901177574083c35fafc24c4d151c2a7c7647c,

ixp4xx_eth: avoid calling dma_pool_create() with NULL dev

The patch above is not incorrect itself, but causes the driver to fail with

  [   33.055473] net eth1: coherent DMA mask is unset
  [   33.055523] net eth1: coherent allocation too big (requested 0x1000 mask 0x0)

The two patches fix this by generalizing and correcting the ixp4xx dma_set_coherent_mask(), which earlier only dealt with the PCI case. The second patch simply sets up the mask for the ixp4xx ethernet device.

The patches have been verified on a board with 256MiB memory, one ipx4xx_eth device and a e100 PCI device, running Linus' tip.

This issue has been discussed before:

https://lkml.org/lkml/2014/1/2/46
http://lists.infradead.org/pipermail/linux-arm-kernel/2013-February/148811.html

This is a resend of the patch series. There was some discussion about it here:

http://www.spinics.net/lists/arm-kernel/msg313082.html

and if I understand Russels comments (as per the documentation), drivers should setup the coherent DMA mask even if it happens to be the platform/CPU default.

ChangeLog:

v2: Move EXPORT_SYMBOL together with dma_set_coherent_mask

// Simon

#1 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Non-PCI devices can use the entire 32-bit range, PCI dittos are limited to the first 64MiB.

Also actually setup coherent_dma_mask.

The patch has been verified on a board with 128MiB memory, one ipx4xx_eth device and a e100 PCI device.

---
ChangeLog:

* v2: Move EXPORT_SYMBOL together with dma_set_coherent_mask (Anrd Bergmann)

 arch/arm/mach-ixp4xx/common-pci.c |    9 ---------
 arch/arm/mach-ixp4xx/common.c     |   12 ++++++++++++
 2 files changed, 12 insertions(+), 9 deletions(-)
arch/arm/mach-ixp4xx/common-pci.c +0 -9
index 200970d..055d816 100644
@@ -481,14 +481,5 @@ int ixp4xx_setup(int nr, struct pci_sys_data *sys)
 	return 1;
 }
 
-int dma_set_coherent_mask(struct device *dev, u64 mask)
-{
-	if (mask >= SZ_64M - 1)
-		return 0;
-
-	return -EIO;
-}
-
 EXPORT_SYMBOL(ixp4xx_pci_read);
 EXPORT_SYMBOL(ixp4xx_pci_write);
-EXPORT_SYMBOL(dma_set_coherent_mask);
arch/arm/mach-ixp4xx/common.c +12 -0
index 6d68aed..df82a2b 100644
@@ -31,6 +31,7 @@
 #include <linux/gpio.h>
 #include <linux/cpu.h>
 #include <linux/sched_clock.h>
+#include <linux/pci.h>
 
 #include <mach/udc.h>
 #include <mach/hardware.h>
@@ -578,6 +579,17 @@ void ixp4xx_restart(enum reboot_mode mode, const char *cmd)
 	}
 }
 
+int dma_set_coherent_mask(struct device *dev, u64 mask)
+{
+	if (dev_is_pci(dev) && mask >= SZ_64M)
+		return -EIO;
+
+	dev->coherent_dma_mask = mask;
+
+	return 0;
+}
+EXPORT_SYMBOL(dma_set_coherent_mask);
+
 #ifdef CONFIG_IXP4XX_INDIRECT_PCI
 /*
  * In the case of using indirect PCI, we simply return the actual PCI
Signature · 1 line
1.7.9.6
#2 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Quoted 10 lines · Simon K?gstr?m

Non-PCI devices can use the entire 32-bit range, PCI dittos are limited to the first 64MiB.

Also actually setup coherent_dma_mask.

The patch has been verified on a board with 128MiB memory, one ipx4xx_eth device and a e100 PCI device.

---

I've applied this patch to the next/fixes-non-critical branch of arm-soc. Please let me know if you need to have it backported to older kernels as well.

Patch 2 should go through the netdev tree.

Arnd

#3 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Quoted 4 lines · On Tue, 18 Mar 2014 15:58:36 +0100 Arnd Bergmann <[email protected]> wrote:
Quoted 3 lines · Simon K?gstr?m

Non-PCI devices can use the entire 32-bit range, PCI dittos are limited to the first 64MiB.

Quoted 8 lines
Quoted 4 lines

Also actually setup coherent_dma_mask.

The patch has been verified on a board with 128MiB memory, one ipx4xx_eth device and a e100 PCI device.

I've applied this patch to the next/fixes-non-critical branch of arm-soc. Please let me know if you need to have it backported to older kernels as well.

Thanks. However, Krzysztof thinks that this implementation is incorrect. It certainly fixes my ixp4xx issues, but might not be good for everyone.

// Simon

#4 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Quoted 3 lines · Simon K?gstr?m

Thanks. However, Krzysztof thinks that this implementation is incorrect. It certainly fixes my ixp4xx issues, but might not be good for everyone.

It because you don't have PCI devices setting coherent mask to 32-bits (and that's what normal PCI devices do).

BTW PCI (and other) devices requesting 32-bit coherent allocs don't care if they're given 26-bit memory. 26 bits fit perfectly in 32 bits. It's the streaming mapping which is (may be) constrained by hardware.

Signature · 4 lines
Krzysztof Halasa

Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland
#5 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Quoted 6 lines · Krzysztof Ha?asa
Quoted 3 lines · Simon K?gstr?m

Thanks. However, Krzysztof thinks that this implementation is incorrect. It certainly fixes my ixp4xx issues, but might not be good for everyone.

Quoted 6 lines

It because you don't have PCI devices setting coherent mask to 32-bits (and that's what normal PCI devices do).

BTW PCI (and other) devices requesting 32-bit coherent allocs don't care if they're given 26-bit memory. 26 bits fit perfectly in 32 bits. It's the streaming mapping which is (may be) constrained by hardware.

Should I revert the patch then until we have a better fix?

Arnd

#6 lore raw

PATCH RESEND v2 1/2 ARM: ixp4xx: Make dma_set_coherent_mask common, correct implementation

Quoted 7 lines · On Thu, 20 Mar 2014 12:02:36 +0100 Arnd Bergmann <[email protected]> wrote:
Quoted 6 lines · Krzysztof Ha?asa
Quoted 3 lines · Simon K?gstr?m

Thanks. However, Krzysztof thinks that this implementation is incorrect. It certainly fixes my ixp4xx issues, but might not be good for everyone.

Quoted 8 lines
Quoted 6 lines

It because you don't have PCI devices setting coherent mask to 32-bits (and that's what normal PCI devices do).

BTW PCI (and other) devices requesting 32-bit coherent allocs don't care if they're given 26-bit memory. 26 bits fit perfectly in 32 bits. It's the streaming mapping which is (may be) constrained by hardware.

Should I revert the patch then until we have a better fix?

Yes, I think that would be good. Thanks to all for looking into it!

// Simon

#7 lore raw

PATCH RESEND v2 2/2 ixp4xx_eth: Setup coherent_dma_mask

In reply to Simon Kågström

This driver has been broken since commit 1a4901177574083c35fafc24c4d151c2a7c7647c

ixp4xx_eth: avoid calling dma_pool_create() with NULL dev

in 3.7 and would fail with

[   33.055473] net eth1: coherent DMA mask is unset
[   33.055523] net eth1: coherent allocation too big (requested 0x1000 mask 0x0)

Fix by setting up the DMA mask to the entire 32-bit range.

---
 drivers/net/ethernet/xscale/ixp4xx_eth.c |    4 ++++
 1 file changed, 4 insertions(+)
drivers/net/ethernet/xscale/ixp4xx_eth.c +4 -0
index 25283f1..e540e51 100644
@@ -1426,6 +1426,10 @@ static int eth_init_one(struct platform_device *pdev)
 	port->netdev = dev;
 	port->id = pdev->id;
 
+	err = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
+	if (err < 0)
+		goto err_free;
+
 	switch (port->id) {
 	case IXP4XX_ETH_NPEA:
 		port->regs = (struct eth_regs __iomem *)IXP4XX_EthA_BASE_VIRT;
Signature · 1 line
1.7.9.6
#8 lore raw

PATCH RESEND v2 2/2 ixp4xx_eth: Setup coherent_dma_mask

drivers/net/ethernet/xscale/ixp4xx_eth.c static int eth_init_one(struct platform_device *pdev) · line 1432

Quoted 9 lines · Simon K?gstr?m

+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c

drivers/net/ethernet/xscale/ixp4xx_eth.c +4 -0
@@ -1426,6 +1426,10 @@ static int eth_init_one(struct platform_device *pdev)
 	port->netdev = dev;
 	port->id = pdev->id;
 
+	err = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
+	if (err < 0)
+		goto err_free;
+

Yeah. One could also set both masks with the new single call. The driver uses both streaming and coherent mapping.

Signature · 4 lines
Krzysztof Halasa

Research Institute for Automation and Measurements PIAP
Al. Jerozolimskie 202, 02-486 Warsaw, Poland
#9 lore raw

PATCH RESEND v2 2/2 ixp4xx_eth: Setup coherent_dma_mask

Quoted 7 lines · Krzysztof Ha?asa
Quoted 5 lines · Simon K?gstr?m

+++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c

drivers/net/ethernet/xscale/ixp4xx_eth.c +0 -0
@@ -1426,6 +1426,10 @@ static int eth_init_one(struct platform_device *pdev)
 	port->netdev = dev;
 	port->id = pdev->id;
 
Quoted 7 lines

drivers/net/ethernet/xscale/ixp4xx_eth.c static int eth_init_one(struct platform_device *pdev) · line 1432

Quoted 4 lines
drivers/net/ethernet/xscale/ixp4xx_eth.c +4 -0
+	err = dma_set_coherent_mask(&dev->dev, DMA_BIT_MASK(32));
+	if (err < 0)
+		goto err_free;
+

Yeah. One could also set both masks with the new single call. The driver uses both streaming and coherent mapping.

The other issue with this patch set is (from DMA-API-HOWTO.txt):

The coherent coherent mask will always be able to set the same or a smaller mask as the streaming mask.

and code in places assumes that's true.

Signature · 2 lines
FTTC broadband for 0.8mile line: now at 9.7Mbps down 460kbps up... slowly
improving, and getting towards what was expected from it.