[kernel/f14/master] Improved version of the VIA Velocity DMA unmapping fix.

Dave Jones davej at fedoraproject.org
Wed Sep 1 20:46:00 UTC 2010


commit c348adbe3998b31c8bc9a0288ef184f799be5bc4
Author: Dave Jones <davej at redhat.com>
Date:   Wed Sep 1 16:45:48 2010 -0400

    Improved version of the VIA Velocity DMA unmapping fix.

 kernel.spec                          |    5 +-
 linux-2.6-via-velocity-dma-fix.patch |  137 +++++++++++++++++++++++++++++-----
 2 files changed, 123 insertions(+), 19 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 77630ec..d1a81f1 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -48,7 +48,7 @@ Summary: The Linux kernel
 # reset this by hand to 1 (or to 0 and then use rpmdev-bumpspec).
 # scripts/rebase.sh should be made to do that for you, actually.
 #
-%global baserelease 14
+%global baserelease 15
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -1896,6 +1896,9 @@ fi
 # and build.
 
 %changelog
+* Wed Sep 01 2010 Dave Jones <davej at redhat.com> 2.6.35.4-15
+- Improved version of the VIA Velocity DMA fix.
+
 * Tue Aug 31 2010 Kyle McMartin <kyle at redhat.com> 2.6.35.4-14
 - efifb-add-more-models.patch: Add patch from Luke Macken to
   support more Mac models (rhbz#528232)
diff --git a/linux-2.6-via-velocity-dma-fix.patch b/linux-2.6-via-velocity-dma-fix.patch
index 9e945d5..3708484 100644
--- a/linux-2.6-via-velocity-dma-fix.patch
+++ b/linux-2.6-via-velocity-dma-fix.patch
@@ -1,20 +1,121 @@
-From: Simon Kagstrom <simon.kagstrom at netinsight.net>
-Date: Tue, 31 Aug 2010 08:41:26 +0200
-Subject: [PATCH] via-velocity: Correct packet length on tx free
-
-Signed-off-by: Simon Kagstrom <simon.kagstrom at netinsight.net>
----
- drivers/net/via-velocity.c |    2 +-
- 1 files changed, 1 insertions(+), 1 deletions(-)
-
---- linux-2.6.35.x86_64/drivers/net/via-velocity.c~	2010-08-31 11:40:51.000000000 -0400
-+++ linux-2.6.35.x86_64/drivers/net/via-velocity.c	2010-08-31 11:40:58.000000000 -0400
-@@ -1721,7 +1721,7 @@ static void velocity_free_tx_buf(struct 
- 			/* For scatter-gather */
- 			if (skb_shinfo(skb)->nr_frags > 0)
- 				pktlen = max_t(size_t, pktlen,
+Date: Wed, 01 Sep 2010 13:37:33 -0700 (PDT)
+Message-Id: <20100901.133733.223467599.davem at davemloft.net>
+To: davej at redhat.com
+Cc: simon.kagstrom at netinsight.net, netdev at vger.kernel.org
+Subject: Re: via-velocity dma-debug warnings again. (2.6.35.2)
+From: David Miller <davem at davemloft.net>
+In-Reply-To: <20100901.133547.236248297.davem at davemloft.net>
+References: <20100901200555.GA30689 at redhat.com>
+	<20100901.133414.24593005.davem at davemloft.net>
+	<20100901.133547.236248297.davem at davemloft.net>
+
+New patch:
+
+via-velocity: Fix TX buffer unmapping.
+
+Fix several bugs in TX buffer DMA unmapping:
+
+1) Use pci_unmap_page() as appropriate.
+
+2) Don't try to fetch the length from the DMA descriptor,
+   the chip and modify that value.  Use the correct lengths,
+   calculated the same way as is done at map time.
+
+3) Kill meaningless NULL checks (against embedded sized
+   arrays which can never be NULL, and against the address
+   of the non-zero indexed entry of an array).
+
+4) max() on ETH_ZLEN is not necessary and just adds
+   confusion, since the xmit function does a proper
+   skb_padto() very early on.
+
+Reported-by: Dave Jones <davej at redhat.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+
+diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
+index fd69095..4167e1f 100644
+--- a/drivers/net/via-velocity.c
++++ b/drivers/net/via-velocity.c
+@@ -1705,28 +1705,21 @@ err_free_dma_rings_0:
+  *	recycle it, if not then unmap the buffer.
+  */
+ static void velocity_free_tx_buf(struct velocity_info *vptr,
+-		struct velocity_td_info *tdinfo, struct tx_desc *td)
++		struct velocity_td_info *tdinfo)
+ {
+ 	struct sk_buff *skb = tdinfo->skb;
++	int i;
+ 
+-	/*
+-	 *	Don't unmap the pre-allocated tx_bufs
+-	 */
+-	if (tdinfo->skb_dma) {
+-		int i;
+-
+-		for (i = 0; i < tdinfo->nskb_dma; i++) {
+-			size_t pktlen = max_t(size_t, skb->len, ETH_ZLEN);
++	pci_unmap_single(vptr->pdev, tdinfo->skb_dma[0],
++			 skb_headlen(skb), PCI_DMA_TODEVICE);
+ 
+-			/* For scatter-gather */
+-			if (skb_shinfo(skb)->nr_frags > 0)
+-				pktlen = max_t(size_t, pktlen,
 -						td->td_buf[i].size & ~TD_QUEUE);
-+						skb_headlen(skb));
++	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
++		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+ 
+-			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
+-					le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
+-		}
++		pci_unmap_page(vptr->pdev, tdinfo->skb_dma[i + 1],
++			       frag->size, PCI_DMA_TODEVICE);
+ 	}
++
+ 	dev_kfree_skb_irq(skb);
+ 	tdinfo->skb = NULL;
+ }
+@@ -1739,22 +1732,8 @@ static void velocity_free_td_ring_entry(struct velocity_info *vptr,
+ 							 int q, int n)
+ {
+ 	struct velocity_td_info *td_info = &(vptr->tx.infos[q][n]);
+-	int i;
+-
+-	if (td_info == NULL)
+-		return;
+ 
+-	if (td_info->skb) {
+-		for (i = 0; i < td_info->nskb_dma; i++) {
+-			if (td_info->skb_dma[i]) {
+-				pci_unmap_single(vptr->pdev, td_info->skb_dma[i],
+-					td_info->skb->len, PCI_DMA_TODEVICE);
+-				td_info->skb_dma[i] = 0;
+-			}
+-		}
+-		dev_kfree_skb(td_info->skb);
+-		td_info->skb = NULL;
+-	}
++	velocity_free_tx_buf(vptr, td_info);
+ }
  
- 			pci_unmap_single(vptr->pdev, tdinfo->skb_dma[i],
- 					le16_to_cpu(pktlen), PCI_DMA_TODEVICE);
+ /**
+@@ -1925,7 +1904,7 @@ static int velocity_tx_srv(struct velocity_info *vptr)
+ 				stats->tx_packets++;
+ 				stats->tx_bytes += tdinfo->skb->len;
+ 			}
+-			velocity_free_tx_buf(vptr, tdinfo, td);
++			velocity_free_tx_buf(vptr, tdinfo);
+ 			vptr->tx.used[qnum]--;
+ 		}
+ 		vptr->tx.tail[qnum] = idx;
+@@ -2534,9 +2513,7 @@ static netdev_tx_t velocity_xmit(struct sk_buff *skb,
+ 		return NETDEV_TX_OK;
+ 	}
+ 
+-	pktlen = skb_shinfo(skb)->nr_frags == 0 ?
+-			max_t(unsigned int, skb->len, ETH_ZLEN) :
+-				skb_headlen(skb);
++	pktlen = skb_headlen(skb);
+ 
+ 	spin_lock_irqsave(&vptr->lock, flags);
+ 
+


More information about the scm-commits mailing list