linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* bisected regression: 3c59x corrupts packets in 3.17-rc5
@ 2014-09-15 23:14 Meelis Roos
  2014-09-16 10:17 ` Neil Horman
  2014-09-17 13:04 ` [PATCH 1/2] 3c59x: Add dma error checking and recovery Neil Horman
  0 siblings, 2 replies; 14+ messages in thread
From: Meelis Roos @ 2014-09-15 23:14 UTC (permalink / raw)
  To: Neil Horman; +Cc: Steffen Klassert, netdev, Linux Kernel list

Somewhere between 3.17.0-rc3 and 3.17.0-rc5 I started seeing dropped ssh 
connections to a couple of test servers with dual AthlonMP (32-bit) and 
3C90x family of NICs (3Com Corporation 3c980-C 10/100baseTX NIC 
[Python-T] (rev 78) in one server and 3Com Corporation 3c905C-TX/TX-M 
[Tornado] (rev 78) in the other server). Bisect leads to the following 
commit:

98ea232cf63961fad734cc8c5e07e8915ec73073 is the first bad commit
commit 98ea232cf63961fad734cc8c5e07e8915ec73073
Author: Neil Horman <nhorman@tuxdriver.com>
Date:   Thu Sep 4 06:13:38 2014 -0400

    3c59x: avoid panic in boomerang_start_xmit when finding page address:
    ...

-- 
Meelis Roos (mroos@linux.ee)

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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-15 23:14 bisected regression: 3c59x corrupts packets in 3.17-rc5 Meelis Roos
@ 2014-09-16 10:17 ` Neil Horman
  2014-09-16 10:32   ` Meelis Roos
                     ` (2 more replies)
  2014-09-17 13:04 ` [PATCH 1/2] 3c59x: Add dma error checking and recovery Neil Horman
  1 sibling, 3 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-16 10:17 UTC (permalink / raw)
  To: Meelis Roos; +Cc: Steffen Klassert, netdev, Linux Kernel list

On Tue, Sep 16, 2014 at 02:14:54AM +0300, Meelis Roos wrote:
> Somewhere between 3.17.0-rc3 and 3.17.0-rc5 I started seeing dropped ssh 
> connections to a couple of test servers with dual AthlonMP (32-bit) and 
> 3C90x family of NICs (3Com Corporation 3c980-C 10/100baseTX NIC 
> [Python-T] (rev 78) in one server and 3Com Corporation 3c905C-TX/TX-M 
> [Tornado] (rev 78) in the other server). Bisect leads to the following 
> commit:
> 
> 98ea232cf63961fad734cc8c5e07e8915ec73073 is the first bad commit
> commit 98ea232cf63961fad734cc8c5e07e8915ec73073
> Author: Neil Horman <nhorman@tuxdriver.com>
> Date:   Thu Sep 4 06:13:38 2014 -0400
> 
>     3c59x: avoid panic in boomerang_start_xmit when finding page address:
>     ...
> 
> -- 
> Meelis Roos (mroos@linux.ee)
> 
I'm guessing the above change has uncovered another bug, mostly likely an
exhaustion of dma space on your system.  Nothing in the transmit path there does
any error checking for successful dma mapping, which it really should.  I'd be
willing to be that any dma mapping error leads to a leak in the mapping table.
Does your system have an iommu, or does it use swiotlb?  If its the latter, can
you increase the swiotlb table space and see if that relieves the problem?  In
the interim, I'll start adding some error checking to the transmit path.

