[PATCH 10/10 REV5] [E1000] Implement batching

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Krishna Kumar
Date: Friday, September 14, 2007 - 2:04 am

E1000: Implement batching capability (ported thanks to changes taken from
	Jamal).

Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com>
---
 e1000_main.c |  104 ++++++++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 75 insertions(+), 29 deletions(-)

diff -ruNp org/drivers/net/e1000/e1000_main.c new/drivers/net/e1000/e1000_main.c
--- org/drivers/net/e1000/e1000_main.c	2007-09-14 10:30:57.000000000 +0530
+++ new/drivers/net/e1000/e1000_main.c	2007-09-14 10:31:02.000000000 +0530
@@ -990,7 +990,7 @@ e1000_probe(struct pci_dev *pdev,
 	if (pci_using_dac)
 		netdev->features |= NETIF_F_HIGHDMA;
 
-	netdev->features |= NETIF_F_LLTX;
+	netdev->features |= NETIF_F_LLTX | NETIF_F_BATCH_SKBS;
 
 	adapter->en_mng_pt = e1000_enable_mng_pass_thru(&adapter->hw);
 
@@ -3092,6 +3092,17 @@ e1000_tx_map(struct e1000_adapter *adapt
 	return count;
 }
 
+static void e1000_kick_DMA(struct e1000_adapter *adapter,
+			   struct e1000_tx_ring *tx_ring, int i)
+{
+	wmb();
+
+	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
+	/* we need this if more than one processor can write to our tail
+	 * at a time, it syncronizes IO on IA64/Altix systems */
+	mmiowb();
+}
+
 static void
 e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
                int tx_flags, int count)
@@ -3138,13 +3149,7 @@ e1000_tx_queue(struct e1000_adapter *ada
 	 * know there are new descriptors to fetch.  (Only
 	 * applicable for weak-ordered memory model archs,
 	 * such as IA-64). */
-	wmb();
-
 	tx_ring->next_to_use = i;
-	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
-	/* we need this if more than one processor can write to our tail
-	 * at a time, it syncronizes IO on IA64/Altix systems */
-	mmiowb();
 }
 
 /**
@@ -3251,22 +3256,23 @@ static int e1000_maybe_stop_tx(struct ne
 }
 
 #define TXD_USE_COUNT(S, X) (((S) >> (X)) + 1 )
+
+#define NETDEV_TX_DROPPED	-5
+
 static int
-e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+e1000_prep_queue_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_tx_ring *tx_ring;
 	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
-	unsigned int len = skb->len;
-	unsigned long flags;
-	unsigned int nr_frags = 0;
-	unsigned int mss = 0;
+	unsigned int len = skb->len - skb->data_len;
+	unsigned int nr_frags;
+	unsigned int mss;
 	int count = 0;
 	int tso;
 	unsigned int f;
-	len -= skb->data_len;
 
 	/* This goes back to the question of how to logically map a tx queue
 	 * to a flow.  Right now, performance is impacted slightly negatively
@@ -3276,7 +3282,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 
 	if (unlikely(skb->len <= 0)) {
 		dev_kfree_skb_any(skb);
-		return NETDEV_TX_OK;
+		return NETDEV_TX_DROPPED;
 	}
 
 	/* 82571 and newer doesn't need the workaround that limited descriptor
@@ -3322,7 +3328,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 					DPRINTK(DRV, ERR,
 						"__pskb_pull_tail failed.\n");
 					dev_kfree_skb_any(skb);
-					return NETDEV_TX_OK;
+					return NETDEV_TX_DROPPED;
 				}
 				len = skb->len - skb->data_len;
 				break;
@@ -3366,22 +3372,15 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	    (adapter->hw.mac_type == e1000_82573))
 		e1000_transfer_dhcp_info(adapter, skb);
 
-	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags))
-		/* Collision - tell upper layer to requeue */
-		return NETDEV_TX_LOCKED;
-
 	/* need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time */
-	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2))) {
-		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
+	if (unlikely(e1000_maybe_stop_tx(netdev, tx_ring, count + 2)))
 		return NETDEV_TX_BUSY;
-	}
 
 	if (unlikely(adapter->hw.mac_type == e1000_82547)) {
 		if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies + 1);
-			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 			return NETDEV_TX_BUSY;
 		}
 	}
