From dec6453797550afa086617e27ea77ffd6b196d99 Mon Sep 17 00:00:00 2001
From: Jeff Becker <Jeffrey.C.Becker@nasa.gov>
Date: Tue, 6 Sep 2011 09:43:38 -0700
Subject: [PATCH 1/2] Remove carriage returns from DOS formatted patches so they can apply
 Signed-off-by: Jeff Becker <Jeffrey.C.Becker@nasa.gov>

---
 .../backport/2.6.32/mlx4_semaphore_include.patch   |   28 +-
 .../backport/2.6.32/net_skb-dst_accessors.patch    |  298 ++++++++++----------
 .../backport/2.6.32/new_frags_interface.patch      |  262 +++++++++---------
 3 files changed, 294 insertions(+), 294 deletions(-)

diff --git a/kernel_patches/backport/2.6.32/mlx4_semaphore_include.patch b/kernel_patches/backport/2.6.32/mlx4_semaphore_include.patch
index f2141f1..011d364 100644
--- a/kernel_patches/backport/2.6.32/mlx4_semaphore_include.patch
+++ b/kernel_patches/backport/2.6.32/mlx4_semaphore_include.patch
@@ -1,14 +1,14 @@
-From: Sven-Thorsten Dietrich <sdietrich@suse.de>
-Subject: Include semaphore.h explicitly.
-
-Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
---- a/drivers/net/mlx4/cmd.c	2012-09-01 10:14:58.000000000 -0700
-+++ b/drivers/net/mlx4//cmd.c	2012-09-01 13:19:46.000000000 -0700
-@@ -35,6 +35,7 @@
- #include <linux/sched.h>
- #include <linux/pci.h>
- #include <linux/errno.h>
-+#include <linux/semaphore.h>
- 
- #include <linux/mlx4/cmd.h>
- 
+From: Sven-Thorsten Dietrich <sdietrich@suse.de>
+Subject: Include semaphore.h explicitly.
+
+Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
+--- a/drivers/net/mlx4/cmd.c	2012-09-01 10:14:58.000000000 -0700
++++ b/drivers/net/mlx4//cmd.c	2012-09-01 13:19:46.000000000 -0700
+@@ -35,6 +35,7 @@
+ #include <linux/sched.h>
+ #include <linux/pci.h>
+ #include <linux/errno.h>
++#include <linux/semaphore.h>
+ 
+ #include <linux/mlx4/cmd.h>
+ 
diff --git a/kernel_patches/backport/2.6.32/net_skb-dst_accessors.patch b/kernel_patches/backport/2.6.32/net_skb-dst_accessors.patch
index 36d612b..c742dad 100644
--- a/kernel_patches/backport/2.6.32/net_skb-dst_accessors.patch
+++ b/kernel_patches/backport/2.6.32/net_skb-dst_accessors.patch
@@ -1,149 +1,149 @@
-From: Sven-Thorsten Dietrich <sdietrich@suse.de>
-Subject: Forward-port new accessor for net: dst.
-
-See Kernel.org:
-commit adf30907d63893e4208dfe3f5c88ae12bc2f25d5
-Author: Eric Dumazet <eric.dumazet@gmail.com>
-Date:   Tue Jun 2 05:19:30 2009 +0000
-Subject: net: skb->dst accessors
-
-Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
---- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
-@@ -1394,8 +1394,8 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
- 	struct ipoib_dev_priv *priv = netdev_priv(dev);
- 	int e = skb_queue_empty(&priv->cm.skb_queue);
- 
--	if (skb->dst)
--		skb->dst->ops->update_pmtu(skb->dst, mtu);
-+	if (skb_dst(skb))
-+		skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
- 
- 	skb_queue_tail(&priv->cm.skb_queue, skb);
- 	if (e)
---- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
-@@ -561,7 +561,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
- 	struct ipoib_neigh *neigh;
- 	unsigned long flags;
- 
--	neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
-+	neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev);
- 	if (!neigh) {
- 		++dev->stats.tx_dropped;
- 		dev_kfree_skb_any(skb);
-@@ -570,9 +570,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
- 
- 	spin_lock_irqsave(&priv->lock, flags);
- 
--	path = __path_find(dev, skb->dst->neighbour->ha + 4);
-+	path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4);
- 	if (!path) {
--		path = path_rec_create(dev, skb->dst->neighbour->ha + 4);
-+		path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4);
- 		if (!path)
- 			goto err_path;
- 
-@@ -605,7 +605,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
- 				goto err_drop;
- 			}
- 		} else
--			ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha));
-+			ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
- 	} else {
- 		neigh->ah  = NULL;
- 
-@@ -635,15 +635,15 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
- 	struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
- 
- 	/* Look up path record for unicasts */
--	if (skb->dst->neighbour->ha[4] != 0xff) {
-+	if (skb_dst(skb)->neighbour->ha[4] != 0xff) {
- 		neigh_add_path(skb, dev);
- 		return;
- 	}
- 
- 	/* Add in the P_Key for multicasts */
--	skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
--	skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
--	ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb);
-+	skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
-+	skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff;
-+	ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb);
- }
- 
- static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
-@@ -708,16 +708,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 	struct ipoib_neigh *neigh;
- 	unsigned long flags;
- 
--	if (likely(skb->dst && skb->dst->neighbour)) {
--		if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
-+	if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) {
-+		if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) {
- 			ipoib_path_lookup(skb, dev);
- 			return NETDEV_TX_OK;
- 		}
- 
--		neigh = *to_ipoib_neigh(skb->dst->neighbour);
-+		neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour);
- 
- 		if (unlikely((memcmp(&neigh->dgid.raw,
--				     skb->dst->neighbour->ha + 4,
-+				     skb_dst(skb)->neighbour->ha + 4,
- 				     sizeof(union ib_gid))) ||
- 			     (neigh->dev != dev))) {
- 			spin_lock_irqsave(&priv->lock, flags);
-@@ -743,7 +743,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 				return NETDEV_TX_OK;
- 			}
- 		} else if (neigh->ah) {
--			ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
-+			ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
- 			return NETDEV_TX_OK;
- 		}
- 
-@@ -772,7 +772,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
- 			if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
- 			    (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
- 				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
--					   skb->dst ? "neigh" : "dst",
-+					   skb_dst(skb) ? "neigh" : "dst",
- 					   be16_to_cpup((__be16 *) skb->data),
- 					   IPOIB_QPN(phdr->hwaddr),
- 					   phdr->hwaddr + 4);
-@@ -817,7 +817,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
- 	 * destination address onto the front of the skb so we can
- 	 * figure out where to send the packet later.
- 	 */
--	if ((!skb->dst || !skb->dst->neighbour) && daddr) {
-+	if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) {
- 		struct ipoib_pseudoheader *phdr =
- 			(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
- 		memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
---- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
-@@ -261,7 +261,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
- 
- 		skb->dev = dev;
- 
--		if (!skb->dst || !skb->dst->neighbour) {
-+		if (!skb_dst(skb) || !skb_dst(skb)->neighbour) {
- 			/* put pseudoheader back on for next time */
- 			skb_push(skb, sizeof (struct ipoib_pseudoheader));
- 		}
-@@ -707,10 +707,10 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
- 
- out:
- 	if (mcast && mcast->ah) {
--		if (skb->dst		&&
--		    skb->dst->neighbour &&
--		    !*to_ipoib_neigh(skb->dst->neighbour)) {
--			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
-+		if (skb_dst(skb)		&&
-+		    skb_dst(skb)->neighbour &&
-+		    !*to_ipoib_neigh(skb_dst(skb)->neighbour)) {
-+			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour,
- 									skb->dev);
- 
- 			if (neigh) {
+From: Sven-Thorsten Dietrich <sdietrich@suse.de>
+Subject: Forward-port new accessor for net: dst.
+
+See Kernel.org:
+commit adf30907d63893e4208dfe3f5c88ae12bc2f25d5
+Author: Eric Dumazet <eric.dumazet@gmail.com>
+Date:   Tue Jun 2 05:19:30 2009 +0000
+Subject: net: skb->dst accessors
+
+Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
+--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+@@ -1394,8 +1394,8 @@ void ipoib_cm_skb_too_long(struct net_device *dev, struct sk_buff *skb,
+ 	struct ipoib_dev_priv *priv = netdev_priv(dev);
+ 	int e = skb_queue_empty(&priv->cm.skb_queue);
+ 
+-	if (skb->dst)
+-		skb->dst->ops->update_pmtu(skb->dst, mtu);
++	if (skb_dst(skb))
++		skb_dst(skb)->ops->update_pmtu(skb_dst(skb), mtu);
+ 
+ 	skb_queue_tail(&priv->cm.skb_queue, skb);
+ 	if (e)
+--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
+@@ -561,7 +561,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+ 	struct ipoib_neigh *neigh;
+ 	unsigned long flags;
+ 
+-	neigh = ipoib_neigh_alloc(skb->dst->neighbour, skb->dev);
++	neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour, skb->dev);
+ 	if (!neigh) {
+ 		++dev->stats.tx_dropped;
+ 		dev_kfree_skb_any(skb);
+@@ -570,9 +570,9 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+ 
+ 	spin_lock_irqsave(&priv->lock, flags);
+ 
+-	path = __path_find(dev, skb->dst->neighbour->ha + 4);
++	path = __path_find(dev, skb_dst(skb)->neighbour->ha + 4);
+ 	if (!path) {
+-		path = path_rec_create(dev, skb->dst->neighbour->ha + 4);
++		path = path_rec_create(dev, skb_dst(skb)->neighbour->ha + 4);
+ 		if (!path)
+ 			goto err_path;
+ 
+@@ -605,7 +605,7 @@ static void neigh_add_path(struct sk_buff *skb, struct net_device *dev)
+ 				goto err_drop;
+ 			}
+ 		} else
+-			ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb->dst->neighbour->ha));
++			ipoib_send(dev, skb, path->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
+ 	} else {
+ 		neigh->ah  = NULL;
+ 
+@@ -635,15 +635,15 @@ static void ipoib_path_lookup(struct sk_buff *skb, struct net_device *dev)
+ 	struct ipoib_dev_priv *priv = netdev_priv(skb->dev);
+ 
+ 	/* Look up path record for unicasts */
+-	if (skb->dst->neighbour->ha[4] != 0xff) {
++	if (skb_dst(skb)->neighbour->ha[4] != 0xff) {
+ 		neigh_add_path(skb, dev);
+ 		return;
+ 	}
+ 
+ 	/* Add in the P_Key for multicasts */
+-	skb->dst->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
+-	skb->dst->neighbour->ha[9] = priv->pkey & 0xff;
+-	ipoib_mcast_send(dev, skb->dst->neighbour->ha + 4, skb);
++	skb_dst(skb)->neighbour->ha[8] = (priv->pkey >> 8) & 0xff;
++	skb_dst(skb)->neighbour->ha[9] = priv->pkey & 0xff;
++	ipoib_mcast_send(dev, skb_dst(skb)->neighbour->ha + 4, skb);
+ }
+ 
+ static void unicast_arp_send(struct sk_buff *skb, struct net_device *dev,
+@@ -708,16 +708,16 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	struct ipoib_neigh *neigh;
+ 	unsigned long flags;
+ 
+-	if (likely(skb->dst && skb->dst->neighbour)) {
+-		if (unlikely(!*to_ipoib_neigh(skb->dst->neighbour))) {
++	if (likely(skb_dst(skb) && skb_dst(skb)->neighbour)) {
++		if (unlikely(!*to_ipoib_neigh(skb_dst(skb)->neighbour))) {
+ 			ipoib_path_lookup(skb, dev);
+ 			return NETDEV_TX_OK;
+ 		}
+ 
+-		neigh = *to_ipoib_neigh(skb->dst->neighbour);
++		neigh = *to_ipoib_neigh(skb_dst(skb)->neighbour);
+ 
+ 		if (unlikely((memcmp(&neigh->dgid.raw,
+-				     skb->dst->neighbour->ha + 4,
++				     skb_dst(skb)->neighbour->ha + 4,
+ 				     sizeof(union ib_gid))) ||
+ 			     (neigh->dev != dev))) {
+ 			spin_lock_irqsave(&priv->lock, flags);
+@@ -743,7 +743,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 				return NETDEV_TX_OK;
+ 			}
+ 		} else if (neigh->ah) {
+-			ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb->dst->neighbour->ha));
++			ipoib_send(dev, skb, neigh->ah, IPOIB_QPN(skb_dst(skb)->neighbour->ha));
+ 			return NETDEV_TX_OK;
+ 		}
+ 
+@@ -772,7 +772,7 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 			if ((be16_to_cpup((__be16 *) skb->data) != ETH_P_ARP) &&
+ 			    (be16_to_cpup((__be16 *) skb->data) != ETH_P_RARP)) {
+ 				ipoib_warn(priv, "Unicast, no %s: type %04x, QPN %06x %pI6\n",
+-					   skb->dst ? "neigh" : "dst",
++					   skb_dst(skb) ? "neigh" : "dst",
+ 					   be16_to_cpup((__be16 *) skb->data),
+ 					   IPOIB_QPN(phdr->hwaddr),
+ 					   phdr->hwaddr + 4);
+@@ -817,7 +817,7 @@ static int ipoib_hard_header(struct sk_buff *skb,
+ 	 * destination address onto the front of the skb so we can
+ 	 * figure out where to send the packet later.
+ 	 */
+-	if ((!skb->dst || !skb->dst->neighbour) && daddr) {
++	if ((!skb_dst(skb) || !skb_dst(skb)->neighbour) && daddr) {
+ 		struct ipoib_pseudoheader *phdr =
+ 			(struct ipoib_pseudoheader *) skb_push(skb, sizeof *phdr);
+ 		memcpy(phdr->hwaddr, daddr, INFINIBAND_ALEN);
+--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
++++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+@@ -261,7 +261,7 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
+ 
+ 		skb->dev = dev;
+ 
+-		if (!skb->dst || !skb->dst->neighbour) {
++		if (!skb_dst(skb) || !skb_dst(skb)->neighbour) {
+ 			/* put pseudoheader back on for next time */
+ 			skb_push(skb, sizeof (struct ipoib_pseudoheader));
+ 		}
+@@ -707,10 +707,10 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
+ 
+ out:
+ 	if (mcast && mcast->ah) {
+-		if (skb->dst		&&
+-		    skb->dst->neighbour &&
+-		    !*to_ipoib_neigh(skb->dst->neighbour)) {
+-			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb->dst->neighbour,
++		if (skb_dst(skb)		&&
++		    skb_dst(skb)->neighbour &&
++		    !*to_ipoib_neigh(skb_dst(skb)->neighbour)) {
++			struct ipoib_neigh *neigh = ipoib_neigh_alloc(skb_dst(skb)->neighbour,
+ 									skb->dev);
+ 
+ 			if (neigh) {
diff --git a/kernel_patches/backport/2.6.32/new_frags_interface.patch b/kernel_patches/backport/2.6.32/new_frags_interface.patch
index b1ad068..7025736 100644
--- a/kernel_patches/backport/2.6.32/new_frags_interface.patch
+++ b/kernel_patches/backport/2.6.32/new_frags_interface.patch
@@ -1,131 +1,131 @@
-From: Sven-Thorsten Dietrich <sdietrich@suse.de>
-
-See Kernel.org:
-commit 76620aafd66f0004829764940c5466144969cffc
-Author: Herbert Xu <herbert@gondor.apana.org.au>
-Date:   Thu Apr 16 02:02:07 2009 -0700
-Subject: gro: New frags interface to avoid copying shinfo
-
-
-Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
---- a/drivers/net/cxgb3/adapter.h
-+++ b/drivers/net/cxgb3/adapter.h
-@@ -195,7 +195,7 @@ struct sge_qset {		/* an SGE queue set */
- 	struct sge_rspq rspq;
- 	struct sge_fl fl[SGE_RXQ_PER_SET];
- 	struct sge_txq txq[SGE_TXQ_PER_SET];
--	struct napi_gro_fraginfo lro_frag_tbl;
-+	int nomem;
- 	int lro_enabled;
- 	void *lro_va;
- 	struct net_device *netdev;
---- a/drivers/net/cxgb3/sge.c
-+++ b/drivers/net/cxgb3/sge.c
-@@ -654,7 +654,8 @@ static void t3_reset_qset(struct sge_qset *q)
- 	q->txq_stopped = 0;
- 	q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
- 	q->rx_reclaim_timer.function = NULL;
--	q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
-+	q->nomem = 0;
-+	napi_free_frags(&q->napi);
- }
- 
- 
-@@ -2074,20 +2075,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
- 			 struct sge_fl *fl, int len, int complete)
- {
- 	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
-+	struct sk_buff *skb = NULL;
- 	struct cpl_rx_pkt *cpl;
--	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
--	int nr_frags = qs->lro_frag_tbl.nr_frags;
--	int frag_len = qs->lro_frag_tbl.len;
-+	struct skb_frag_struct *rx_frag;
-+	int nr_frags;
- 	int offset = 0;
- 
--	if (!nr_frags) {
--		offset = 2 + sizeof(struct cpl_rx_pkt);
--		qs->lro_va = cpl = sd->pg_chunk.va + 2;
-+	if (!qs->nomem) {
-+		skb = napi_get_frags(&qs->napi);
-+		qs->nomem = !skb;
- 	}
- 
- 	fl->credits--;
- 
--	len -= offset;
- 	pci_dma_sync_single_for_cpu(adap->pdev,
- 				    pci_unmap_addr(sd, dma_addr),
- 				    fl->buf_size - SGE_PG_RSVD,
-@@ -2100,21 +2100,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
- 			       fl->alloc_size,
- 			       PCI_DMA_FROMDEVICE);
- 
-+	if (!skb) {
-+		put_page(sd->pg_chunk.page);
-+		if (complete)
-+			qs->nomem = 0;
-+		return;
-+	}
-+
-+	rx_frag = skb_shinfo(skb)->frags;
-+	nr_frags = skb_shinfo(skb)->nr_frags;
-+
-+	if (!nr_frags) {
-+		offset = 2 + sizeof(struct cpl_rx_pkt);
-+		qs->lro_va = sd->pg_chunk.va + 2;
-+	}
-+	len -= offset;
-+
- 	prefetch(qs->lro_va);
- 
- 	rx_frag += nr_frags;
- 	rx_frag->page = sd->pg_chunk.page;
- 	rx_frag->page_offset = sd->pg_chunk.offset + offset;
- 	rx_frag->size = len;
--	frag_len += len;
--	qs->lro_frag_tbl.nr_frags++;
--	qs->lro_frag_tbl.len = frag_len;
- 
-+	skb->len += len;
-+	skb->data_len += len;
-+	skb->truesize += len;
-+	skb_shinfo(skb)->nr_frags++;
- 
- 	if (!complete)
- 		return;
- 
--	qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
-+	skb->ip_summed = CHECKSUM_UNNECESSARY;
- 	cpl = qs->lro_va;
- 
- 	if (unlikely(cpl->vlan_valid)) {
-@@ -2123,15 +2140,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
- 		struct vlan_group *grp = pi->vlan_grp;
- 
- 		if (likely(grp != NULL)) {
--			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
--				       &qs->lro_frag_tbl);
--			goto out;
-+			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
-+			return;
- 		}
- 	}
--	napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
--
--out:
--	qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
-+	napi_gro_frags(&qs->napi);
- }
- 
- /**
-@@ -2300,8 +2313,6 @@ no_mem:
- 			if (fl->use_pages) {
- 				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
- 
--				prefetch(&qs->lro_frag_tbl);
--
- 				prefetch(addr);
- #if L1_CACHE_BYTES < 128
- 				prefetch(addr + L1_CACHE_BYTES);
+From: Sven-Thorsten Dietrich <sdietrich@suse.de>
+
+See Kernel.org:
+commit 76620aafd66f0004829764940c5466144969cffc
+Author: Herbert Xu <herbert@gondor.apana.org.au>
+Date:   Thu Apr 16 02:02:07 2009 -0700
+Subject: gro: New frags interface to avoid copying shinfo
+
+
+Signed-off-by: Sven-Thorsten Dietrich <sdietrich@suse.de>
+--- a/drivers/net/cxgb3/adapter.h
++++ b/drivers/net/cxgb3/adapter.h
+@@ -195,7 +195,7 @@ struct sge_qset {		/* an SGE queue set */
+ 	struct sge_rspq rspq;
+ 	struct sge_fl fl[SGE_RXQ_PER_SET];
+ 	struct sge_txq txq[SGE_TXQ_PER_SET];
+-	struct napi_gro_fraginfo lro_frag_tbl;
++	int nomem;
+ 	int lro_enabled;
+ 	void *lro_va;
+ 	struct net_device *netdev;
+--- a/drivers/net/cxgb3/sge.c
++++ b/drivers/net/cxgb3/sge.c
+@@ -654,7 +654,8 @@ static void t3_reset_qset(struct sge_qset *q)
+ 	q->txq_stopped = 0;
+ 	q->tx_reclaim_timer.function = NULL; /* for t3_stop_sge_timers() */
+ 	q->rx_reclaim_timer.function = NULL;
+-	q->lro_frag_tbl.nr_frags = q->lro_frag_tbl.len = 0;
++	q->nomem = 0;
++	napi_free_frags(&q->napi);
+ }
+ 
+ 
+@@ -2074,20 +2075,19 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
+ 			 struct sge_fl *fl, int len, int complete)
+ {
+ 	struct rx_sw_desc *sd = &fl->sdesc[fl->cidx];
++	struct sk_buff *skb = NULL;
+ 	struct cpl_rx_pkt *cpl;
+-	struct skb_frag_struct *rx_frag = qs->lro_frag_tbl.frags;
+-	int nr_frags = qs->lro_frag_tbl.nr_frags;
+-	int frag_len = qs->lro_frag_tbl.len;
++	struct skb_frag_struct *rx_frag;
++	int nr_frags;
+ 	int offset = 0;
+ 
+-	if (!nr_frags) {
+-		offset = 2 + sizeof(struct cpl_rx_pkt);
+-		qs->lro_va = cpl = sd->pg_chunk.va + 2;
++	if (!qs->nomem) {
++		skb = napi_get_frags(&qs->napi);
++		qs->nomem = !skb;
+ 	}
+ 
+ 	fl->credits--;
+ 
+-	len -= offset;
+ 	pci_dma_sync_single_for_cpu(adap->pdev,
+ 				    pci_unmap_addr(sd, dma_addr),
+ 				    fl->buf_size - SGE_PG_RSVD,
+@@ -2100,21 +2100,38 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
+ 			       fl->alloc_size,
+ 			       PCI_DMA_FROMDEVICE);
+ 
++	if (!skb) {
++		put_page(sd->pg_chunk.page);
++		if (complete)
++			qs->nomem = 0;
++		return;
++	}
++
++	rx_frag = skb_shinfo(skb)->frags;
++	nr_frags = skb_shinfo(skb)->nr_frags;
++
++	if (!nr_frags) {
++		offset = 2 + sizeof(struct cpl_rx_pkt);
++		qs->lro_va = sd->pg_chunk.va + 2;
++	}
++	len -= offset;
++
+ 	prefetch(qs->lro_va);
+ 
+ 	rx_frag += nr_frags;
+ 	rx_frag->page = sd->pg_chunk.page;
+ 	rx_frag->page_offset = sd->pg_chunk.offset + offset;
+ 	rx_frag->size = len;
+-	frag_len += len;
+-	qs->lro_frag_tbl.nr_frags++;
+-	qs->lro_frag_tbl.len = frag_len;
+ 
++	skb->len += len;
++	skb->data_len += len;
++	skb->truesize += len;
++	skb_shinfo(skb)->nr_frags++;
+ 
+ 	if (!complete)
+ 		return;
+ 
+-	qs->lro_frag_tbl.ip_summed = CHECKSUM_UNNECESSARY;
++	skb->ip_summed = CHECKSUM_UNNECESSARY;
+ 	cpl = qs->lro_va;
+ 
+ 	if (unlikely(cpl->vlan_valid)) {
+@@ -2123,15 +2140,11 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
+ 		struct vlan_group *grp = pi->vlan_grp;
+ 
+ 		if (likely(grp != NULL)) {
+-			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan),
+-				       &qs->lro_frag_tbl);
+-			goto out;
++			vlan_gro_frags(&qs->napi, grp, ntohs(cpl->vlan));
++			return;
+ 		}
+ 	}
+-	napi_gro_frags(&qs->napi, &qs->lro_frag_tbl);
+-
+-out:
+-	qs->lro_frag_tbl.nr_frags = qs->lro_frag_tbl.len = 0;
++	napi_gro_frags(&qs->napi);
+ }
+ 
+ /**
+@@ -2300,8 +2313,6 @@ no_mem:
+ 			if (fl->use_pages) {
+ 				void *addr = fl->sdesc[fl->cidx].pg_chunk.va;
+ 
+-				prefetch(&qs->lro_frag_tbl);
+-
+ 				prefetch(addr);
+ #if L1_CACHE_BYTES < 128
+ 				prefetch(addr + L1_CACHE_BYTES);
-- 
1.7.3.4