Neil


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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-16 10:17 ` Neil Horman
@ 2014-09-16 10:32   ` Meelis Roos
  2014-09-16 14:31     ` Neil Horman
  2014-09-16 14:32   ` [RFC PATCH] 3c59x: Add dma error checking and recovery Neil Horman
  2014-09-16 20:29   ` bisected regression: 3c59x corrupts packets in 3.17-rc5 David Miller
  2 siblings, 1 reply; 14+ messages in thread
From: Meelis Roos @ 2014-09-16 10:32 UTC (permalink / raw)
  To: Neil Horman; +Cc: Steffen Klassert, netdev, Linux Kernel list

[ Fixed Steffen Klasserts bouncing email address as per the bounce message ]

> > Somewhere between 3.17.0-rc3 and 3.17.0-rc5 I started seeing dropped ssh 
> > connections to a couple of test servers with dual AthlonMP (32-bit) and 
> > 3C90x family of NICs (3Com Corporation 3c980-C 10/100baseTX NIC 
> > [Python-T] (rev 78) in one server and 3Com Corporation 3c905C-TX/TX-M 
> > [Tornado] (rev 78) in the other server). Bisect leads to the following 
> > commit:
> > 
> > 98ea232cf63961fad734cc8c5e07e8915ec73073 is the first bad commit
> > commit 98ea232cf63961fad734cc8c5e07e8915ec73073
> > Author: Neil Horman <nhorman@tuxdriver.com>
> > Date:   Thu Sep 4 06:13:38 2014 -0400
> > 
> >     3c59x: avoid panic in boomerang_start_xmit when finding page address:
> >     ...
> > 
> I'm guessing the above change has uncovered another bug, mostly likely an
> exhaustion of dma space on your system.  Nothing in the transmit path there does
> any error checking for successful dma mapping, which it really should.  I'd be
> willing to be that any dma mapping error leads to a leak in the mapping table.
> Does your system have an iommu, or does it use swiotlb?  If its the latter, can
> you increase the swiotlb table space and see if that relieves the problem?  In
> the interim, I'll start adding some error checking to the transmit path.

# CONFIG_IOMMU_SUPPORT is not set

nothing matching iommu or iotlb in dmesg. I thought the system does not 
have any - K7 CPUs and AMD 760MP chipset with normal AGP gart.

[    3.763519] agpgart-amdk7 0000:00:00.0: AMD 760MP chipset
[    3.782995] agpgart-amdk7 0000:00:00.0: AGP aperture is 64M @ 0xf8000000

-- 
Meelis Roos (mroos@linux.ee)

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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-16 10:32   ` Meelis Roos
@ 2014-09-16 14:31     ` Neil Horman
  0 siblings, 0 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-16 14:31 UTC (permalink / raw)
  To: Meelis Roos; +Cc: Steffen Klassert, netdev, Linux Kernel list

On Tue, Sep 16, 2014 at 01:32:31PM +0300, Meelis Roos wrote:
> [ Fixed Steffen Klasserts bouncing email address as per the bounce message ]
> 
> > > Somewhere between 3.17.0-rc3 and 3.17.0-rc5 I started seeing dropped ssh 
> > > connections to a couple of test servers with dual AthlonMP (32-bit) and 
> > > 3C90x family of NICs (3Com Corporation 3c980-C 10/100baseTX NIC 
> > > [Python-T] (rev 78) in one server and 3Com Corporation 3c905C-TX/TX-M 
> > > [Tornado] (rev 78) in the other server). Bisect leads to the following 
> > > commit:
> > > 
> > > 98ea232cf63961fad734cc8c5e07e8915ec73073 is the first bad commit
> > > commit 98ea232cf63961fad734cc8c5e07e8915ec73073
> > > Author: Neil Horman <nhorman@tuxdriver.com>
> > > Date:   Thu Sep 4 06:13:38 2014 -0400
> > > 
> > >     3c59x: avoid panic in boomerang_start_xmit when finding page address:
> > >     ...
> > > 
> > I'm guessing the above change has uncovered another bug, mostly likely an
> > exhaustion of dma space on your system.  Nothing in the transmit path there does
> > any error checking for successful dma mapping, which it really should.  I'd be
> > willing to be that any dma mapping error leads to a leak in the mapping table.
> > Does your system have an iommu, or does it use swiotlb?  If its the latter, can
> > you increase the swiotlb table space and see if that relieves the problem?  In
> > the interim, I'll start adding some error checking to the transmit path.
> 
> # CONFIG_IOMMU_SUPPORT is not set
> 
> nothing matching iommu or iotlb in dmesg. I thought the system does not 
> have any - K7 CPUs and AMD 760MP chipset with normal AGP gart.
> 
> [    3.763519] agpgart-amdk7 0000:00:00.0: AMD 760MP chipset
> [    3.782995] agpgart-amdk7 0000:00:00.0: AGP aperture is 64M @ 0xf8000000
> 
Then I think you are likely very lmiited in how much DMA memory you can map (may
be limited to ZONE_DMA), which is likely from where this problem is stemming.
Try adding swiotlb= setup to the kernel command line and play with the size to
see if you can avoid the problem.  I also have a patch I'm sending you to test.

Neil

> -- 
> Meelis Roos (mroos@linux.ee)
> --
> 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/
> 

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

* [RFC PATCH] 3c59x: Add dma error checking and recovery
  2014-09-16 10:17 ` Neil Horman
  2014-09-16 10:32   ` Meelis Roos
@ 2014-09-16 14:32   ` Neil Horman
  2014-09-16 20:29   ` bisected regression: 3c59x corrupts packets in 3.17-rc5 David Miller
  2 siblings, 0 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-16 14:32 UTC (permalink / raw)
  To: netdev; +Cc: Meelis Roos, linux-kernel, Neil Horman

Noted that 3c59x has no checks on transmit for failed DMA mappings, and no
ability to unmap fragments when a single map fails in the middle of a transmit.
This patch provides error checking to ensure that dma mappings work properly,
and unrolls an skb mapping if a fragmented skb transmission has a mapping
failure to prevent leaks.

Please test this patch out.  It may fix the problem your experiencing, and, if
you enable dynamic debug in the driver, it will certainly confirm that is the
problem you are experiencing.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
 drivers/net/ethernet/3com/3c59x.c | 50 ++++++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 3fe45c7..5621dab 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -2129,6 +2129,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	int entry = vp->cur_tx % TX_RING_SIZE;
 	struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
 	unsigned long flags;
+	dma_addr_t dma_addr;
 
 	if (vortex_debug > 6) {
 		pr_debug("boomerang_start_xmit()\n");
@@ -2163,24 +2164,48 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
 
 	if (!skb_shinfo(skb)->nr_frags) {
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb->len, PCI_DMA_TODEVICE));
+		dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data, skb->len,
+					  PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+			goto out_dma_err;
+
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr);
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
 	} else {
 		int i;
 
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb_headlen(skb), PCI_DMA_TODEVICE));
+		dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data,
+					  skb_headlen(skb), PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+			goto out_dma_err;
+
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr);
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
+			dma_addr = skb_frag_dma_map(&VORTEX_PCI(vp)->dev, frag,
+						    frag->page_offset,
+						    frag->size,
+						    DMA_TO_DEVICE);
+			if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) {
+				for(i = i-1; i >= 0; i--)
+					dma_unmap_page(&VORTEX_PCI(vp)->dev,
+						       le32_to_cpu(vp->tx_ring[entry].frag[i+1].addr),
+						       le32_to_cpu(vp->tx_ring[entry].frag[i+1].length),
+						       DMA_TO_DEVICE);
+
+				pci_unmap_single(VORTEX_PCI(vp),
+						 le32_to_cpu(vp->tx_ring[entry].frag[0].addr),
+						 le32_to_cpu(vp->tx_ring[entry].frag[0].length),
+						 PCI_DMA_TODEVICE);
+
+				goto out_dma_err;
+			}
+
 			vp->tx_ring[entry].frag[i+1].addr =
-					cpu_to_le32(skb_frag_dma_map(
-						&VORTEX_PCI(vp)->dev,
-						frag,
-						frag->page_offset, frag->size, DMA_TO_DEVICE));
+						cpu_to_le32(dma_addr);
 
 			if (i == skb_shinfo(skb)->nr_frags-1)
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
@@ -2189,7 +2214,10 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 #else
-	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
+	dma_addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
+	if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+		goto out_dma_err;
+	vp->tx_ring[entry].addr = cpu_to_le32(dma_addr);
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 #endif
@@ -2217,7 +2245,11 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_tx_timestamp(skb);
 	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	spin_unlock_irqrestore(&vp->lock, flags);
+out:
 	return NETDEV_TX_OK;
+out_dma_err:
+	dev_err(&VORTEX_PCI(vp)->dev, "Error mapping dma buffer\n");
+	goto out; 
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
-- 
1.9.3


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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-16 10:17 ` Neil Horman
  2014-09-16 10:32   ` Meelis Roos
  2014-09-16 14:32   ` [RFC PATCH] 3c59x: Add dma error checking and recovery Neil Horman