@@ -3396,8 +3395,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	tso = e1000_tso(adapter, tx_ring, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-		return NETDEV_TX_OK;
+		return NETDEV_TX_DROPPED;
 	}
 
 	if (likely(tso)) {
@@ -3416,13 +3414,61 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	               e1000_tx_map(adapter, tx_ring, skb, first,
 	                            max_per_txd, nr_frags, mss));
 
-	netdev->trans_start = jiffies;
+	return NETDEV_TX_OK;
+}
+
+static int e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+	struct sk_buff_head *blist;
+	int ret, skbs_done = 0;
+	unsigned long flags;
+
+	if (!spin_trylock_irqsave(&tx_ring->tx_lock, flags)) {
+		/* Collision - tell upper layer to requeue */
+		return NETDEV_TX_LOCKED;
+	}
 
-	/* Make sure there is space in the ring for the next send. */
-	e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+	blist = netdev->skb_blist;
+
+	if (!skb || (blist && skb_queue_len(blist))) {
+		/*
+		 * Either batching xmit call, or single skb case but there are
+		 * skbs already in the batch list from previous failure to
+		 * xmit - send the earlier skbs first to avoid out of order.
+		 */
+		if (skb)
+			__skb_queue_tail(blist, skb);
+		skb = __skb_dequeue(blist);
+	} else {
+		blist = NULL;
+	}
+
+	do {
+		ret = e1000_prep_queue_frame(skb, netdev);
+		if (likely(ret == NETDEV_TX_OK))
+			skbs_done++;
+		else {
+			if (ret == NETDEV_TX_BUSY) {
+				if (blist)
+					__skb_queue_head(blist, skb);
+				break;
+			}
+			/* skb dropped, not a TX error */
+			ret = NETDEV_TX_OK;
+		}
+	} while (blist && (skb = __skb_dequeue(blist)) != NULL);
+
+	if (skbs_done) {
+		e1000_kick_DMA(adapter, tx_ring, adapter->tx_ring->next_to_use);
+		netdev->trans_start = jiffies;
+		/* Make sure there is space in the ring for the next send. */
+		e1000_maybe_stop_tx(netdev, tx_ring, MAX_SKB_FRAGS + 2);
+	}
 
 	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