@ 2014-09-16 20:29   ` David Miller
  2014-09-17 10:27     ` Neil Horman
  2 siblings, 1 reply; 14+ messages in thread
From: David Miller @ 2014-09-16 20:29 UTC (permalink / raw)
  To: nhorman; +Cc: mroos, klassert, netdev, linux-kernel

From: Neil Horman <nhorman@tuxdriver.com>
Date: Tue, 16 Sep 2014 06:17:04 -0400

> I'm guessing the above change has uncovered another bug,

Neil, read your patch carefully, I think it added the bug.

The ->page_offset of the frag gets applied two times.

skb_dma_map_frag() already takes frag->page_offset into consideration,
you then pass it in as the 'offset' argument and it then gets added to
itself to compute th final offset.

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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-16 20:29   ` bisected regression: 3c59x corrupts packets in 3.17-rc5 David Miller
@ 2014-09-17 10:27     ` Neil Horman
  2014-09-17 12:43       ` mroos
  0 siblings, 1 reply; 14+ messages in thread
From: Neil Horman @ 2014-09-17 10:27 UTC (permalink / raw)
  To: David Miller; +Cc: mroos, klassert, netdev, linux-kernel

On Tue, Sep 16, 2014 at 04:29:23PM -0400, David Miller wrote:
> From: Neil Horman <nhorman@tuxdriver.com>
> Date: Tue, 16 Sep 2014 06:17:04 -0400
> 
> > I'm guessing the above change has uncovered another bug,
> 
> Neil, read your patch carefully, I think it added the bug.
> 
> The ->page_offset of the frag gets applied two times.
> 
> skb_dma_map_frag() already takes frag->page_offset into consideration,
> you then pass it in as the 'offset' argument and it then gets added to
> itself to compute th final offset.
> 
Shit, you're right, sorry about that.  Its odd, I'm running it here, and its not 
causing problems, but thats obviously wrong.  Meelis, please add the above fix
to your test and confirm that it sovles the problem.  If you could keep the
previous patch in place too that would be great, as we should probably add the
dma error checking anyway.


[PATCH] 3c59x: Fix bad offset spec in skb_frag_dma_map

Recently aded the use of skb_frag_dma_map to 3c59x, but didn't realize it
automatically included the frag_offset internally, as well as provided an option
to specify an extra offset in the parameter list.  We need to specify an offset
of 0 in the parameter list to avoid skb corruption that results in lost
connections.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
 drivers/net/ethernet/3com/3c59x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 5621dab..0f59d68 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -2186,7 +2186,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			dma_addr = skb_frag_dma_map(&VORTEX_PCI(vp)->dev, frag,
-						    frag->page_offset,
+						    0,
 						    frag->size,
 						    DMA_TO_DEVICE);
 			if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) {
-- 
1.9.3


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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-17 10:27     ` Neil Horman
@ 2014-09-17 12:43       ` mroos
  2014-09-17 12:56         ` Neil Horman
  0 siblings, 1 reply; 14+ messages in thread
From: mroos @ 2014-09-17 12:43 UTC (permalink / raw)
  To: Neil Horman; +Cc: David Miller, steffen, netdev, Linux Kernel list

> Shit, you're right, sorry about that.  Its odd, I'm running it here, and its not 
> causing problems, but thats obviously wrong.  Meelis, please add the above fix
> to your test and confirm that it sovles the problem.  If you could keep the
> previous patch in place too that would be great, as we should probably add the
> dma error checking anyway.
> 
> 
> [PATCH] 3c59x: Fix bad offset spec in skb_frag_dma_map

Tested 2 variants: only this patch (backported to old state) and both 
patches together.

Both work fine.

-- 
Meelis Roos (mroos@linux.ee)

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

* Re: bisected regression: 3c59x corrupts packets in 3.17-rc5
  2014-09-17 12:43       ` mroos
@ 2014-09-17 12:56         ` Neil Horman
  0 siblings, 0 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-17 12:56 UTC (permalink / raw)
  To: mroos; +Cc: David Miller, steffen, netdev, Linux Kernel list

On Wed, Sep 17, 2014 at 03:43:54PM +0300, mroos@linux.ee wrote:
> > Shit, you're right, sorry about that.  Its odd, I'm running it here, and its not 
> > causing problems, but thats obviously wrong.  Meelis, please add the above fix
> > to your test and confirm that it sovles the problem.  If you could keep the
> > previous patch in place too that would be great, as we should probably add the
> > dma error checking anyway.
> > 
> > 
> > [PATCH] 3c59x: Fix bad offset spec in skb_frag_dma_map
> 
> Tested 2 variants: only this patch (backported to old state) and both 
> patches together.
> 
> Both work fine.
> 
Thank you, Meelis.  Dave, I'll propose these patches officially in just a bit