-	return NETDEV_TX_OK;
+	return ret;
 }
 
 /**
-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 1/10 REV5] [Doc] HOWTO Documentation for batching, Krishna Kumar, (Fri Sep 14, 2:01 am)
[PATCH 4/10 REV5] [ethtool] Add ethtool support, Krishna Kumar, (Fri Sep 14, 2:02 am)
[PATCH 5/10 REV5] [IPoIB] Header file changes, Krishna Kumar, (Fri Sep 14, 2:02 am)
[PATCH 6/10 REV5] [IPoIB] CM &amp; Multicast changes, Krishna Kumar, (Fri Sep 14, 2:03 am)
[PATCH 7/10 REV5] [IPoIB] Verbs changes, Krishna Kumar, (Fri Sep 14, 2:03 am)
[PATCH 9/10 REV5] [IPoIB] Implement batching, Krishna Kumar, (Fri Sep 14, 2:04 am)
[PATCH 10/10 REV5] [E1000] Implement batching, Krishna Kumar, (Fri Sep 14, 2:04 am)
Re: [PATCH 3/10 REV5] [sched] Modify qdisc_run to support ..., Evgeniy Polyakov, (Fri Sep 14, 5:15 am)
Re: [PATCH 10/10 REV5] [E1000] Implement batching, Evgeniy Polyakov, (Fri Sep 14, 5:47 am)
Re: [PATCH 10/10 REV5] [E1000] Implement batching, Krishna Kumar2, (Sun Sep 16, 8:56 pm)
[PATCHES] TX batching, jamal, (Sun Sep 23, 10:53 am)
[PATCH 3/4][NET_BATCH] net core use batching, jamal, (Sun Sep 23, 11:00 am)
[PATCH 4/4][NET_SCHED] kill dev-&gt;gso_skb, jamal, (Sun Sep 23, 11:02 am)
Re: [PATCHES] TX batching, Jeff Garzik, (Sun Sep 23, 11:19 am)
Re: [PATCHES] TX batching, jamal, (Sun Sep 23, 12:11 pm)
Re: [PATCHES] TX batching, Kok, Auke, (Sun Sep 23, 12:36 pm)
Re: [PATCHES] TX batching, jamal, (Sun Sep 23, 2:20 pm)
Re: [PATCHES] TX batching, Kok, Auke, (Mon Sep 24, 12:00 am)
RE: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Waskiewicz Jr, Peter P, (Mon Sep 24, 12:12 pm)
Re: [PATCHES] TX batching, jamal, (Mon Sep 24, 3:38 pm)
Re: [PATCHES] TX batching, Kok, Auke, (Mon Sep 24, 3:52 pm)
[DOC] Net batching driver howto, jamal, (Mon Sep 24, 3:54 pm)
RE: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Waskiewicz Jr, Peter P, (Mon Sep 24, 3:57 pm)
RE: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Waskiewicz Jr, Peter P, (Mon Sep 24, 4:47 pm)
Re: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Stephen Hemminger, (Mon Sep 24, 5:14 pm)
Re: [PATCHES] TX batching, Jeff Garzik, (Mon Sep 24, 5:15 pm)
RE: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Waskiewicz Jr, Peter P, (Mon Sep 24, 5:31 pm)
Re: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, Stephen Hemminger, (Tue Sep 25, 8:24 am)
Re: [DOC] Net batching driver howto, Randy Dunlap, (Tue Sep 25, 1:16 pm)
Re: [DOC] Net batching driver howto, jamal, (Tue Sep 25, 3:28 pm)
[PATCHES] TX batching, jamal, (Sun Sep 30, 11:50 am)
[PATCH 2/3][NET_BATCH] net core use batching, jamal, (Sun Sep 30, 11:52 am)
[PATCH 3/3][NET_SCHED] kill dev-&gt;gso_skb, jamal, (Sun Sep 30, 11:53 am)
Re: [PATCHES] TX batching, jamal, (Sun Sep 30, 12:19 pm)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Bill Fink, (Sun Sep 30, 9:11 pm)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Patrick McHardy, (Mon Oct 1, 3:42 am)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Bill Fink, (Mon Oct 1, 9:25 pm)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Bill Fink, (Tue Oct 2, 10:29 pm)
[PATCHES] TX batching, jamal, (Sun Oct 7, 11:34 am)
[PATCH 2/3][NET_BATCH] net core use batching, jamal, (Sun Oct 7, 11:38 am)
[PATCH 3/3][NET_BATCH] kill dev-&gt;gso_skb, jamal, (Sun Oct 7, 11:39 am)
Re: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, David Miller, (Sun Oct 7, 9:51 pm)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Krishna Kumar2, (Sun Oct 7, 10:03 pm)
Re: [PATCH 1/3] [NET_BATCH] Introduce batching interface, Krishna Kumar2, (Mon Oct 8, 2:59 am)
Re: [PATCHES] TX batching, Evgeniy Polyakov, (Mon Oct 8, 5:51 am)
Re: [PATCHES] TX batching, jamal, (Mon Oct 8, 7:05 am)
Re: [PATCH 1/4] [NET_SCHED] explict hold dev tx lock, David Miller, (Mon Oct 8, 2:05 pm)
Re: parallel networking, David Miller, (Mon Oct 8, 2:11 pm)
Re: parallel networking, jamal, (Mon Oct 8, 3:30 pm)
Re: parallel networking, David Miller, (Mon Oct 8, 3:33 pm)
RE: parallel networking, Waskiewicz Jr, Peter P, (Mon Oct 8, 3:35 pm)
Re: parallel networking, jamal, (Mon Oct 8, 4:42 pm)
Re: parallel networking, Jeff Garzik, (Mon Oct 8, 6:53 pm)
Re: [PATCH 2/3][NET_BATCH] net core use batching, Krishna Kumar2, (Mon Oct 8, 8:09 pm)
Re: [PATCHES] TX batching, Krishna Kumar2, (Tue Oct 9, 1:14 am)
Re: [PATCHES] TX batching, jamal, (Tue Oct 9, 6:25 am)
Re: [PATCH 10/10 REV5] [E1000] Implement batching, Kok, Auke, (Tue Nov 13, 2:28 pm)
Re: [PATCH 10/10 REV5] [E1000] Implement batching, Krishna Kumar2, (Wed Nov 14, 1:30 am)