sorry for the 
> -- 
> Meelis Roos (mroos@linux.ee)
> 

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

* [PATCH 1/2] 3c59x: Add dma error checking and recovery
  2014-09-15 23:14 bisected regression: 3c59x corrupts packets in 3.17-rc5 Meelis Roos
  2014-09-16 10:17 ` Neil Horman
@ 2014-09-17 13:04 ` Neil Horman
  2014-09-17 13:04   ` [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map Neil Horman
  2014-09-19 20:29   ` [PATCH 1/2] 3c59x: Add dma error checking and recovery David Miller
  1 sibling, 2 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-17 13:04 UTC (permalink / raw)
  To: netdev; +Cc: Neil Horman, Linux Kernel list, David S. Miller, Meelis Roos

Noted that 3c59x has no checks on transmit for failed DMA mappings, and no
ability to unmap fragments when a single map fails in the middle of a transmit.
This patch provides error checking to ensure that dma mappings work properly,
and unrolls an skb mapping if a fragmented skb transmission has a mapping
failure to prevent leaks.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Linux Kernel list <linux-kernel@vger.kernel.org>
CC: "David S. Miller" <davem@davemloft.net>
CC: Meelis Roos <mroos@linux.ee>
Tested-by: Meelis Roos <mroos@linux.ee>
---
 drivers/net/ethernet/3com/3c59x.c | 50 ++++++++++++++++++++++++++++++++-------
 1 file changed, 41 insertions(+), 9 deletions(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 3fe45c7..5621dab 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -2129,6 +2129,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	int entry = vp->cur_tx % TX_RING_SIZE;
 	struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
 	unsigned long flags;
+	dma_addr_t dma_addr;
 
 	if (vortex_debug > 6) {
 		pr_debug("boomerang_start_xmit()\n");
@@ -2163,24 +2164,48 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded | AddTCPChksum | AddUDPChksum);
 
 	if (!skb_shinfo(skb)->nr_frags) {
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb->len, PCI_DMA_TODEVICE));
+		dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data, skb->len,
+					  PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+			goto out_dma_err;
+
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr);
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb->len | LAST_FRAG);
 	} else {
 		int i;
 
-		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data,
-										skb_headlen(skb), PCI_DMA_TODEVICE));
+		dma_addr = pci_map_single(VORTEX_PCI(vp), skb->data,
+					  skb_headlen(skb), PCI_DMA_TODEVICE);
+		if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+			goto out_dma_err;
+
+		vp->tx_ring[entry].frag[0].addr = cpu_to_le32(dma_addr);
 		vp->tx_ring[entry].frag[0].length = cpu_to_le32(skb_headlen(skb));
 
 		for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
+			dma_addr = skb_frag_dma_map(&VORTEX_PCI(vp)->dev, frag,
+						    frag->page_offset,
+						    frag->size,
+						    DMA_TO_DEVICE);
+			if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) {
+				for(i = i-1; i >= 0; i--)
+					dma_unmap_page(&VORTEX_PCI(vp)->dev,
+						       le32_to_cpu(vp->tx_ring[entry].frag[i+1].addr),
+						       le32_to_cpu(vp->tx_ring[entry].frag[i+1].length),
+						       DMA_TO_DEVICE);
+
+				pci_unmap_single(VORTEX_PCI(vp),
+						 le32_to_cpu(vp->tx_ring[entry].frag[0].addr),
+						 le32_to_cpu(vp->tx_ring[entry].frag[0].length),
+						 PCI_DMA_TODEVICE);
+
+				goto out_dma_err;
+			}
+
 			vp->tx_ring[entry].frag[i+1].addr =
-					cpu_to_le32(skb_frag_dma_map(
-						&VORTEX_PCI(vp)->dev,
-						frag,
-						frag->page_offset, frag->size, DMA_TO_DEVICE));
+						cpu_to_le32(dma_addr);
 
 			if (i == skb_shinfo(skb)->nr_frags-1)
 					vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
@@ -2189,7 +2214,10 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 		}
 	}
 #else
-	vp->tx_ring[entry].addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
+	dma_addr = cpu_to_le32(pci_map_single(VORTEX_PCI(vp), skb->data, skb->len, PCI_DMA_TODEVICE));
+	if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr))
+		goto out_dma_err;
+	vp->tx_ring[entry].addr = cpu_to_le32(dma_addr);
 	vp->tx_ring[entry].length = cpu_to_le32(skb->len | LAST_FRAG);
 	vp->tx_ring[entry].status = cpu_to_le32(skb->len | TxIntrUploaded);
 #endif
@@ -2217,7 +2245,11 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	skb_tx_timestamp(skb);
 	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	spin_unlock_irqrestore(&vp->lock, flags);
+out:
 	return NETDEV_TX_OK;
+out_dma_err:
+	dev_err(&VORTEX_PCI(vp)->dev, "Error mapping dma buffer\n");
+	goto out; 
 }
 
 /* The interrupt handler does all of the Rx thread work and cleans up
-- 
1.9.3


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

* [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map
  2014-09-17 13:04 ` [PATCH 1/2] 3c59x: Add dma error checking and recovery Neil Horman
@ 2014-09-17 13:04   ` Neil Horman
  2014-09-19 20:29     ` David Miller
  2014-09-19 20:29   ` [PATCH 1/2] 3c59x: Add dma error checking and recovery David Miller
  1 sibling, 1 reply; 14+ messages in thread
From: Neil Horman @ 2014-09-17 13:04 UTC (permalink / raw)
  To: netdev; +Cc: Neil Horman, Linux Kernel list, David S. Miller, Meelis Roos

Recently aded the use of skb_frag_dma_map to 3c59x, but didn't realize it
automatically included the frag_offset internally, as well as provided an option
to specify an extra offset in the parameter list.  We need to specify an offset
of 0 in the parameter list to avoid skb corruption that results in lost
connections.

Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Linux Kernel list <linux-kernel@vger.kernel.org>
CC: "David S. Miller" <davem@davemloft.net>
CC: Meelis Roos <mroos@linux.ee>
Tested-by: Meelis Roos <mroos@linux.ee>
---
 drivers/net/ethernet/3com/3c59x.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
index 5621dab..0f59d68 100644
--- a/drivers/net/ethernet/3com/3c59x.c
+++ b/drivers/net/ethernet/3com/3c59x.c
@@ -2186,7 +2186,7 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 			skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
 			dma_addr = skb_frag_dma_map(&VORTEX_PCI(vp)->dev, frag,
-						    frag->page_offset,
+						    0,
 						    frag->size,
 						    DMA_TO_DEVICE);
 			if (dma_mapping_error(&VORTEX_PCI(vp)->dev, dma_addr)) {
-- 
1.9.3


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

* Re: [PATCH 1/2] 3c59x: Add dma error checking and recovery
  2014-09-17 13:04 ` [PATCH 1/2] 3c59x: Add dma error checking and recovery Neil Horman
  2014-09-17 13:04   ` [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map Neil Horman
@ 2014-09-19 20:29   ` David Miller
  2014-09-20  1:19     ` Neil Horman
  1 sibling, 1 reply; 14+ messages in thread
From: David Miller @ 2014-09-19 20:29 UTC (permalink / raw)
  To: nhorman; +Cc: netdev, linux-kernel, mroos

From: Neil Horman <nhorman@tuxdriver.com>
Date: Wed, 17 Sep 2014 09:04:44 -0400

> Noted that 3c59x has no checks on transmit for failed DMA mappings, and no
> ability to unmap fragments when a single map fails in the middle of a transmit.
> This patch provides error checking to ensure that dma mappings work properly,
> and unrolls an skb mapping if a fragmented skb transmission has a mapping
> failure to prevent leaks.
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Linux Kernel list <linux-kernel@vger.kernel.org>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Meelis Roos <mroos@linux.ee>
> Tested-by: Meelis Roos <mroos@linux.ee>

Applied.

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

* Re: [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map
  2014-09-17 13:04   ` [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map Neil Horman
@ 2014-09-19 20:29     ` David Miller
  0 siblings, 0 replies; 14+ messages in thread
From: David Miller @ 2014-09-19 20:29 UTC (permalink / raw)
  To: nhorman; +Cc: netdev, linux-kernel, mroos

From: Neil Horman <nhorman@tuxdriver.com>
Date: Wed, 17 Sep 2014 09:04:45 -0400

> Recently aded the use of skb_frag_dma_map to 3c59x, but didn't realize it
> automatically included the frag_offset internally, as well as provided an option
> to specify an extra offset in the parameter list.  We need to specify an offset
> of 0 in the parameter list to avoid skb corruption that results in lost
> connections.
> 
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Linux Kernel list <linux-kernel@vger.kernel.org>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Meelis Roos <mroos@linux.ee>
> Tested-by: Meelis Roos <mroos@linux.ee>

Applied.

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

* Re: [PATCH 1/2] 3c59x: Add dma error checking and recovery
  2014-09-19 20:29   ` [PATCH 1/2] 3c59x: Add dma error checking and recovery David Miller
@ 2014-09-20  1:19     ` Neil Horman
  0 siblings, 0 replies; 14+ messages in thread
From: Neil Horman @ 2014-09-20  1:19 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-kernel, mroos

On Fri, Sep 19, 2014 at 04:29:19PM -0400, David Miller wrote:
> From: Neil Horman <nhorman@tuxdriver.com>
> Date: Wed, 17 Sep 2014 09:04:44 -0400
> 
> > Noted that 3c59x has no checks on transmit for failed DMA mappings, and no
> > ability to unmap fragments when a single map fails in the middle of a transmit.
> > This patch provides error checking to ensure that dma mappings work properly,
> > and unrolls an skb mapping if a fragmented skb transmission has a mapping
> > failure to prevent leaks.
> > 
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: Linux Kernel list <linux-kernel@vger.kernel.org>
> > CC: "David S. Miller" <davem@davemloft.net>
> > CC: Meelis Roos <mroos@linux.ee>
> > Tested-by: Meelis Roos <mroos@linux.ee>
> 
> Applied.
> 
Thanks Dave!
Neil


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

end of thread, other threads:[~2014-09-20  1:19 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-09-15 23:14 bisected regression: 3c59x corrupts packets in 3.17-rc5 Meelis Roos
2014-09-16 10:17 ` Neil Horman
2014-09-16 10:32   ` Meelis Roos
2014-09-16 14:31     ` Neil Horman
2014-09-16 14:32   ` [RFC PATCH] 3c59x: Add dma error checking and recovery Neil Horman
2014-09-16 20:29   ` bisected regression: 3c59x corrupts packets in 3.17-rc5 David Miller
2014-09-17 10:27     ` Neil Horman
2014-09-17 12:43       ` mroos
2014-09-17 12:56         ` Neil Horman
2014-09-17 13:04 ` [PATCH 1/2] 3c59x: Add dma error checking and recovery Neil Horman
2014-09-17 13:04   ` [PATCH 2/2] 3c59x: Fix bad offset spec in skb_frag_dma_map Neil Horman
2014-09-19 20:29     ` David Miller
2014-09-19 20:29   ` [PATCH 1/2] 3c59x: Add dma error checking and recovery David Miller
2014-09-20  1:19     ` Neil Horman

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).