[kernel] r19307 - in dists/sid/linux/debian: . patches patches/features/all/bql

Ben Hutchings benh at alioth.debian.org
Sat Aug 4 13:32:29 UTC 2012


Author: benh
Date: Sat Aug  4 13:32:28 2012
New Revision: 19307

Log:
net: Add byte queue limits (bql) for reduced buffer-bloat

[prerequisite] net: new counter for tx_timeout errors in sysfs
bnx2,bnx2x,e1000e,forcedeth,igb,ixgbe,r8169,sfc,skge,sky2,tg3: Add support for bql

Added:
   dists/sid/linux/debian/patches/features/all/bql/
   dists/sid/linux/debian/patches/features/all/bql/bnx2-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/bnx2x-fix-crash-while-ethtool-t.patch
   dists/sid/linux/debian/patches/features/all/bql/bnx2x-remove-unused-variable.patch
   dists/sid/linux/debian/patches/features/all/bql/bnx2x-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-avoid-possible-inconsistent-calculation.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-avoid-unneeded-limit-decrement.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-fix-config_xps-n-build.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-fix-inconsistency-between-file-mode-and-attr-method.patch
   dists/sid/linux/debian/patches/features/all/bql/bql-fix-posdiff-to-integer-overflow-aware.patch
   dists/sid/linux/debian/patches/features/all/bql/dql-dynamic-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/dql-fix-undefined-jiffies.patch
   dists/sid/linux/debian/patches/features/all/bql/e1000e-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/forcedeath-fix-bql-support-for-forcedeath.patch
   dists/sid/linux/debian/patches/features/all/bql/forcedeth-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/igb-add-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/igb-fix-ethtool-offline-test.patch
   dists/sid/linux/debian/patches/features/all/bql/igb-ixgbe-netdev_tx_reset_queue-incorrectly-called-from-tx-init.patch
   dists/sid/linux/debian/patches/features/all/bql/ixgbe-add-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/net-add-netdev-interfaces-for-recording-sends-comp.patch
   dists/sid/linux/debian/patches/features/all/bql/net-add-queue-state-xoff-flag-for-stack.patch
   dists/sid/linux/debian/patches/features/all/bql/net-fix-issue-with-netdev_tx_reset_queue-not-resetting-queue-from.patch
   dists/sid/linux/debian/patches/features/all/bql/net-new-counter-for-tx_timeout-errors-in-sysfs.patch
   dists/sid/linux/debian/patches/features/all/bql/r8169-add-byte-queue-limit-support.patch
   dists/sid/linux/debian/patches/features/all/bql/sfc-fix-race-in-efx_enqueue_skb_tso.patch
   dists/sid/linux/debian/patches/features/all/bql/sfc-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/skge-add-byte-queue-limit-support.patch
   dists/sid/linux/debian/patches/features/all/bql/sky2-add-bql-support.patch
   dists/sid/linux/debian/patches/features/all/bql/tg3-fix-to-use-multi-queue-bql-interfaces.patch
   dists/sid/linux/debian/patches/features/all/bql/tg3-support-for-byte-queue-limits.patch
   dists/sid/linux/debian/patches/features/all/bql/xps-add-xps_queue_release-function.patch
Modified:
   dists/sid/linux/debian/changelog
   dists/sid/linux/debian/patches/series

Modified: dists/sid/linux/debian/changelog
==============================================================================
--- dists/sid/linux/debian/changelog	Fri Aug  3 01:55:45 2012	(r19306)
+++ dists/sid/linux/debian/changelog	Sat Aug  4 13:32:28 2012	(r19307)
@@ -52,6 +52,10 @@
     (Closes: #682726)
   * debugfs: Add mode, uid and gid mount options; set default mode to 700
     (Closes: #681418)
+  * net: new counter for tx_timeout errors in sysfs
+  * net: Add byte queue limits (bql) for reduced buffer-bloat
+  * bnx2,bnx2x,e1000e,forcedeth,igb,ixgbe,r8169,sfc,skge,sky2,tg3:
+    Add support for bql
 
  -- Ben Hutchings <ben at decadent.org.uk>  Tue, 24 Jul 2012 02:20:37 +0100
 

Added: dists/sid/linux/debian/patches/features/all/bql/bnx2-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bnx2-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,60 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Tue, 29 Nov 2011 11:53:05 +0000
+Subject: bnx2: Support for byte queue limits
+
+commit e98319098885859e34c23cc8a130b6b8668a6abe upstream.
+
+Changes to bnx2 to use byte queue limits.
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+CC: Tom Herbert <therbert at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bnx2.c |    6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/bnx2.c b/drivers/net/ethernet/broadcom/bnx2.c
+index d573169..787e175 100644
+--- a/drivers/net/ethernet/broadcom/bnx2.c
++++ b/drivers/net/ethernet/broadcom/bnx2.c
+@@ -2810,6 +2810,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
+ 	struct bnx2_tx_ring_info *txr = &bnapi->tx_ring;
+ 	u16 hw_cons, sw_cons, sw_ring_cons;
+ 	int tx_pkt = 0, index;
++	unsigned int tx_bytes = 0;
+ 	struct netdev_queue *txq;
+ 
+ 	index = (bnapi - bp->bnx2_napi);
+@@ -2864,6 +2865,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
+ 
+ 		sw_cons = NEXT_TX_BD(sw_cons);
+ 
++		tx_bytes += skb->len;
+ 		dev_kfree_skb(skb);
+ 		tx_pkt++;
+ 		if (tx_pkt == budget)
+@@ -2873,6 +2875,7 @@ bnx2_tx_int(struct bnx2 *bp, struct bnx2_napi *bnapi, int budget)
+ 			hw_cons = bnx2_get_hw_tx_cons(bnapi);
+ 	}
+ 
++	netdev_tx_completed_queue(txq, tx_pkt, tx_bytes);
+ 	txr->hw_tx_cons = hw_cons;
+ 	txr->tx_cons = sw_cons;
+ 
+@@ -5393,6 +5396,7 @@ bnx2_free_tx_skbs(struct bnx2 *bp)
+ 			}
+ 			dev_kfree_skb(skb);
+ 		}
++		netdev_tx_reset_queue(netdev_get_tx_queue(bp->dev, i));
+ 	}
+ }
+ 
+@@ -6546,6 +6550,8 @@ bnx2_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	}
+ 	txbd->tx_bd_vlan_tag_flags |= TX_BD_FLAGS_END;
+ 
++	netdev_tx_sent_queue(txq, skb->len);
++
+ 	prod = NEXT_TX_BD(prod);
+ 	txr->tx_prod_bseq += skb->len;
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/bnx2x-fix-crash-while-ethtool-t.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bnx2x-fix-crash-while-ethtool-t.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,40 @@
+From: Dmitry Kravkov <dmitry at broadcom.com>
+Date: Tue, 6 Dec 2011 02:05:12 +0000
+Subject: bnx2x: fix crash while ethtool -t
+
+commit 73dbb5e1627a35c8ab81f3813c096e9e7aaabaaa upstream.
+
+commit 2df1a70aaf70e8dff11b89b938a5f317556ee640  "bnx2x: Support
+for byte queue limits" has introduced an asymmetry in usage of
+netdev_tx_completed_queue and netdev_tx_sent_queue. Missing
+call to netdev_tx_sent_queue causes the crash during ethtool -t.
+
+The patch adds the missing call.
+
+Signed-off-by: Dmitry Kravkov <dmitry at broadcom.com>
+Signed-off-by: Eilon Greenstein <eilong at broadcom.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Backported to 3.2: adjust context]
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c |    3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_ethtool.c
+@@ -1740,6 +1740,7 @@
+ 	struct sw_rx_bd *rx_buf;
+ 	u16 len;
+ 	int rc = -ENODEV;
++	struct netdev_queue *txq = netdev_get_tx_queue(bp->dev, txdata->txq_index);
+ 
+ 	/* check the loopback mode */
+ 	switch (loopback_mode) {
+@@ -1784,6 +1785,8 @@
+ 	tx_start_idx = le16_to_cpu(*txdata->tx_cons_sb);
+ 	rx_start_idx = le16_to_cpu(*fp_rx->rx_cons_sb);
+ 
++	netdev_tx_sent_queue(txq, skb->len);
++
+ 	pkt_prod = txdata->tx_pkt_prod++;
+ 	tx_buf = &txdata->tx_buf_ring[TX_BD(pkt_prod)];
+ 	tx_buf->first_bd = txdata->tx_bd_prod;

Added: dists/sid/linux/debian/patches/features/all/bql/bnx2x-remove-unused-variable.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bnx2x-remove-unused-variable.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,32 @@
+From: Dmitry Kravkov <dmitry at broadcom.com>
+Date: Sun, 13 Nov 2011 04:34:23 +0000
+Subject: bnx2x: remove unused variable
+
+commit ad756594a8d88ffc048d14b8d5c02971e08856ce upstream.
+
+Signed-off-by: Dmitry Kravkov <dmitry at broadcom.com>
+Signed-off-by: Eilon Greenstein <eilong at broadcom.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |    4 +---
+ 1 file changed, 1 insertion(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+index 1ace946..f946a6e 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -1094,13 +1094,11 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
+ 		for_each_cos_in_tx_queue(fp, cos) {
+ 			struct bnx2x_fp_txdata *txdata = &fp->txdata[cos];
+ 
+-			u16 bd_cons = txdata->tx_bd_cons;
+ 			u16 sw_prod = txdata->tx_pkt_prod;
+ 			u16 sw_cons = txdata->tx_pkt_cons;
+ 
+ 			while (sw_cons != sw_prod) {
+-				bd_cons = bnx2x_free_tx_pkt(bp, txdata,
+-							    TX_BD(sw_cons));
++				bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons));
+ 				sw_cons++;
+ 			}
+ 		}

Added: dists/sid/linux/debian/patches/features/all/bql/bnx2x-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bnx2x-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,111 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:37 +0000
+Subject: bnx2x: Support for byte queue limits
+
+commit 2df1a70aaf70e8dff11b89b938a5f317556ee640 upstream.
+
+Changes to bnx2x to use byte queue limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c |   26 +++++++++++++++++++----
+ 1 file changed, 22 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+index 8336c78..42ce566 100644
+--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
++++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+@@ -102,7 +102,8 @@ int load_count[2][3] = { {0} }; /* per-path: 0-common, 1-port0, 2-port1 */
+  * return idx of last bd freed
+  */
+ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
+-			     u16 idx)
++			     u16 idx, unsigned int *pkts_compl,
++			     unsigned int *bytes_compl)
+ {
+ 	struct sw_tx_bd *tx_buf = &txdata->tx_buf_ring[idx];
+ 	struct eth_tx_start_bd *tx_start_bd;
+@@ -159,6 +160,10 @@ static u16 bnx2x_free_tx_pkt(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata,
+ 
+ 	/* release skb */
+ 	WARN_ON(!skb);
++	if (skb) {
++		(*pkts_compl)++;
++		(*bytes_compl) += skb->len;
++	}
+ 	dev_kfree_skb_any(skb);
+ 	tx_buf->first_bd = 0;
+ 	tx_buf->skb = NULL;
+@@ -170,6 +175,7 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
+ {
+ 	struct netdev_queue *txq;
+ 	u16 hw_cons, sw_cons, bd_cons = txdata->tx_bd_cons;
++	unsigned int pkts_compl = 0, bytes_compl = 0;
+ 
+ #ifdef BNX2X_STOP_ON_ERROR
+ 	if (unlikely(bp->panic))
+@@ -189,10 +195,14 @@ int bnx2x_tx_int(struct bnx2x *bp, struct bnx2x_fp_txdata *txdata)
+ 				      " pkt_cons %u\n",
+ 		   txdata->txq_index, hw_cons, sw_cons, pkt_cons);
+ 
+-		bd_cons = bnx2x_free_tx_pkt(bp, txdata, pkt_cons);
++		bd_cons = bnx2x_free_tx_pkt(bp, txdata, pkt_cons,
++		    &pkts_compl, &bytes_compl);
++
+ 		sw_cons++;
+ 	}
+ 
++	netdev_tx_completed_queue(txq, pkts_compl, bytes_compl);
++
+ 	txdata->tx_pkt_cons = sw_cons;
+ 	txdata->tx_bd_cons = bd_cons;
+ 
+@@ -1077,14 +1087,18 @@ static void bnx2x_free_tx_skbs(struct bnx2x *bp)
+ 		struct bnx2x_fastpath *fp = &bp->fp[i];
+ 		for_each_cos_in_tx_queue(fp, cos) {
+ 			struct bnx2x_fp_txdata *txdata = &fp->txdata[cos];
++			unsigned pkts_compl = 0, bytes_compl = 0;
+ 
+ 			u16 sw_prod = txdata->tx_pkt_prod;
+ 			u16 sw_cons = txdata->tx_pkt_cons;
+ 
+ 			while (sw_cons != sw_prod) {
+-				bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons));
++				bnx2x_free_tx_pkt(bp, txdata, TX_BD(sw_cons),
++				    &pkts_compl, &bytes_compl);
+ 				sw_cons++;
+ 			}
++			netdev_tx_reset_queue(
++			    netdev_get_tx_queue(bp->dev, txdata->txq_index));
+ 		}
+ 	}
+ }
+@@ -2788,6 +2802,7 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		mapping = skb_frag_dma_map(&bp->pdev->dev, frag, 0,
+ 					   skb_frag_size(frag), DMA_TO_DEVICE);
+ 		if (unlikely(dma_mapping_error(&bp->pdev->dev, mapping))) {
++			unsigned int pkts_compl = 0, bytes_compl = 0;
+ 
+ 			DP(NETIF_MSG_TX_QUEUED, "Unable to map page - "
+ 						"dropping packet...\n");
+@@ -2799,7 +2814,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 			 */
+ 			first_bd->nbd = cpu_to_le16(nbd);
+ 			bnx2x_free_tx_pkt(bp, txdata,
+-					  TX_BD(txdata->tx_pkt_prod));
++					  TX_BD(txdata->tx_pkt_prod),
++					  &pkts_compl, &bytes_compl);
+ 			return NETDEV_TX_OK;
+ 		}
+ 
+@@ -2860,6 +2876,8 @@ netdev_tx_t bnx2x_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 		   pbd_e2->parsing_data);
+ 	DP(NETIF_MSG_TX_QUEUED, "doorbell: nbd %d  bd %u\n", nbd, bd_prod);
+ 
++	netdev_tx_sent_queue(txq, skb->len);
++
+ 	txdata->tx_pkt_prod++;
+ 	/*
+ 	 * Make sure that the BD data is updated before updating the producer

Added: dists/sid/linux/debian/patches/features/all/bql/bql-avoid-possible-inconsistent-calculation.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-avoid-possible-inconsistent-calculation.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,55 @@
+From: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Date: Wed, 30 May 2012 12:25:37 +0000
+Subject: bql: Avoid possible inconsistent calculation.
+
+commit 914bec1011a25f65cdc94988a6f974bfb9a3c10d upstream.
+
+dql->num_queued could change while processing dql_completed().
+To provide consistent calculation, added an on stack variable.
+
+Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Cc: Tom Herbert <therbert at google.com>
+Cc: Eric Dumazet <eric.dumazet at gmail.com>
+Cc: Denys Fedoryshchenko <denys at visp.net.lb>
+Signed-off-by: Eric Dumazet <edumazet at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ lib/dynamic_queue_limits.c |   12 +++++++-----
+ 1 file changed, 7 insertions(+), 5 deletions(-)
+
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+index 0fafa77..0777c5a 100644
+--- a/lib/dynamic_queue_limits.c
++++ b/lib/dynamic_queue_limits.c
+@@ -17,16 +17,18 @@
+ void dql_completed(struct dql *dql, unsigned int count)
+ {
+ 	unsigned int inprogress, prev_inprogress, limit;
+-	unsigned int ovlimit, completed;
++	unsigned int ovlimit, completed, num_queued;
+ 	bool all_prev_completed;
+ 
++	num_queued = ACCESS_ONCE(dql->num_queued);
++
+ 	/* Can't complete more than what's in queue */
+-	BUG_ON(count > dql->num_queued - dql->num_completed);
++	BUG_ON(count > num_queued - dql->num_completed);
+ 
+ 	completed = dql->num_completed + count;
+ 	limit = dql->limit;
+-	ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
+-	inprogress = dql->num_queued - completed;
++	ovlimit = POSDIFF(num_queued - dql->num_completed, limit);
++	inprogress = num_queued - completed;
+ 	prev_inprogress = dql->prev_num_queued - dql->num_completed;
+ 	all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
+ 
+@@ -106,7 +108,7 @@ void dql_completed(struct dql *dql, unsigned int count)
+ 	dql->prev_ovlimit = ovlimit;
+ 	dql->prev_last_obj_cnt = dql->last_obj_cnt;
+ 	dql->num_completed = completed;
+-	dql->prev_num_queued = dql->num_queued;
++	dql->prev_num_queued = num_queued;
+ }
+ EXPORT_SYMBOL(dql_completed);
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/bql-avoid-unneeded-limit-decrement.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-avoid-unneeded-limit-decrement.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,70 @@
+From: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Date: Wed, 30 May 2012 12:25:19 +0000
+Subject: bql: Avoid unneeded limit decrement.
+
+commit 25426b794efdc70dde7fd3134dc56fac3e7d562d upstream.
+
+When below pattern is observed,
+
+                                               TIME
+       dql_queued()         dql_completed()     |
+      a) initial state                          |
+                                                |
+      b) X bytes queued                         V
+
+      c) Y bytes queued
+                           d) X bytes completed
+      e) Z bytes queued
+                           f) Y bytes completed
+
+a) dql->limit has already some value and there is no in-flight packet.
+b) X bytes queued.
+c) Y bytes queued and excess limit.
+d) X bytes completed and dql->prev_ovlimit is set and also
+   dql->prev_num_queued is set Y.
+e) Z bytes queued.
+f) Y bytes completed. inprogress and prev_inprogress are true.
+
+At f), according to the comment, all_prev_completed becomes
+true and limit should be increased. But POSDIFF() ignores
+(completed == dql->prev_num_queued) case, so limit is decreased.
+
+Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Cc: Tom Herbert <therbert at google.com>
+Cc: Eric Dumazet <eric.dumazet at gmail.com>
+Cc: Denys Fedoryshchenko <denys at visp.net.lb>
+Acked-by: Eric Dumazet <edumazet at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ lib/dynamic_queue_limits.c |    6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+index c87eb76..0fafa77 100644
+--- a/lib/dynamic_queue_limits.c
++++ b/lib/dynamic_queue_limits.c
+@@ -11,12 +11,14 @@
+ #include <linux/dynamic_queue_limits.h>
+ 
+ #define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
++#define AFTER_EQ(A, B) ((int)((A) - (B)) >= 0)
+ 
+ /* Records completed count and recalculates the queue limit */
+ void dql_completed(struct dql *dql, unsigned int count)
+ {
+ 	unsigned int inprogress, prev_inprogress, limit;
+-	unsigned int ovlimit, all_prev_completed, completed;
++	unsigned int ovlimit, completed;
++	bool all_prev_completed;
+ 
+ 	/* Can't complete more than what's in queue */
+ 	BUG_ON(count > dql->num_queued - dql->num_completed);
+@@ -26,7 +28,7 @@ void dql_completed(struct dql *dql, unsigned int count)
+ 	ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
+ 	inprogress = dql->num_queued - completed;
+ 	prev_inprogress = dql->prev_num_queued - dql->num_completed;
+-	all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
++	all_prev_completed = AFTER_EQ(completed, dql->prev_num_queued);
+ 
+ 	if ((ovlimit && !inprogress) ||
+ 	    (dql->prev_ovlimit && all_prev_completed)) {

Added: dists/sid/linux/debian/patches/features/all/bql/bql-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,325 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:09 +0000
+Subject: bql: Byte queue limits
+
+commit 114cf5802165ee93e3ab461c9c505cd94a08b800 upstream.
+
+Networking stack support for byte queue limits, uses dynamic queue
+limits library.  Byte queue limits are maintained per transmit queue,
+and a dql structure has been added to netdev_queue structure for this
+purpose.
+
+Configuration of bql is in the tx-<n> sysfs directory for the queue
+under the byte_queue_limits directory.  Configuration includes:
+limit_min, bql minimum limit
+limit_max, bql maximum limit
+hold_time, bql slack hold time
+
+Also under the directory are:
+limit, current byte limit
+inflight, current number of bytes on the queue
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+[bwh: Adjust context in net/Kconfig for 3.2]
+---
+ include/linux/netdevice.h |   32 ++++++++++-
+ net/Kconfig               |    6 ++
+ net/core/dev.c            |    3 +
+ net/core/net-sysfs.c      |  140 ++++++++++++++++++++++++++++++++++++++++++---
+ 4 files changed, 172 insertions(+), 9 deletions(-)
+
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -43,6 +43,7 @@
+ #include <linux/rculist.h>
+ #include <linux/dmaengine.h>
+ #include <linux/workqueue.h>
++#include <linux/dynamic_queue_limits.h>
+ 
+ #include <linux/ethtool.h>
+ #include <net/net_namespace.h>
+@@ -540,7 +541,6 @@
+  */
+ 	struct net_device	*dev;
+ 	struct Qdisc		*qdisc;
+-	unsigned long		state;
+ 	struct Qdisc		*qdisc_sleeping;
+ #ifdef CONFIG_SYSFS
+ 	struct kobject		kobj;
+@@ -563,6 +563,12 @@
+ 	 * (/sys/class/net/DEV/Q/trans_timeout)
+ 	 */
+ 	unsigned long		trans_timeout;
++
++	unsigned long		state;
++
++#ifdef CONFIG_BQL
++	struct dql		dql;
++#endif
+ } ____cacheline_aligned_in_smp;
+ 
+ static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
+@@ -1926,6 +1932,15 @@
+ static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
+ 					unsigned int bytes)
+ {
++#ifdef CONFIG_BQL
++	dql_queued(&dev_queue->dql, bytes);
++	if (unlikely(dql_avail(&dev_queue->dql) < 0)) {
++		set_bit(__QUEUE_STATE_STACK_XOFF, &dev_queue->state);
++		if (unlikely(dql_avail(&dev_queue->dql) >= 0))
++			clear_bit(__QUEUE_STATE_STACK_XOFF,
++			    &dev_queue->state);
++	}
++#endif
+ }
+ 
+ static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes)
+@@ -1936,6 +1951,18 @@
+ static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue,
+ 					     unsigned pkts, unsigned bytes)
+ {
++#ifdef CONFIG_BQL
++	if (likely(bytes)) {
++		dql_completed(&dev_queue->dql, bytes);
++		if (unlikely(test_bit(__QUEUE_STATE_STACK_XOFF,
++		    &dev_queue->state) &&
++		    dql_avail(&dev_queue->dql) >= 0)) {
++			if (test_and_clear_bit(__QUEUE_STATE_STACK_XOFF,
++			     &dev_queue->state))
++				netif_schedule_queue(dev_queue);
++		}
++	}
++#endif
+ }
+ 
+ static inline void netdev_completed_queue(struct net_device *dev,
+@@ -1946,6 +1973,9 @@
+ 
+ static inline void netdev_tx_reset_queue(struct netdev_queue *q)
+ {
++#ifdef CONFIG_BQL
++	dql_reset(&q->dql);
++#endif
+ }
+ 
+ static inline void netdev_reset_queue(struct net_device *dev_queue)
+--- a/net/Kconfig
++++ b/net/Kconfig
+@@ -232,6 +232,12 @@
+ 	depends on SMP && SYSFS && USE_GENERIC_SMP_HELPERS
+ 	default y
+ 
++config BQL
++	boolean
++	depends on SYSFS
++	select DQL
++	default y
++
+ config BPF_JIT
+ 	bool "enable BPF Just In Time compiler"
+ 	depends on HAVE_BPF_JIT
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -5524,6 +5524,9 @@
+ 	queue->xmit_lock_owner = -1;
+ 	netdev_queue_numa_node_write(queue, NUMA_NO_NODE);
+ 	queue->dev = dev;
++#ifdef CONFIG_BQL
++	dql_init(&queue->dql, HZ);
++#endif
+ }
+ 
+ static int netif_alloc_netdev_queues(struct net_device *dev)
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -21,6 +21,7 @@
+ #include <linux/wireless.h>
+ #include <linux/vmalloc.h>
+ #include <linux/export.h>
++#include <linux/jiffies.h>
+ #include <net/wext.h>
+ 
+ #include "net-sysfs.h"
+@@ -845,6 +846,116 @@
+ static struct netdev_queue_attribute queue_trans_timeout =
+ 	__ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
+ 
++#ifdef CONFIG_BQL
++/*
++ * Byte queue limits sysfs structures and functions.
++ */
++static ssize_t bql_show(char *buf, unsigned int value)
++{
++	return sprintf(buf, "%u\n", value);
++}
++
++static ssize_t bql_set(const char *buf, const size_t count,
++		       unsigned int *pvalue)
++{
++	unsigned int value;
++	int err;
++
++	if (!strcmp(buf, "max") || !strcmp(buf, "max\n"))
++		value = DQL_MAX_LIMIT;
++	else {
++		err = kstrtouint(buf, 10, &value);
++		if (err < 0)
++			return err;
++		if (value > DQL_MAX_LIMIT)
++			return -EINVAL;
++	}
++
++	*pvalue = value;
++
++	return count;
++}
++
++static ssize_t bql_show_hold_time(struct netdev_queue *queue,
++				  struct netdev_queue_attribute *attr,
++				  char *buf)
++{
++	struct dql *dql = &queue->dql;
++
++	return sprintf(buf, "%u\n", jiffies_to_msecs(dql->slack_hold_time));
++}
++
++static ssize_t bql_set_hold_time(struct netdev_queue *queue,
++				 struct netdev_queue_attribute *attribute,
++				 const char *buf, size_t len)
++{
++	struct dql *dql = &queue->dql;
++	unsigned value;
++	int err;
++
++	err = kstrtouint(buf, 10, &value);
++	if (err < 0)
++		return err;
++
++	dql->slack_hold_time = msecs_to_jiffies(value);
++
++	return len;
++}
++
++static struct netdev_queue_attribute bql_hold_time_attribute =
++	__ATTR(hold_time, S_IRUGO | S_IWUSR, bql_show_hold_time,
++	    bql_set_hold_time);
++
++static ssize_t bql_show_inflight(struct netdev_queue *queue,
++				 struct netdev_queue_attribute *attr,
++				 char *buf)
++{
++	struct dql *dql = &queue->dql;
++
++	return sprintf(buf, "%u\n", dql->num_queued - dql->num_completed);
++}
++
++static struct netdev_queue_attribute bql_inflight_attribute =
++	__ATTR(inflight, S_IRUGO | S_IWUSR, bql_show_inflight, NULL);
++
++#define BQL_ATTR(NAME, FIELD)						\
++static ssize_t bql_show_ ## NAME(struct netdev_queue *queue,		\
++				 struct netdev_queue_attribute *attr,	\
++				 char *buf)				\
++{									\
++	return bql_show(buf, queue->dql.FIELD);				\
++}									\
++									\
++static ssize_t bql_set_ ## NAME(struct netdev_queue *queue,		\
++				struct netdev_queue_attribute *attr,	\
++				const char *buf, size_t len)		\
++{									\
++	return bql_set(buf, len, &queue->dql.FIELD);			\
++}									\
++									\
++static struct netdev_queue_attribute bql_ ## NAME ## _attribute =	\
++	__ATTR(NAME, S_IRUGO | S_IWUSR, bql_show_ ## NAME,		\
++	    bql_set_ ## NAME);
++
++BQL_ATTR(limit, limit)
++BQL_ATTR(limit_max, max_limit)
++BQL_ATTR(limit_min, min_limit)
++
++static struct attribute *dql_attrs[] = {
++	&bql_limit_attribute.attr,
++	&bql_limit_max_attribute.attr,
++	&bql_limit_min_attribute.attr,
++	&bql_hold_time_attribute.attr,
++	&bql_inflight_attribute.attr,
++	NULL
++};
++
++static struct attribute_group dql_group = {
++	.name  = "byte_queue_limits",
++	.attrs  = dql_attrs,
++};
++#endif /* CONFIG_BQL */
++
+ #ifdef CONFIG_XPS
+ static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
+ {
+@@ -1096,17 +1207,17 @@
+ 	NULL
+ };
+ 
+-#ifdef CONFIG_XPS
+ static void netdev_queue_release(struct kobject *kobj)
+ {
+ 	struct netdev_queue *queue = to_netdev_queue(kobj);
+ 
++#ifdef CONFIG_XPS
+ 	xps_queue_release(queue);
++#endif
+ 
+ 	memset(kobj, 0, sizeof(*kobj));
+ 	dev_put(queue->dev);
+ }
+-#endif /* CONFIG_XPS */
+ 
+ static struct kobj_type netdev_queue_ktype = {
+ 	.sysfs_ops = &netdev_queue_sysfs_ops,
+@@ -1125,14 +1236,21 @@
+ 	kobj->kset = net->queues_kset;
+ 	error = kobject_init_and_add(kobj, &netdev_queue_ktype, NULL,
+ 	    "tx-%u", index);
+-	if (error) {
+-		kobject_put(kobj);
+-		return error;
+-	}
++	if (error)
++		goto exit;
++
++#ifdef CONFIG_BQL
++	error = sysfs_create_group(kobj, &dql_group);
++	if (error)
++		goto exit;
++#endif
+ 
+ 	kobject_uevent(kobj, KOBJ_ADD);
+ 	dev_hold(queue->dev);
+ 
++	return 0;
++exit:
++	kobject_put(kobj);
+ 	return error;
+ }
+ #endif /* CONFIG_SYSFS */
+@@ -1152,8 +1270,14 @@
+ 		}
+ 	}
+ 
+-	while (--i >= new_num)
+-		kobject_put(&net->_tx[i].kobj);
++	while (--i >= new_num) {
++		struct netdev_queue *queue = net->_tx + i;
++
++#ifdef CONFIG_BQL
++		sysfs_remove_group(&queue->kobj, &dql_group);
++#endif
++		kobject_put(&queue->kobj);
++	}
+ 
+ 	return error;
+ #else

Added: dists/sid/linux/debian/patches/features/all/bql/bql-fix-config_xps-n-build.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-fix-config_xps-n-build.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,29 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Sun, 4 Dec 2011 12:38:00 +0000
+Subject: bql: fix CONFIG_XPS=n build
+
+commit b474ae77609b725098d5a7cc8f69c1c528710d53 upstream.
+
+netdev_queue_release() should be called even if CONFIG_XPS=n
+to properly release device reference.
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ net/core/net-sysfs.c |    2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index 3bf72b6..9d13463 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -1221,9 +1221,7 @@ static void netdev_queue_release(struct kobject *kobj)
+ 
+ static struct kobj_type netdev_queue_ktype = {
+ 	.sysfs_ops = &netdev_queue_sysfs_ops,
+-#ifdef CONFIG_XPS
+ 	.release = netdev_queue_release,
+-#endif
+ 	.default_attrs = netdev_queue_default_attrs,
+ };
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/bql-fix-inconsistency-between-file-mode-and-attr-method.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-fix-inconsistency-between-file-mode-and-attr-method.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,30 @@
+From: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Date: Sat, 14 Jan 2012 07:10:21 +0000
+Subject: bql: Fix inconsistency between file mode and attr method.
+
+commit 795d9a2538b205d9329f34798ec96503a07b7919 upstream.
+
+There is no store() method for inflight attribute in the
+tx-<n>/byte_queue_limits sysfs directory.
+So remove S_IWUSR bit.
+
+Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ net/core/net-sysfs.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index f3dbd4f..a1727cd 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -929,7 +929,7 @@ static ssize_t bql_show_inflight(struct netdev_queue *queue,
+ }
+ 
+ static struct netdev_queue_attribute bql_inflight_attribute =
+-	__ATTR(inflight, S_IRUGO | S_IWUSR, bql_show_inflight, NULL);
++	__ATTR(inflight, S_IRUGO, bql_show_inflight, NULL);
+ 
+ #define BQL_ATTR(NAME, FIELD)						\
+ static ssize_t bql_show_ ## NAME(struct netdev_queue *queue,		\

Added: dists/sid/linux/debian/patches/features/all/bql/bql-fix-posdiff-to-integer-overflow-aware.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/bql-fix-posdiff-to-integer-overflow-aware.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,31 @@
+From: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Date: Wed, 30 May 2012 12:24:39 +0000
+Subject: bql: Fix POSDIFF() to integer overflow aware.
+
+commit 0cfd32b736ae0c36b42697584811042726c07cba upstream.
+
+POSDIFF() fails to take into account integer overflow case.
+
+Signed-off-by: Hiroaki SHIMODA <shimoda.hiroaki at gmail.com>
+Cc: Tom Herbert <therbert at google.com>
+Cc: Eric Dumazet <eric.dumazet at gmail.com>
+Cc: Denys Fedoryshchenko <denys at visp.net.lb>
+Acked-by: Eric Dumazet <edumazet at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ lib/dynamic_queue_limits.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+index 6ab4587..c87eb76 100644
+--- a/lib/dynamic_queue_limits.c
++++ b/lib/dynamic_queue_limits.c
+@@ -10,7 +10,7 @@
+ #include <linux/jiffies.h>
+ #include <linux/dynamic_queue_limits.h>
+ 
+-#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
++#define POSDIFF(A, B) ((int)((A) - (B)) > 0 ? (A) - (B) : 0)
+ 
+ /* Records completed count and recalculates the queue limit */
+ void dql_completed(struct dql *dql, unsigned int count)

Added: dists/sid/linux/debian/patches/features/all/bql/dql-dynamic-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/dql-dynamic-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,328 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:32:35 +0000
+Subject: dql: Dynamic queue limits
+
+commit 75957ba36c05b979701e9ec64b37819adc12f830 upstream.
+
+Implementation of dynamic queue limits (dql).  This is a libary which
+allows a queue limit to be dynamically managed.  The goal of dql is
+to set the queue limit, number of objects to the queue, to be minimized
+without allowing the queue to be starved.
+
+dql would be used with a queue which has these properties:
+
+1) Objects are queued up to some limit which can be expressed as a
+   count of objects.
+2) Periodically a completion process executes which retires consumed
+   objects.
+3) Starvation occurs when limit has been reached, all queued data has
+   actually been consumed but completion processing has not yet run,
+   so queuing new data is blocked.
+4) Minimizing the amount of queued data is desirable.
+
+A canonical example of such a queue would be a NIC HW transmit queue.
+
+The queue limit is dynamic, it will increase or decrease over time
+depending on the workload.  The queue limit is recalculated each time
+completion processing is done.  Increases occur when the queue is
+starved and can exponentially increase over successive intervals.
+Decreases occur when more data is being maintained in the queue than
+needed to prevent starvation.  The number of extra objects, or "slack",
+is measured over successive intervals, and to avoid hysteresis the
+limit is only reduced by the miminum slack seen over a configurable
+time period.
+
+dql API provides routines to manage the queue:
+- dql_init is called to intialize the dql structure
+- dql_reset is called to reset dynamic values
+- dql_queued called when objects are being enqueued
+- dql_avail returns availability in the queue
+- dql_completed is called when objects have be consumed in the queue
+
+Configuration consists of:
+- max_limit, maximum limit
+- min_limit, minimum limit
+- slack_hold_time, time to measure instances of slack before reducing
+  queue limit
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ include/linux/dynamic_queue_limits.h |   97 +++++++++++++++++++++++++
+ lib/Kconfig                          |    3 +
+ lib/Makefile                         |    2 +
+ lib/dynamic_queue_limits.c           |  133 ++++++++++++++++++++++++++++++++++
+ 4 files changed, 235 insertions(+)
+ create mode 100644 include/linux/dynamic_queue_limits.h
+ create mode 100644 lib/dynamic_queue_limits.c
+
+diff --git a/include/linux/dynamic_queue_limits.h b/include/linux/dynamic_queue_limits.h
+new file mode 100644
+index 0000000..5621547
+--- /dev/null
++++ b/include/linux/dynamic_queue_limits.h
+@@ -0,0 +1,97 @@
++/*
++ * Dynamic queue limits (dql) - Definitions
++ *
++ * Copyright (c) 2011, Tom Herbert <therbert at google.com>
++ *
++ * This header file contains the definitions for dynamic queue limits (dql).
++ * dql would be used in conjunction with a producer/consumer type queue
++ * (possibly a HW queue).  Such a queue would have these general properties:
++ *
++ *   1) Objects are queued up to some limit specified as number of objects.
++ *   2) Periodically a completion process executes which retires consumed
++ *      objects.
++ *   3) Starvation occurs when limit has been reached, all queued data has
++ *      actually been consumed, but completion processing has not yet run
++ *      so queuing new data is blocked.
++ *   4) Minimizing the amount of queued data is desirable.
++ *
++ * The goal of dql is to calculate the limit as the minimum number of objects
++ * needed to prevent starvation.
++ *
++ * The primary functions of dql are:
++ *    dql_queued - called when objects are enqueued to record number of objects
++ *    dql_avail - returns how many objects are available to be queued based
++ *      on the object limit and how many objects are already enqueued
++ *    dql_completed - called at completion time to indicate how many objects
++ *      were retired from the queue
++ *
++ * The dql implementation does not implement any locking for the dql data
++ * structures, the higher layer should provide this.  dql_queued should
++ * be serialized to prevent concurrent execution of the function; this
++ * is also true for  dql_completed.  However, dql_queued and dlq_completed  can
++ * be executed concurrently (i.e. they can be protected by different locks).
++ */
++
++#ifndef _LINUX_DQL_H
++#define _LINUX_DQL_H
++
++#ifdef __KERNEL__
++
++struct dql {
++	/* Fields accessed in enqueue path (dql_queued) */
++	unsigned int	num_queued;		/* Total ever queued */
++	unsigned int	adj_limit;		/* limit + num_completed */
++	unsigned int	last_obj_cnt;		/* Count at last queuing */
++
++	/* Fields accessed only by completion path (dql_completed) */
++
++	unsigned int	limit ____cacheline_aligned_in_smp; /* Current limit */
++	unsigned int	num_completed;		/* Total ever completed */
++
++	unsigned int	prev_ovlimit;		/* Previous over limit */
++	unsigned int	prev_num_queued;	/* Previous queue total */
++	unsigned int	prev_last_obj_cnt;	/* Previous queuing cnt */
++
++	unsigned int	lowest_slack;		/* Lowest slack found */
++	unsigned long	slack_start_time;	/* Time slacks seen */
++
++	/* Configuration */
++	unsigned int	max_limit;		/* Max limit */
++	unsigned int	min_limit;		/* Minimum limit */
++	unsigned int	slack_hold_time;	/* Time to measure slack */
++};
++
++/* Set some static maximums */
++#define DQL_MAX_OBJECT (UINT_MAX / 16)
++#define DQL_MAX_LIMIT ((UINT_MAX / 2) - DQL_MAX_OBJECT)
++
++/*
++ * Record number of objects queued. Assumes that caller has already checked
++ * availability in the queue with dql_avail.
++ */
++static inline void dql_queued(struct dql *dql, unsigned int count)
++{
++	BUG_ON(count > DQL_MAX_OBJECT);
++
++	dql->num_queued += count;
++	dql->last_obj_cnt = count;
++}
++
++/* Returns how many objects can be queued, < 0 indicates over limit. */
++static inline int dql_avail(const struct dql *dql)
++{
++	return dql->adj_limit - dql->num_queued;
++}
++
++/* Record number of completed objects and recalculate the limit. */
++void dql_completed(struct dql *dql, unsigned int count);
++
++/* Reset dql state */
++void dql_reset(struct dql *dql);
++
++/* Initialize dql state */
++int dql_init(struct dql *dql, unsigned hold_time);
++
++#endif /* _KERNEL_ */
++
++#endif /* _LINUX_DQL_H */
+diff --git a/lib/Kconfig b/lib/Kconfig
+index 32f3e5a..63b5782 100644
+--- a/lib/Kconfig
++++ b/lib/Kconfig
+@@ -244,6 +244,9 @@ config CPU_RMAP
+ 	bool
+ 	depends on SMP
+ 
++config DQL
++	bool
++
+ #
+ # Netlink attribute parsing support is select'ed if needed
+ #
+diff --git a/lib/Makefile b/lib/Makefile
+index a4da283..ff00d4d 100644
+--- a/lib/Makefile
++++ b/lib/Makefile
+@@ -115,6 +115,8 @@ obj-$(CONFIG_CPU_RMAP) += cpu_rmap.o
+ 
+ obj-$(CONFIG_CORDIC) += cordic.o
+ 
++obj-$(CONFIG_DQL) += dynamic_queue_limits.o
++
+ hostprogs-y	:= gen_crc32table
+ clean-files	:= crc32table.h
+ 
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+new file mode 100644
+index 0000000..3d1bdcd
+--- /dev/null
++++ b/lib/dynamic_queue_limits.c
+@@ -0,0 +1,133 @@
++/*
++ * Dynamic byte queue limits.  See include/linux/dynamic_queue_limits.h
++ *
++ * Copyright (c) 2011, Tom Herbert <therbert at google.com>
++ */
++#include <linux/module.h>
++#include <linux/types.h>
++#include <linux/ctype.h>
++#include <linux/kernel.h>
++#include <linux/dynamic_queue_limits.h>
++
++#define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)
++
++/* Records completed count and recalculates the queue limit */
++void dql_completed(struct dql *dql, unsigned int count)
++{
++	unsigned int inprogress, prev_inprogress, limit;
++	unsigned int ovlimit, all_prev_completed, completed;
++
++	/* Can't complete more than what's in queue */
++	BUG_ON(count > dql->num_queued - dql->num_completed);
++
++	completed = dql->num_completed + count;
++	limit = dql->limit;
++	ovlimit = POSDIFF(dql->num_queued - dql->num_completed, limit);
++	inprogress = dql->num_queued - completed;
++	prev_inprogress = dql->prev_num_queued - dql->num_completed;
++	all_prev_completed = POSDIFF(completed, dql->prev_num_queued);
++
++	if ((ovlimit && !inprogress) ||
++	    (dql->prev_ovlimit && all_prev_completed)) {
++		/*
++		 * Queue considered starved if:
++		 *   - The queue was over-limit in the last interval,
++		 *     and there is no more data in the queue.
++		 *  OR
++		 *   - The queue was over-limit in the previous interval and
++		 *     when enqueuing it was possible that all queued data
++		 *     had been consumed.  This covers the case when queue
++		 *     may have becomes starved between completion processing
++		 *     running and next time enqueue was scheduled.
++		 *
++		 *     When queue is starved increase the limit by the amount
++		 *     of bytes both sent and completed in the last interval,
++		 *     plus any previous over-limit.
++		 */
++		limit += POSDIFF(completed, dql->prev_num_queued) +
++		     dql->prev_ovlimit;
++		dql->slack_start_time = jiffies;
++		dql->lowest_slack = UINT_MAX;
++	} else if (inprogress && prev_inprogress && !all_prev_completed) {
++		/*
++		 * Queue was not starved, check if the limit can be decreased.
++		 * A decrease is only considered if the queue has been busy in
++		 * the whole interval (the check above).
++		 *
++		 * If there is slack, the amount of execess data queued above
++		 * the the amount needed to prevent starvation, the queue limit
++		 * can be decreased.  To avoid hysteresis we consider the
++		 * minimum amount of slack found over several iterations of the
++		 * completion routine.
++		 */
++		unsigned int slack, slack_last_objs;
++
++		/*
++		 * Slack is the maximum of
++		 *   - The queue limit plus previous over-limit minus twice
++		 *     the number of objects completed.  Note that two times
++		 *     number of completed bytes is a basis for an upper bound
++		 *     of the limit.
++		 *   - Portion of objects in the last queuing operation that
++		 *     was not part of non-zero previous over-limit.  That is
++		 *     "round down" by non-overlimit portion of the last
++		 *     queueing operation.
++		 */
++		slack = POSDIFF(limit + dql->prev_ovlimit,
++		    2 * (completed - dql->num_completed));
++		slack_last_objs = dql->prev_ovlimit ?
++		    POSDIFF(dql->prev_last_obj_cnt, dql->prev_ovlimit) : 0;
++
++		slack = max(slack, slack_last_objs);
++
++		if (slack < dql->lowest_slack)
++			dql->lowest_slack = slack;
++
++		if (time_after(jiffies,
++			       dql->slack_start_time + dql->slack_hold_time)) {
++			limit = POSDIFF(limit, dql->lowest_slack);
++			dql->slack_start_time = jiffies;
++			dql->lowest_slack = UINT_MAX;
++		}
++	}
++
++	/* Enforce bounds on limit */
++	limit = clamp(limit, dql->min_limit, dql->max_limit);
++
++	if (limit != dql->limit) {
++		dql->limit = limit;
++		ovlimit = 0;
++	}
++
++	dql->adj_limit = limit + completed;
++	dql->prev_ovlimit = ovlimit;
++	dql->prev_last_obj_cnt = dql->last_obj_cnt;
++	dql->num_completed = completed;
++	dql->prev_num_queued = dql->num_queued;
++}
++EXPORT_SYMBOL(dql_completed);
++
++void dql_reset(struct dql *dql)
++{
++	/* Reset all dynamic values */
++	dql->limit = 0;
++	dql->num_queued = 0;
++	dql->num_completed = 0;
++	dql->last_obj_cnt = 0;
++	dql->prev_num_queued = 0;
++	dql->prev_last_obj_cnt = 0;
++	dql->prev_ovlimit = 0;
++	dql->lowest_slack = UINT_MAX;
++	dql->slack_start_time = jiffies;
++}
++EXPORT_SYMBOL(dql_reset);
++
++int dql_init(struct dql *dql, unsigned hold_time)
++{
++	dql->max_limit = DQL_MAX_LIMIT;
++	dql->min_limit = 0;
++	dql->slack_hold_time = hold_time;
++	dql_reset(dql);
++	return 0;
++}
++EXPORT_SYMBOL(dql_init);

Added: dists/sid/linux/debian/patches/features/all/bql/dql-fix-undefined-jiffies.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/dql-fix-undefined-jiffies.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,28 @@
+From: Tom Herbert <therbert at google.com>
+Date: Sun, 11 Mar 2012 19:59:43 -0700
+Subject: dql: Fix undefined jiffies
+
+commit 930c514f6960454a5082f7e533bd2867df6fe9cb upstream.
+
+In some configurations, jiffies may be undefined in
+lib/dynamic_queue_limits.c.  Adding include of jiffies.h to avoid
+this.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ lib/dynamic_queue_limits.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/lib/dynamic_queue_limits.c b/lib/dynamic_queue_limits.c
+index 3d1bdcd..6ab4587 100644
+--- a/lib/dynamic_queue_limits.c
++++ b/lib/dynamic_queue_limits.c
+@@ -7,6 +7,7 @@
+ #include <linux/types.h>
+ #include <linux/ctype.h>
+ #include <linux/kernel.h>
++#include <linux/jiffies.h>
+ #include <linux/dynamic_queue_limits.h>
+ 
+ #define POSDIFF(A, B) ((A) > (B) ? (A) - (B) : 0)

Added: dists/sid/linux/debian/patches/features/all/bql/e1000e-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/e1000e-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,63 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:16 +0000
+Subject: e1000e: Support for byte queue limits
+
+commit 3f0cfa3bc11e7f00c9994e0f469cbc0e7da7b00c upstream.
+
+Changes to e1000e to use byte queue limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/intel/e1000e/netdev.c |    9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
+index a5bd7a3..c6e9763 100644
+--- a/drivers/net/ethernet/intel/e1000e/netdev.c
++++ b/drivers/net/ethernet/intel/e1000e/netdev.c
+@@ -1079,6 +1079,7 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
+ 	unsigned int i, eop;
+ 	unsigned int count = 0;
+ 	unsigned int total_tx_bytes = 0, total_tx_packets = 0;
++	unsigned int bytes_compl = 0, pkts_compl = 0;
+ 
+ 	i = tx_ring->next_to_clean;
+ 	eop = tx_ring->buffer_info[i].next_to_watch;
+@@ -1096,6 +1097,10 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
+ 			if (cleaned) {
+ 				total_tx_packets += buffer_info->segs;
+ 				total_tx_bytes += buffer_info->bytecount;
++				if (buffer_info->skb) {
++					bytes_compl += buffer_info->skb->len;
++					pkts_compl++;
++				}
+ 			}
+ 
+ 			e1000_put_txbuf(adapter, buffer_info);
+@@ -1114,6 +1119,8 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
+ 
+ 	tx_ring->next_to_clean = i;
+ 
++	netdev_completed_queue(netdev, pkts_compl, bytes_compl);
++
+ #define TX_WAKE_THRESHOLD 32
+ 	if (count && netif_carrier_ok(netdev) &&
+ 	    e1000_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD) {
+@@ -2240,6 +2247,7 @@ static void e1000_clean_tx_ring(struct e1000_adapter *adapter)
+ 		e1000_put_txbuf(adapter, buffer_info);
+ 	}
+ 
++	netdev_reset_queue(adapter->netdev);
+ 	size = sizeof(struct e1000_buffer) * tx_ring->count;
+ 	memset(tx_ring->buffer_info, 0, size);
+ 
+@@ -5027,6 +5035,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
+ 	/* if count is 0 then mapping error has occurred */
+ 	count = e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss);
+ 	if (count) {
++		netdev_sent_queue(netdev, skb->len);
+ 		e1000_tx_queue(adapter, tx_flags, count);
+ 		/* Make sure there is space in the ring for the next send. */
+ 		e1000_maybe_stop_tx(netdev, MAX_SKB_FRAGS + 2);

Added: dists/sid/linux/debian/patches/features/all/bql/forcedeath-fix-bql-support-for-forcedeath.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/forcedeath-fix-bql-support-for-forcedeath.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,39 @@
+From: Igor Maravic <igorm at etf.rs>
+Date: Thu, 1 Dec 2011 23:48:20 +0000
+Subject: forcedeath: Fix bql support for forcedeath
+
+commit 7505afe28c16a8d386624930a018d0052c75d687 upstream.
+
+Moved netdev_completed_queue() out of while loop in function nv_tx_done_optimized().
+Because this function was in while loop,
+BUG_ON(count > dql->num_queued - dql->num_completed)
+was hit in dql_completed().
+
+Signed-off-by: Igor Maravic <igorm at etf.rs>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/nvidia/forcedeth.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
+index 5245dac..4c4e7f4 100644
+--- a/drivers/net/ethernet/nvidia/forcedeth.c
++++ b/drivers/net/ethernet/nvidia/forcedeth.c
+@@ -2561,13 +2561,14 @@ static int nv_tx_done_optimized(struct net_device *dev, int limit)
+ 				nv_tx_flip_ownership(dev);
+ 		}
+ 
+-		netdev_completed_queue(np->dev, tx_work, bytes_cleaned);
+-
+ 		if (unlikely(np->get_tx.ex++ == np->last_tx.ex))
+ 			np->get_tx.ex = np->first_tx.ex;
+ 		if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx))
+ 			np->get_tx_ctx = np->first_tx_ctx;
+ 	}
++
++	netdev_completed_queue(np->dev, tx_work, bytes_cleaned);
++
+ 	if (unlikely((np->tx_stop == 1) && (np->get_tx.ex != orig_get_tx))) {
+ 		np->tx_stop = 0;
+ 		netif_wake_queue(dev);

Added: dists/sid/linux/debian/patches/features/all/bql/forcedeth-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/forcedeth-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,105 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:23 +0000
+Subject: forcedeth: Support for byte queue limits
+
+commit b8bfca9439d4ed03446bc9a3fdaef81b364d32dd upstream.
+
+Changes to forcedeth to use byte queue limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/nvidia/forcedeth.c |   18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+--- a/drivers/net/ethernet/nvidia/forcedeth.c
++++ b/drivers/net/ethernet/nvidia/forcedeth.c
+@@ -1849,6 +1849,7 @@
+ 		np->last_tx.ex = &np->tx_ring.ex[np->tx_ring_size-1];
+ 	np->get_tx_ctx = np->put_tx_ctx = np->first_tx_ctx = np->tx_skb;
+ 	np->last_tx_ctx = &np->tx_skb[np->tx_ring_size-1];
++	netdev_reset_queue(np->dev);
+ 	np->tx_pkts_in_progress = 0;
+ 	np->tx_change_owner = NULL;
+ 	np->tx_end_flip = NULL;
+@@ -2194,6 +2195,9 @@
+ 
+ 	/* set tx flags */
+ 	start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
++
++	netdev_sent_queue(np->dev, skb->len);
++
+ 	np->put_tx.orig = put_tx;
+ 
+ 	spin_unlock_irqrestore(&np->lock, flags);
+@@ -2338,6 +2342,9 @@
+ 
+ 	/* set tx flags */
+ 	start_tx->flaglen |= cpu_to_le32(tx_flags | tx_flags_extra);
++
++	netdev_sent_queue(np->dev, skb->len);
++
+ 	np->put_tx.ex = put_tx;
+ 
+ 	spin_unlock_irqrestore(&np->lock, flags);
+@@ -2375,6 +2382,7 @@
+ 	u32 flags;
+ 	int tx_work = 0;
+ 	struct ring_desc *orig_get_tx = np->get_tx.orig;
++	unsigned int bytes_compl = 0;
+ 
+ 	while ((np->get_tx.orig != np->put_tx.orig) &&
+ 	       !((flags = le32_to_cpu(np->get_tx.orig->flaglen)) & NV_TX_VALID) &&
+@@ -2391,6 +2399,7 @@
+ 					dev->stats.tx_packets++;
+ 					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ 				}
++				bytes_compl += np->get_tx_ctx->skb->len;
+ 				dev_kfree_skb_any(np->get_tx_ctx->skb);
+ 				np->get_tx_ctx->skb = NULL;
+ 				tx_work++;
+@@ -2404,6 +2413,7 @@
+ 					dev->stats.tx_packets++;
+ 					dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ 				}
++				bytes_compl += np->get_tx_ctx->skb->len;
+ 				dev_kfree_skb_any(np->get_tx_ctx->skb);
+ 				np->get_tx_ctx->skb = NULL;
+ 				tx_work++;
+@@ -2414,6 +2424,9 @@
+ 		if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx))
+ 			np->get_tx_ctx = np->first_tx_ctx;
+ 	}
++
++	netdev_completed_queue(np->dev, tx_work, bytes_compl);
++
+ 	if (unlikely((np->tx_stop == 1) && (np->get_tx.orig != orig_get_tx))) {
+ 		np->tx_stop = 0;
+ 		netif_wake_queue(dev);
+@@ -2427,6 +2440,7 @@
+ 	u32 flags;
+ 	int tx_work = 0;
+ 	struct ring_desc_ex *orig_get_tx = np->get_tx.ex;
++	unsigned long bytes_cleaned = 0;
+ 
+ 	while ((np->get_tx.ex != np->put_tx.ex) &&
+ 	       !((flags = le32_to_cpu(np->get_tx.ex->flaglen)) & NV_TX2_VALID) &&
+@@ -2447,6 +2461,7 @@
+ 				dev->stats.tx_bytes += np->get_tx_ctx->skb->len;
+ 			}
+ 
++			bytes_cleaned += np->get_tx_ctx->skb->len;
+ 			dev_kfree_skb_any(np->get_tx_ctx->skb);
+ 			np->get_tx_ctx->skb = NULL;
+ 			tx_work++;
+@@ -2454,6 +2469,9 @@
+ 			if (np->tx_limit)
+ 				nv_tx_flip_ownership(dev);
+ 		}
++
++		netdev_completed_queue(np->dev, tx_work, bytes_cleaned);
++
+ 		if (unlikely(np->get_tx.ex++ == np->last_tx.ex))
+ 			np->get_tx.ex = np->first_tx.ex;
+ 		if (unlikely(np->get_tx_ctx++ == np->last_tx_ctx))

Added: dists/sid/linux/debian/patches/features/all/bql/igb-add-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/igb-add-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,65 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Wed, 4 Jan 2012 20:23:36 +0000
+Subject: igb: Add support for byte queue limits.
+
+commit bdbc063129e811264cd6c311d8c2d9b95de01231 upstream.
+
+This adds support for byte queue limits (BQL)
+
+Since this driver collects bytes count in 'bytecount' field, use it also
+in igb_tx_map()
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+CC: Alexander Duyck <alexander.h.duyck at intel.com>
+Tested-by: Aaron Brown <aaron.f.brown at intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/intel/igb/igb.h      |    5 +++++
+ drivers/net/ethernet/intel/igb/igb_main.c |    5 +++++
+ 2 files changed, 10 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
+index c69feeb..3d12e67 100644
+--- a/drivers/net/ethernet/intel/igb/igb.h
++++ b/drivers/net/ethernet/intel/igb/igb.h
+@@ -447,4 +447,9 @@ static inline s32 igb_get_phy_info(struct e1000_hw *hw)
+ 	return 0;
+ }
+ 
++static inline struct netdev_queue *txring_txq(const struct igb_ring *tx_ring)
++{
++	return netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
++}
++
+ #endif /* _IGB_H_ */
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index 89d576c..dcc68cc 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -3201,6 +3201,7 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
+ 		buffer_info = &tx_ring->tx_buffer_info[i];
+ 		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
+ 	}
++	netdev_tx_reset_queue(txring_txq(tx_ring));
+ 
+ 	size = sizeof(struct igb_tx_buffer) * tx_ring->count;
+ 	memset(tx_ring->tx_buffer_info, 0, size);
+@@ -4238,6 +4239,8 @@ static void igb_tx_map(struct igb_ring *tx_ring,
+ 		frag++;
+ 	}
+ 
++	netdev_tx_sent_queue(txring_txq(tx_ring), first->bytecount);
++
+ 	/* write last descriptor with RS and EOP bits */
+ 	cmd_type |= cpu_to_le32(size) | cpu_to_le32(IGB_TXD_DCMD);
+ 	tx_desc->read.cmd_type_len = cmd_type;
+@@ -5777,6 +5780,8 @@ static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)
+ 		}
+ 	}
+ 
++	netdev_tx_completed_queue(txring_txq(tx_ring),
++				  total_packets, total_bytes);
+ 	i += tx_ring->count;
+ 	tx_ring->next_to_clean = i;
+ 	u64_stats_update_begin(&tx_ring->tx_syncp);

Added: dists/sid/linux/debian/patches/features/all/bql/igb-fix-ethtool-offline-test.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/igb-fix-ethtool-offline-test.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,56 @@
+From: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+Date: Thu, 19 Jan 2012 18:31:34 +0000
+Subject: igb: fix ethtool offline test
+
+commit 51a76c30929cc8b7d541f51e634f146e54ea9bb7 upstream.
+
+A bug was introduced with the following patch:
+
+  Commmit bdbc063129e811264cd6c311d8c2d9b95de01231
+  Author: Eric Dumazet <eric.dumazet at gmail.com>
+  igb: Add support for byte queue limits.
+
+The ethtool offline tests will cause a perpetual link flap, this
+is because the tests also need to account for byte queue limits (BQL).
+
+CC: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+Signed-off-by: John Fastabend <john.r.fastabend at intel.com>
+Tested-by:  Jeff Pieper  <jeffrey.e.pieper at intel.com>
+---
+ drivers/net/ethernet/intel/igb/igb_ethtool.c |    7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+index aa399a8..e10821a 100644
+--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
++++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
+@@ -1577,7 +1577,9 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring,
+ 	union e1000_adv_rx_desc *rx_desc;
+ 	struct igb_rx_buffer *rx_buffer_info;
+ 	struct igb_tx_buffer *tx_buffer_info;
++	struct netdev_queue *txq;
+ 	u16 rx_ntc, tx_ntc, count = 0;
++	unsigned int total_bytes = 0, total_packets = 0;
+ 
+ 	/* initialize next to clean and descriptor values */
+ 	rx_ntc = rx_ring->next_to_clean;
+@@ -1601,6 +1603,8 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring,
+ 
+ 		/* unmap buffer on tx side */
+ 		tx_buffer_info = &tx_ring->tx_buffer_info[tx_ntc];
++		total_bytes += tx_buffer_info->bytecount;
++		total_packets += tx_buffer_info->gso_segs;
+ 		igb_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
+ 
+ 		/* increment rx/tx next to clean counters */
+@@ -1615,6 +1619,9 @@ static int igb_clean_test_rings(struct igb_ring *rx_ring,
+ 		rx_desc = IGB_RX_DESC(rx_ring, rx_ntc);
+ 	}
+ 
++	txq = netdev_get_tx_queue(tx_ring->netdev, tx_ring->queue_index);
++	netdev_tx_completed_queue(txq, total_packets, total_bytes);
++
+ 	/* re-map buffers to ring, store next to clean values */
+ 	igb_alloc_rx_buffers(rx_ring, count);
+ 	rx_ring->next_to_clean = rx_ntc;

Added: dists/sid/linux/debian/patches/features/all/bql/igb-ixgbe-netdev_tx_reset_queue-incorrectly-called-from-tx-init.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/igb-ixgbe-netdev_tx_reset_queue-incorrectly-called-from-tx-init.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,79 @@
+From: John Fastabend <john.r.fastabend at intel.com>
+Date: Mon, 23 Apr 2012 12:22:39 +0000
+Subject: igb, ixgbe: netdev_tx_reset_queue incorrectly called from tx init
+ path
+
+commit dad8a3b3eaa0c2ca25368a0b9f65edca84e27a40 upstream.
+
+igb and ixgbe incorrectly call netdev_tx_reset_queue() from
+i{gb|xgbe}_clean_tx_ring() this sort of works in most cases except
+when the number of real tx queues changes. When the number of real
+tx queues changes netdev_tx_reset_queue() only gets called on the
+new number of queues so when we reduce the number of queues we risk
+triggering the watchdog timer and repeated device resets.
+
+So this is not only a cosmetic issue but causes real bugs. For
+example enabling/disabling DCB or FCoE in ixgbe will trigger this.
+
+CC: Alexander Duyck <alexander.h.duyck at intel.com>
+Signed-off-by: John Fastabend <john.r.fastabend at intel.com>
+Tested-by: John Bishop <johnx.bishop at intel.com>
+Tested-by: Aaron Brown <aaron.f.brown at intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c        |    4 ++--
+ drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c |    2 ++
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c    |    4 ++--
+ 3 files changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -2711,8 +2711,6 @@
+ 
+ 	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+ 	wr32(E1000_TXDCTL(reg_idx), txdctl);
+-
+-	netdev_tx_reset_queue(txring_txq(ring));
+ }
+ 
+ /**
+@@ -3206,6 +3204,8 @@
+ 		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
+ 	}
+ 
++	netdev_tx_reset_queue(txring_txq(tx_ring));
++
+ 	size = sizeof(struct igb_tx_buffer) * tx_ring->count;
+ 	memset(tx_ring->tx_buffer_info, 0, size);
+ 
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+@@ -1764,6 +1764,8 @@
+ 		staterr = le32_to_cpu(rx_desc->wb.upper.status_error);
+ 	}
+ 
++	netdev_tx_reset_queue(txring_txq(tx_ring));
++
+ 	/* re-map buffers to ring, store next to clean values */
+ 	ixgbe_alloc_rx_buffers(rx_ring, count);
+ 	rx_ring->next_to_clean = rx_ntc;
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -2411,8 +2411,6 @@
+ 	/* enable queue */
+ 	IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl);
+ 
+-	netdev_tx_reset_queue(txring_txq(ring));
+-
+ 	/* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ 	if (hw->mac.type == ixgbe_mac_82598EB &&
+ 	    !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+@@ -3930,6 +3928,8 @@
+ 		ixgbe_unmap_and_free_tx_resource(tx_ring, tx_buffer_info);
+ 	}
+ 
++	netdev_tx_reset_queue(txring_txq(tx_ring));
++
+ 	size = sizeof(struct ixgbe_tx_buffer) * tx_ring->count;
+ 	memset(tx_ring->tx_buffer_info, 0, size);
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/ixgbe-add-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/ixgbe-add-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,59 @@
+From: Alexander Duyck <alexander.h.duyck at intel.com>
+Date: Tue, 7 Feb 2012 08:14:33 +0000
+Subject: ixgbe: add support for byte queue limits
+
+commit b2d96e0ac07cf4929c6b0eb13121672048368117 upstream.
+
+This adds support for byte queue limits (BQL).
+
+Based on patch from Eric Dumazet for igb.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck at intel.com>
+Tested-by: Stephen Ko <stephen.s.ko at intel.com>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe.h      |    5 +++++
+ drivers/net/ethernet/intel/ixgbe/ixgbe_main.c |    7 +++++++
+ 2 files changed, 12 insertions(+)
+
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+@@ -629,4 +629,9 @@
+ extern int ixgbe_fcoe_get_wwn(struct net_device *netdev, u64 *wwn, int type);
+ #endif /* IXGBE_FCOE */
+ 
++static inline struct netdev_queue *txring_txq(const struct ixgbe_ring *ring)
++{
++	return netdev_get_tx_queue(ring->netdev, ring->queue_index);
++}
++
+ #endif /* _IXGBE_H_ */
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+@@ -832,6 +832,9 @@
+ 		return true;
+ 	}
+ 
++	netdev_tx_completed_queue(txring_txq(tx_ring),
++				  total_packets, total_bytes);
++
+ #define TX_WAKE_THRESHOLD (DESC_NEEDED * 2)
+ 	if (unlikely(total_packets && netif_carrier_ok(tx_ring->netdev) &&
+ 		     (ixgbe_desc_unused(tx_ring) >= TX_WAKE_THRESHOLD))) {
+@@ -2408,6 +2411,8 @@
+ 	/* enable queue */
+ 	IXGBE_WRITE_REG(hw, IXGBE_TXDCTL(reg_idx), txdctl);
+ 
++	netdev_tx_reset_queue(txring_txq(ring));
++
+ 	/* TXDCTL.EN will return 0 on 82598 if link is down, so skip it */
+ 	if (hw->mac.type == ixgbe_mac_82598EB &&
+ 	    !(IXGBE_READ_REG(hw, IXGBE_LINKS) & IXGBE_LINKS_UP))
+@@ -6581,6 +6586,8 @@
+ 	tx_buffer_info->gso_segs = gso_segs;
+ 	tx_buffer_info->skb = skb;
+ 
++	netdev_tx_sent_queue(txring_txq(tx_ring), tx_buffer_info->bytecount);
++
+ 	/* set the timestamp */
+ 	first->time_stamp = jiffies;
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/net-add-netdev-interfaces-for-recording-sends-comp.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/net-add-netdev-interfaces-for-recording-sends-comp.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,56 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:32:52 +0000
+Subject: net: Add netdev interfaces for recording sends/comp
+
+commit c5d67bd78c5dc540e3461c36fb3d389fbe0de4c3 upstream.
+
+Add interfaces for drivers to call for recording number of packets and
+bytes at send time and transmit completion.  Also, added a function to
+"reset" a queue.  These will be used by Byte Queue Limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ include/linux/netdevice.h |   28 ++++++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index d19f932..9b24cc7 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1859,6 +1859,34 @@ static inline int netif_xmit_frozen_or_stopped(const struct netdev_queue *dev_qu
+ 	return dev_queue->state & QUEUE_STATE_ANY_XOFF_OR_FROZEN;
+ }
+ 
++static inline void netdev_tx_sent_queue(struct netdev_queue *dev_queue,
++					unsigned int bytes)
++{
++}
++
++static inline void netdev_sent_queue(struct net_device *dev, unsigned int bytes)
++{
++	netdev_tx_sent_queue(netdev_get_tx_queue(dev, 0), bytes);
++}
++
++static inline void netdev_tx_completed_queue(struct netdev_queue *dev_queue,
++					     unsigned pkts, unsigned bytes)
++{
++}
++
++static inline void netdev_completed_queue(struct net_device *dev,
++					  unsigned pkts, unsigned bytes)
++{
++	netdev_tx_completed_queue(netdev_get_tx_queue(dev, 0), pkts, bytes);
++}
++
++static inline void netdev_tx_reset_queue(struct netdev_queue *q)
++{
++}
++
++static inline void netdev_reset_queue(struct net_device *dev_queue)
++{
++	netdev_tx_reset_queue(netdev_get_tx_queue(dev_queue, 0));
+ }
+ 
+ /**

Added: dists/sid/linux/debian/patches/features/all/bql/net-add-queue-state-xoff-flag-for-stack.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/net-add-queue-state-xoff-flag-for-stack.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,279 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:32:44 +0000
+Subject: net: Add queue state xoff flag for stack
+
+commit 7346649826382b769cfadf4a2fe8a84d060c55e9 upstream.
+
+Create separate queue state flags so that either the stack or drivers
+can turn on XOFF.  Added a set of functions used in the stack to determine
+if a queue is really stopped (either by stack or driver)
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ include/linux/netdevice.h |   41 ++++++++++++++++++++++++++++++-----------
+ net/core/dev.c            |    4 ++--
+ net/core/netpoll.c        |    4 ++--
+ net/core/pktgen.c         |    2 +-
+ net/sched/sch_generic.c   |    8 ++++----
+ net/sched/sch_multiq.c    |    6 ++++--
+ net/sched/sch_teql.c      |    6 +++---
+ 7 files changed, 46 insertions(+), 25 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index ac9a4b9..d19f932 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -517,11 +517,23 @@ static inline void napi_synchronize(const struct napi_struct *n)
+ #endif
+ 
+ enum netdev_queue_state_t {
+-	__QUEUE_STATE_XOFF,
++	__QUEUE_STATE_DRV_XOFF,
++	__QUEUE_STATE_STACK_XOFF,
+ 	__QUEUE_STATE_FROZEN,
+-#define QUEUE_STATE_XOFF_OR_FROZEN ((1 << __QUEUE_STATE_XOFF)		| \
+-				    (1 << __QUEUE_STATE_FROZEN))
++#define QUEUE_STATE_ANY_XOFF ((1 << __QUEUE_STATE_DRV_XOFF)		| \
++			      (1 << __QUEUE_STATE_STACK_XOFF))
++#define QUEUE_STATE_ANY_XOFF_OR_FROZEN (QUEUE_STATE_ANY_XOFF		| \
++					(1 << __QUEUE_STATE_FROZEN))
+ };
++/*
++ * __QUEUE_STATE_DRV_XOFF is used by drivers to stop the transmit queue.  The
++ * netif_tx_* functions below are used to manipulate this flag.  The
++ * __QUEUE_STATE_STACK_XOFF flag is used by the stack to stop the transmit
++ * queue independently.  The netif_xmit_*stopped functions below are called
++ * to check if the queue has been stopped by the driver or stack (either
++ * of the XOFF bits are set in the state).  Drivers should not need to call
++ * netif_xmit*stopped functions, they should only be using netif_tx_*.
++ */
+ 
+ struct netdev_queue {
+ /*
+@@ -1718,7 +1730,7 @@ extern void __netif_schedule(struct Qdisc *q);
+ 
+ static inline void netif_schedule_queue(struct netdev_queue *txq)
+ {
+-	if (!test_bit(__QUEUE_STATE_XOFF, &txq->state))
++	if (!(txq->state & QUEUE_STATE_ANY_XOFF))
+ 		__netif_schedule(txq->qdisc);
+ }
+ 
+@@ -1732,7 +1744,7 @@ static inline void netif_tx_schedule_all(struct net_device *dev)
+ 
+ static inline void netif_tx_start_queue(struct netdev_queue *dev_queue)
+ {
+-	clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
++	clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
+ }
+ 
+ /**
+@@ -1764,7 +1776,7 @@ static inline void netif_tx_wake_queue(struct netdev_queue *dev_queue)
+ 		return;
+ 	}
+ #endif
+-	if (test_and_clear_bit(__QUEUE_STATE_XOFF, &dev_queue->state))
++	if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state))
+ 		__netif_schedule(dev_queue->qdisc);
+ }
+ 
+@@ -1796,7 +1808,7 @@ static inline void netif_tx_stop_queue(struct netdev_queue *dev_queue)
+ 		pr_info("netif_stop_queue() cannot be called before register_netdev()\n");
+ 		return;
+ 	}
+-	set_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
++	set_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
+ }
+ 
+ /**
+@@ -1823,7 +1835,7 @@ static inline void netif_tx_stop_all_queues(struct net_device *dev)
+ 
+ static inline int netif_tx_queue_stopped(const struct netdev_queue *dev_queue)
+ {
+-	return test_bit(__QUEUE_STATE_XOFF, &dev_queue->state);
++	return test_bit(__QUEUE_STATE_DRV_XOFF, &dev_queue->state);
+ }
+ 
+ /**
+@@ -1837,9 +1849,16 @@ static inline int netif_queue_stopped(const struct net_device *dev)
+ 	return netif_tx_queue_stopped(netdev_get_tx_queue(dev, 0));
+ }
+ 
+-static inline int netif_tx_queue_frozen_or_stopped(const struct netdev_queue *dev_queue)
++static inline int netif_xmit_stopped(const struct netdev_queue *dev_queue)
+ {
+-	return dev_queue->state & QUEUE_STATE_XOFF_OR_FROZEN;
++	return dev_queue->state & QUEUE_STATE_ANY_XOFF;
++}
++
++static inline int netif_xmit_frozen_or_stopped(const struct netdev_queue *dev_queue)
++{
++	return dev_queue->state & QUEUE_STATE_ANY_XOFF_OR_FROZEN;
++}
++
+ }
+ 
+ /**
+@@ -1926,7 +1945,7 @@ static inline void netif_wake_subqueue(struct net_device *dev, u16 queue_index)
+ 	if (netpoll_trap())
+ 		return;
+ #endif
+-	if (test_and_clear_bit(__QUEUE_STATE_XOFF, &txq->state))
++	if (test_and_clear_bit(__QUEUE_STATE_DRV_XOFF, &txq->state))
+ 		__netif_schedule(txq->qdisc);
+ }
+ 
+diff --git a/net/core/dev.c b/net/core/dev.c
+index c7ef6c5..cb8f753 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -2270,7 +2270,7 @@ gso:
+ 			return rc;
+ 		}
+ 		txq_trans_update(txq);
+-		if (unlikely(netif_tx_queue_stopped(txq) && skb->next))
++		if (unlikely(netif_xmit_stopped(txq) && skb->next))
+ 			return NETDEV_TX_BUSY;
+ 	} while (skb->next);
+ 
+@@ -2558,7 +2558,7 @@ int dev_queue_xmit(struct sk_buff *skb)
+ 
+ 			HARD_TX_LOCK(dev, txq, cpu);
+ 
+-			if (!netif_tx_queue_stopped(txq)) {
++			if (!netif_xmit_stopped(txq)) {
+ 				__this_cpu_inc(xmit_recursion);
+ 				rc = dev_hard_start_xmit(skb, dev, txq);
+ 				__this_cpu_dec(xmit_recursion);
+diff --git a/net/core/netpoll.c b/net/core/netpoll.c
+index 1a7d8e2..0d38808 100644
+--- a/net/core/netpoll.c
++++ b/net/core/netpoll.c
+@@ -76,7 +76,7 @@ static void queue_process(struct work_struct *work)
+ 
+ 		local_irq_save(flags);
+ 		__netif_tx_lock(txq, smp_processor_id());
+-		if (netif_tx_queue_frozen_or_stopped(txq) ||
++		if (netif_xmit_frozen_or_stopped(txq) ||
+ 		    ops->ndo_start_xmit(skb, dev) != NETDEV_TX_OK) {
+ 			skb_queue_head(&npinfo->txq, skb);
+ 			__netif_tx_unlock(txq);
+@@ -317,7 +317,7 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb,
+ 		for (tries = jiffies_to_usecs(1)/USEC_PER_POLL;
+ 		     tries > 0; --tries) {
+ 			if (__netif_tx_trylock(txq)) {
+-				if (!netif_tx_queue_stopped(txq)) {
++				if (!netif_xmit_stopped(txq)) {
+ 					status = ops->ndo_start_xmit(skb, dev);
+ 					if (status == NETDEV_TX_OK)
+ 						txq_trans_update(txq);
+diff --git a/net/core/pktgen.c b/net/core/pktgen.c
+index aa53a35..449fe0f 100644
+--- a/net/core/pktgen.c
++++ b/net/core/pktgen.c
+@@ -3342,7 +3342,7 @@ static void pktgen_xmit(struct pktgen_dev *pkt_dev)
+ 
+ 	__netif_tx_lock_bh(txq);
+ 
+-	if (unlikely(netif_tx_queue_frozen_or_stopped(txq))) {
++	if (unlikely(netif_xmit_frozen_or_stopped(txq))) {
+ 		ret = NETDEV_TX_BUSY;
+ 		pkt_dev->last_ok = 0;
+ 		goto unlock;
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 79ac145..67fc573 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -60,7 +60,7 @@ static inline struct sk_buff *dequeue_skb(struct Qdisc *q)
+ 
+ 		/* check the reason of requeuing without tx lock first */
+ 		txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb));
+-		if (!netif_tx_queue_frozen_or_stopped(txq)) {
++		if (!netif_xmit_frozen_or_stopped(txq)) {
+ 			q->gso_skb = NULL;
+ 			q->q.qlen--;
+ 		} else
+@@ -121,7 +121,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+ 	spin_unlock(root_lock);
+ 
+ 	HARD_TX_LOCK(dev, txq, smp_processor_id());
+-	if (!netif_tx_queue_frozen_or_stopped(txq))
++	if (!netif_xmit_frozen_or_stopped(txq))
+ 		ret = dev_hard_start_xmit(skb, dev, txq);
+ 
+ 	HARD_TX_UNLOCK(dev, txq);
+@@ -143,7 +143,7 @@ int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
+ 		ret = dev_requeue_skb(skb, q);
+ 	}
+ 
+-	if (ret && netif_tx_queue_frozen_or_stopped(txq))
++	if (ret && netif_xmit_frozen_or_stopped(txq))
+ 		ret = 0;
+ 
+ 	return ret;
+@@ -242,7 +242,7 @@ static void dev_watchdog(unsigned long arg)
+ 				 * old device drivers set dev->trans_start
+ 				 */
+ 				trans_start = txq->trans_start ? : dev->trans_start;
+-				if (netif_tx_queue_stopped(txq) &&
++				if (netif_xmit_stopped(txq) &&
+ 				    time_after(jiffies, (trans_start +
+ 							 dev->watchdog_timeo))) {
+ 					some_queue_timedout = 1;
+diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
+index edc1950..49131d7 100644
+--- a/net/sched/sch_multiq.c
++++ b/net/sched/sch_multiq.c
+@@ -107,7 +107,8 @@ static struct sk_buff *multiq_dequeue(struct Qdisc *sch)
+ 		/* Check that target subqueue is available before
+ 		 * pulling an skb to avoid head-of-line blocking.
+ 		 */
+-		if (!__netif_subqueue_stopped(qdisc_dev(sch), q->curband)) {
++		if (!netif_xmit_stopped(
++		    netdev_get_tx_queue(qdisc_dev(sch), q->curband))) {
+ 			qdisc = q->queues[q->curband];
+ 			skb = qdisc->dequeue(qdisc);
+ 			if (skb) {
+@@ -138,7 +139,8 @@ static struct sk_buff *multiq_peek(struct Qdisc *sch)
+ 		/* Check that target subqueue is available before
+ 		 * pulling an skb to avoid head-of-line blocking.
+ 		 */
+-		if (!__netif_subqueue_stopped(qdisc_dev(sch), curband)) {
++		if (!netif_xmit_stopped(
++		    netdev_get_tx_queue(qdisc_dev(sch), curband))) {
+ 			qdisc = q->queues[curband];
+ 			skb = qdisc->ops->peek(qdisc);
+ 			if (skb)
+diff --git a/net/sched/sch_teql.c b/net/sched/sch_teql.c
+index a3b7120..283bfe3 100644
+--- a/net/sched/sch_teql.c
++++ b/net/sched/sch_teql.c
+@@ -301,7 +301,7 @@ restart:
+ 
+ 		if (slave_txq->qdisc_sleeping != q)
+ 			continue;
+-		if (__netif_subqueue_stopped(slave, subq) ||
++		if (netif_xmit_stopped(netdev_get_tx_queue(slave, subq)) ||
+ 		    !netif_running(slave)) {
+ 			busy = 1;
+ 			continue;
+@@ -312,7 +312,7 @@ restart:
+ 			if (__netif_tx_trylock(slave_txq)) {
+ 				unsigned int length = qdisc_pkt_len(skb);
+ 
+-				if (!netif_tx_queue_frozen_or_stopped(slave_txq) &&
++				if (!netif_xmit_frozen_or_stopped(slave_txq) &&
+ 				    slave_ops->ndo_start_xmit(skb, slave) == NETDEV_TX_OK) {
+ 					txq_trans_update(slave_txq);
+ 					__netif_tx_unlock(slave_txq);
+@@ -324,7 +324,7 @@ restart:
+ 				}
+ 				__netif_tx_unlock(slave_txq);
+ 			}
+-			if (netif_queue_stopped(dev))
++			if (netif_xmit_stopped(netdev_get_tx_queue(dev, 0)))
+ 				busy = 1;
+ 			break;
+ 		case 1:

Added: dists/sid/linux/debian/patches/features/all/bql/net-fix-issue-with-netdev_tx_reset_queue-not-resetting-queue-from.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/net-fix-issue-with-netdev_tx_reset_queue-not-resetting-queue-from.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,58 @@
+From: Alexander Duyck <alexander.h.duyck at intel.com>
+Date: Tue, 7 Feb 2012 02:29:01 +0000
+Subject: net: Fix issue with netdev_tx_reset_queue not resetting queue from
+ XOFF state
+
+commit 5c4903549c05bbb373479e0ce2992573c120654a upstream.
+
+We are seeing dev_watchdog hangs on several drivers.  I suspect this is due
+to the __QUEUE_STATE_STACK_XOFF bit being set prior to a reset for link
+change, and then not being cleared by netdev_tx_reset_queue.  This change
+corrects that.
+
+In addition we were seeing dev_watchdog hangs on igb after running the
+ethtool tests.  We found this to be due to the fact that the ethtool test
+runs the same logic as ndo_start_xmit, but we were never clearing the XOFF
+flag since the loopback test in ethtool does not do byte queue accounting.
+
+Signed-off-by: Alexander Duyck <alexander.h.duyck at intel.com>
+Tested-by: Stephen Ko <stephen.s.ko at intel.com>
+Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
+---
+ drivers/net/ethernet/intel/igb/igb_main.c |    3 ++-
+ include/linux/netdevice.h                 |    1 +
+ 2 files changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
+index fda8247..e96cef8 100644
+--- a/drivers/net/ethernet/intel/igb/igb_main.c
++++ b/drivers/net/ethernet/intel/igb/igb_main.c
+@@ -2752,6 +2752,8 @@ void igb_configure_tx_ring(struct igb_adapter *adapter,
+ 
+ 	txdctl |= E1000_TXDCTL_QUEUE_ENABLE;
+ 	wr32(E1000_TXDCTL(reg_idx), txdctl);
++
++	netdev_tx_reset_queue(txring_txq(ring));
+ }
+ 
+ /**
+@@ -3244,7 +3246,6 @@ static void igb_clean_tx_ring(struct igb_ring *tx_ring)
+ 		buffer_info = &tx_ring->tx_buffer_info[i];
+ 		igb_unmap_and_free_tx_resource(tx_ring, buffer_info);
+ 	}
+-	netdev_tx_reset_queue(txring_txq(tx_ring));
+ 
+ 	size = sizeof(struct igb_tx_buffer) * tx_ring->count;
+ 	memset(tx_ring->tx_buffer_info, 0, size);
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index b195a34..4bf314f 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -1939,6 +1939,7 @@ static inline void netdev_completed_queue(struct net_device *dev,
+ static inline void netdev_tx_reset_queue(struct netdev_queue *q)
+ {
+ #ifdef CONFIG_BQL
++	clear_bit(__QUEUE_STATE_STACK_XOFF, &q->state);
+ 	dql_reset(&q->dql);
+ #endif
+ }

Added: dists/sid/linux/debian/patches/features/all/bql/net-new-counter-for-tx_timeout-errors-in-sysfs.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/net-new-counter-for-tx_timeout-errors-in-sysfs.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,189 @@
+From: david decotigny <david.decotigny at google.com>
+Date: Wed, 16 Nov 2011 12:15:10 +0000
+Subject: net: new counter for tx_timeout errors in sysfs
+
+commit ccf5ff69fbbd8d877377f5786369cf5aa78a15fc upstream.
+
+This adds the /sys/class/net/DEV/queues/Q/tx_timeout attribute
+containing the total number of timeout events on the given queue. It
+is always available with CONFIG_SYSFS, independently of
+CONFIG_RPS/XPS.
+
+Credits to Stephen Hemminger for a preliminary version of this patch.
+
+Tested:
+  without CONFIG_SYSFS (compilation only)
+  with sysfs and without CONFIG_RPS & CONFIG_XPS
+  with sysfs and without CONFIG_RPS
+  with sysfs and without CONFIG_XPS
+  with defaults
+
+Signed-off-by: David Decotigny <david.decotigny at google.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ include/linux/netdevice.h |   12 ++++++++++--
+ net/core/net-sysfs.c      |   37 +++++++++++++++++++++++++++++++------
+ net/sched/sch_generic.c   |    1 +
+ 3 files changed, 42 insertions(+), 8 deletions(-)
+
+diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
+index 31da3bb..4d5698a 100644
+--- a/include/linux/netdevice.h
++++ b/include/linux/netdevice.h
+@@ -532,7 +532,7 @@ struct netdev_queue {
+ 	struct Qdisc		*qdisc;
+ 	unsigned long		state;
+ 	struct Qdisc		*qdisc_sleeping;
+-#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
++#ifdef CONFIG_SYSFS
+ 	struct kobject		kobj;
+ #endif
+ #if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
+@@ -547,6 +547,12 @@ struct netdev_queue {
+ 	 * please use this field instead of dev->trans_start
+ 	 */
+ 	unsigned long		trans_start;
++
++	/*
++	 * Number of TX timeouts for this queue
++	 * (/sys/class/net/DEV/Q/trans_timeout)
++	 */
++	unsigned long		trans_timeout;
+ } ____cacheline_aligned_in_smp;
+ 
+ static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
+@@ -1109,9 +1115,11 @@ struct net_device {
+ 
+ 	unsigned char		broadcast[MAX_ADDR_LEN];	/* hw bcast add	*/
+ 
+-#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
++#ifdef CONFIG_SYSFS
+ 	struct kset		*queues_kset;
++#endif
+ 
++#ifdef CONFIG_RPS
+ 	struct netdev_rx_queue	*_rx;
+ 
+ 	/* Number of RX queues allocated at register_netdev() time */
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index a64382f..602b141 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -780,7 +780,7 @@ net_rx_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
+ #endif
+ }
+ 
+-#ifdef CONFIG_XPS
++#ifdef CONFIG_SYSFS
+ /*
+  * netdev_queue sysfs structures and functions.
+  */
+@@ -826,6 +826,23 @@ static const struct sysfs_ops netdev_queue_sysfs_ops = {
+ 	.store = netdev_queue_attr_store,
+ };
+ 
++static ssize_t show_trans_timeout(struct netdev_queue *queue,
++				  struct netdev_queue_attribute *attribute,
++				  char *buf)
++{
++	unsigned long trans_timeout;
++
++	spin_lock_irq(&queue->_xmit_lock);
++	trans_timeout = queue->trans_timeout;
++	spin_unlock_irq(&queue->_xmit_lock);
++
++	return sprintf(buf, "%lu", trans_timeout);
++}
++
++static struct netdev_queue_attribute queue_trans_timeout =
++	__ATTR(tx_timeout, S_IRUGO, show_trans_timeout, NULL);
++
++#ifdef CONFIG_XPS
+ static inline unsigned int get_netdev_queue_index(struct netdev_queue *queue)
+ {
+ 	struct net_device *dev = queue->dev;
+@@ -1020,12 +1037,17 @@ error:
+ 
+ static struct netdev_queue_attribute xps_cpus_attribute =
+     __ATTR(xps_cpus, S_IRUGO | S_IWUSR, show_xps_map, store_xps_map);
++#endif /* CONFIG_XPS */
+ 
+ static struct attribute *netdev_queue_default_attrs[] = {
++	&queue_trans_timeout.attr,
++#ifdef CONFIG_XPS
+ 	&xps_cpus_attribute.attr,
++#endif
+ 	NULL
+ };
+ 
++#ifdef CONFIG_XPS
+ static void netdev_queue_release(struct kobject *kobj)
+ {
+ 	struct netdev_queue *queue = to_netdev_queue(kobj);
+@@ -1076,10 +1098,13 @@ static void netdev_queue_release(struct kobject *kobj)
+ 	memset(kobj, 0, sizeof(*kobj));
+ 	dev_put(queue->dev);
+ }
++#endif /* CONFIG_XPS */
+ 
+ static struct kobj_type netdev_queue_ktype = {
+ 	.sysfs_ops = &netdev_queue_sysfs_ops,
++#ifdef CONFIG_XPS
+ 	.release = netdev_queue_release,
++#endif
+ 	.default_attrs = netdev_queue_default_attrs,
+ };
+ 
+@@ -1102,12 +1127,12 @@ static int netdev_queue_add_kobject(struct net_device *net, int index)
+ 
+ 	return error;
+ }
+-#endif /* CONFIG_XPS */
++#endif /* CONFIG_SYSFS */
+ 
+ int
+ netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
+ {
+-#ifdef CONFIG_XPS
++#ifdef CONFIG_SYSFS
+ 	int i;
+ 	int error = 0;
+ 
+@@ -1125,14 +1150,14 @@ netdev_queue_update_kobjects(struct net_device *net, int old_num, int new_num)
+ 	return error;
+ #else
+ 	return 0;
+-#endif
++#endif /* CONFIG_SYSFS */
+ }
+ 
+ static int register_queue_kobjects(struct net_device *net)
+ {
+ 	int error = 0, txq = 0, rxq = 0, real_rx = 0, real_tx = 0;
+ 
+-#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
++#ifdef CONFIG_SYSFS
+ 	net->queues_kset = kset_create_and_add("queues",
+ 	    NULL, &net->dev.kobj);
+ 	if (!net->queues_kset)
+@@ -1173,7 +1198,7 @@ static void remove_queue_kobjects(struct net_device *net)
+ 
+ 	net_rx_queue_update_kobjects(net, real_rx, 0);
+ 	netdev_queue_update_kobjects(net, real_tx, 0);
+-#if defined(CONFIG_RPS) || defined(CONFIG_XPS)
++#ifdef CONFIG_SYSFS
+ 	kset_unregister(net->queues_kset);
+ #endif
+ }
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
+index 69fca27..79ac145 100644
+--- a/net/sched/sch_generic.c
++++ b/net/sched/sch_generic.c
+@@ -246,6 +246,7 @@ static void dev_watchdog(unsigned long arg)
+ 				    time_after(jiffies, (trans_start +
+ 							 dev->watchdog_timeo))) {
+ 					some_queue_timedout = 1;
++					txq->trans_timeout++;
+ 					break;
+ 				}
+ 			}

Added: dists/sid/linux/debian/patches/features/all/bql/r8169-add-byte-queue-limit-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/r8169-add-byte-queue-limit-support.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,85 @@
+From: Igor Maravic <igorm at etf.rs>
+Date: Mon, 5 Mar 2012 00:01:25 +0100
+Subject: r8169: add byte queue limit support.
+
+commit 036dafa28da1e2565a8529de2ae663c37b7a0060 upstream.
+
+Nothing fancy:
+- sent bytes count is notified in the start_xmit path right before
+  updating the owner bit in the hardware Tx descriptor (E. Dumazet)
+- avoid useless tp->dev dereferencing in start_xmit (E. Dumazet)
+
+Use of netdev_reset_queue is favored over proper accounting in
+rtl8169_tx_clear_range since the latter would need more work for the
+same result (nb: said accounting degenerates to nothing in xmit_frags).
+
+Signed-off-by: Igor Maravic <igorm at etf.rs>
+Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+[bwh: Backported to 3.2:
+ - Adjust context
+ - Don't use 64-bit stats]
+---
+--- a/drivers/net/ethernet/realtek/r8169.c
++++ b/drivers/net/ethernet/realtek/r8169.c
+@@ -5340,6 +5340,7 @@
+ {
+ 	rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
+ 	tp->cur_tx = tp->dirty_tx = 0;
++	netdev_reset_queue(tp->dev);
+ }
+ 
+ static void rtl8169_schedule_work(struct net_device *dev, work_func_t task)
+@@ -5552,6 +5553,8 @@
+ 
+ 	txd->opts2 = cpu_to_le32(opts[1]);
+ 
++	netdev_sent_queue(dev, skb->len);
++
+ 	wmb();
+ 
+ 	/* Anti gcc 2.95.3 bugware (sic) */
+@@ -5644,11 +5647,17 @@
+ 	rtl8169_schedule_work(dev, rtl8169_reinit_task);
+ }
+ 
++struct rtl_txc {
++	int packets;
++	int bytes;
++};
++
+ static void rtl8169_tx_interrupt(struct net_device *dev,
+ 				 struct rtl8169_private *tp,
+ 				 void __iomem *ioaddr)
+ {
+ 	unsigned int dirty_tx, tx_left;
++	struct rtl_txc txc = { 0, 0 };
+ 
+ 	dirty_tx = tp->dirty_tx;
+ 	smp_rmb();
+@@ -5667,15 +5676,22 @@
+ 		rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
+ 				     tp->TxDescArray + entry);
+ 		if (status & LastFrag) {
+-			dev->stats.tx_packets++;
+-			dev->stats.tx_bytes += tx_skb->skb->len;
+-			dev_kfree_skb(tx_skb->skb);
++			struct sk_buff *skb = tx_skb->skb;
++
++			txc.packets++;
++			txc.bytes += skb->len;
++			dev_kfree_skb(skb);
+ 			tx_skb->skb = NULL;
+ 		}
+ 		dirty_tx++;
+ 		tx_left--;
+ 	}
+ 
++	dev->stats.tx_packets += txc.packets;
++	dev->stats.tx_bytes += txc.bytes;
++
++	netdev_completed_queue(dev, txc.packets, txc.bytes);
++
+ 	if (tp->dirty_tx != dirty_tx) {
+ 		tp->dirty_tx = dirty_tx;
+ 		/* Sync with rtl8169_start_xmit:

Added: dists/sid/linux/debian/patches/features/all/bql/sfc-fix-race-in-efx_enqueue_skb_tso.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/sfc-fix-race-in-efx_enqueue_skb_tso.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,33 @@
+From: Eric Dumazet <eric.dumazet at gmail.com>
+Date: Wed, 30 Nov 2011 17:12:27 -0500
+Subject: sfc: fix race in efx_enqueue_skb_tso()
+
+commit 449fa023bca5b53bd924d91a27ffd34807fdeb80 upstream.
+
+As soon as skb is pushed to hardware, it can be completed and freed, so
+we should not dereference skb anymore.
+
+Signed-off-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/sfc/tx.c |    4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
+index ab4c635..e0e00b3 100644
+--- a/drivers/net/ethernet/sfc/tx.c
++++ b/drivers/net/ethernet/sfc/tx.c
+@@ -1173,11 +1173,11 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
+ 			goto mem_err;
+ 	}
+ 
++	netdev_tx_sent_queue(tx_queue->core_txq, skb->len);
++
+ 	/* Pass off to hardware */
+ 	efx_nic_push_buffers(tx_queue);
+ 
+-	netdev_tx_sent_queue(tx_queue->core_txq, skb->len);
+-
+ 	tx_queue->tso_bursts++;
+ 	return NETDEV_TX_OK;
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/sfc-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/sfc-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,121 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:43 +0000
+Subject: sfc: Support for byte queue limits
+
+commit c3940999b29ca7d6ad9b37b827a058c90fd51992 upstream.
+
+Changes to sfc to use byte queue limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/sfc/tx.c |   27 +++++++++++++++++++++------
+ 1 file changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/drivers/net/ethernet/sfc/tx.c b/drivers/net/ethernet/sfc/tx.c
+index df88c543..ab4c635 100644
+--- a/drivers/net/ethernet/sfc/tx.c
++++ b/drivers/net/ethernet/sfc/tx.c
+@@ -31,7 +31,9 @@
+ #define EFX_TXQ_THRESHOLD(_efx) ((_efx)->txq_entries / 2u)
+ 
+ static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
+-			       struct efx_tx_buffer *buffer)
++			       struct efx_tx_buffer *buffer,
++			       unsigned int *pkts_compl,
++			       unsigned int *bytes_compl)
+ {
+ 	if (buffer->unmap_len) {
+ 		struct pci_dev *pci_dev = tx_queue->efx->pci_dev;
+@@ -48,6 +50,8 @@ static void efx_dequeue_buffer(struct efx_tx_queue *tx_queue,
+ 	}
+ 
+ 	if (buffer->skb) {
++		(*pkts_compl)++;
++		(*bytes_compl) += buffer->skb->len;
+ 		dev_kfree_skb_any((struct sk_buff *) buffer->skb);
+ 		buffer->skb = NULL;
+ 		netif_vdbg(tx_queue->efx, tx_done, tx_queue->efx->net_dev,
+@@ -250,6 +254,8 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+ 	buffer->skb = skb;
+ 	buffer->continuation = false;
+ 
++	netdev_tx_sent_queue(tx_queue->core_txq, skb->len);
++
+ 	/* Pass off to hardware */
+ 	efx_nic_push_buffers(tx_queue);
+ 
+@@ -267,10 +273,11 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+  unwind:
+ 	/* Work backwards until we hit the original insert pointer value */
+ 	while (tx_queue->insert_count != tx_queue->write_count) {
++		unsigned int pkts_compl = 0, bytes_compl = 0;
+ 		--tx_queue->insert_count;
+ 		insert_ptr = tx_queue->insert_count & tx_queue->ptr_mask;
+ 		buffer = &tx_queue->buffer[insert_ptr];
+-		efx_dequeue_buffer(tx_queue, buffer);
++		efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl);
+ 		buffer->len = 0;
+ 	}
+ 
+@@ -293,7 +300,9 @@ netdev_tx_t efx_enqueue_skb(struct efx_tx_queue *tx_queue, struct sk_buff *skb)
+  * specified index.
+  */
+ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
+-				unsigned int index)
++				unsigned int index,
++				unsigned int *pkts_compl,
++				unsigned int *bytes_compl)
+ {
+ 	struct efx_nic *efx = tx_queue->efx;
+ 	unsigned int stop_index, read_ptr;
+@@ -311,7 +320,7 @@ static void efx_dequeue_buffers(struct efx_tx_queue *tx_queue,
+ 			return;
+ 		}
+ 
+-		efx_dequeue_buffer(tx_queue, buffer);
++		efx_dequeue_buffer(tx_queue, buffer, pkts_compl, bytes_compl);
+ 		buffer->continuation = true;
+ 		buffer->len = 0;
+ 
+@@ -422,10 +431,12 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index)
+ {
+ 	unsigned fill_level;
+ 	struct efx_nic *efx = tx_queue->efx;
++	unsigned int pkts_compl = 0, bytes_compl = 0;
+ 
+ 	EFX_BUG_ON_PARANOID(index > tx_queue->ptr_mask);
+ 
+-	efx_dequeue_buffers(tx_queue, index);
++	efx_dequeue_buffers(tx_queue, index, &pkts_compl, &bytes_compl);
++	netdev_tx_completed_queue(tx_queue->core_txq, pkts_compl, bytes_compl);
+ 
+ 	/* See if we need to restart the netif queue.  This barrier
+ 	 * separates the update of read_count from the test of the
+@@ -515,13 +526,15 @@ void efx_release_tx_buffers(struct efx_tx_queue *tx_queue)
+ 
+ 	/* Free any buffers left in the ring */
+ 	while (tx_queue->read_count != tx_queue->write_count) {
++		unsigned int pkts_compl = 0, bytes_compl = 0;
+ 		buffer = &tx_queue->buffer[tx_queue->read_count & tx_queue->ptr_mask];
+-		efx_dequeue_buffer(tx_queue, buffer);
++		efx_dequeue_buffer(tx_queue, buffer, &pkts_compl, &bytes_compl);
+ 		buffer->continuation = true;
+ 		buffer->len = 0;
+ 
+ 		++tx_queue->read_count;
+ 	}
++	netdev_tx_reset_queue(tx_queue->core_txq);
+ }
+ 
+ void efx_fini_tx_queue(struct efx_tx_queue *tx_queue)
+@@ -1163,6 +1176,8 @@ static int efx_enqueue_skb_tso(struct efx_tx_queue *tx_queue,
+ 	/* Pass off to hardware */
+ 	efx_nic_push_buffers(tx_queue);
+ 
++	netdev_tx_sent_queue(tx_queue->core_txq, skb->len);
++
+ 	tx_queue->tso_bursts++;
+ 	return NETDEV_TX_OK;
+ 

Added: dists/sid/linux/debian/patches/features/all/bql/skge-add-byte-queue-limit-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/skge-add-byte-queue-limit-support.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,104 @@
+From: stephen hemminger <shemminger at vyatta.com>
+Date: Sun, 22 Jan 2012 09:40:40 +0000
+Subject: skge: add byte queue limit support
+
+commit da057fb7d272c7e7609465a54bcac8ec8072ead5 upstream.
+
+This also changes the cleanup logic slightly to aggregate
+completed notifications for multiple packets.
+
+Signed-off-by: Stephen Hemminger <shemminger at vyatta.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/marvell/skge.c |   37 +++++++++++++++++++++++------------
+ 1 file changed, 24 insertions(+), 13 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c
+index 299c33b..edb9bda 100644
+--- a/drivers/net/ethernet/marvell/skge.c
++++ b/drivers/net/ethernet/marvell/skge.c
+@@ -2817,6 +2817,8 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb,
+ 	td->control = BMU_OWN | BMU_SW | BMU_STF | control | len;
+ 	wmb();
+ 
++	netdev_sent_queue(dev, skb->len);
++
+ 	skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START);
+ 
+ 	netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev,
+@@ -2858,11 +2860,9 @@ mapping_error:
+ 
+ 
+ /* Free resources associated with this reing element */
+-static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
+-			 u32 control)
++static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e,
++				 u32 control)
+ {
+-	struct pci_dev *pdev = skge->hw->pdev;
+-
+ 	/* skb header vs. fragment */
+ 	if (control & BMU_STF)
+ 		pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr),
+@@ -2872,13 +2872,6 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e,
+ 		pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr),
+ 			       dma_unmap_len(e, maplen),
+ 			       PCI_DMA_TODEVICE);
+-
+-	if (control & BMU_EOF) {
+-		netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
+-			     "tx done slot %td\n", e - skge->tx_ring.start);
+-
+-		dev_kfree_skb(e->skb);
+-	}
+ }
+ 
+ /* Free all buffers in transmit ring */
+@@ -2889,10 +2882,15 @@ static void skge_tx_clean(struct net_device *dev)
+ 
+ 	for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) {
+ 		struct skge_tx_desc *td = e->desc;
+-		skge_tx_free(skge, e, td->control);
++
++		skge_tx_unmap(skge->hw->pdev, e, td->control);
++
++		if (td->control & BMU_EOF)
++			dev_kfree_skb(e->skb);
+ 		td->control = 0;
+ 	}
+ 
++	netdev_reset_queue(dev);
+ 	skge->tx_ring.to_clean = e;
+ }
+ 
+@@ -3157,6 +3155,7 @@ static void skge_tx_done(struct net_device *dev)
+ 	struct skge_port *skge = netdev_priv(dev);
+ 	struct skge_ring *ring = &skge->tx_ring;
+ 	struct skge_element *e;
++	unsigned int bytes_compl = 0, pkts_compl = 0;
+ 
+ 	skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F);
+ 
+@@ -3166,8 +3165,20 @@ static void skge_tx_done(struct net_device *dev)
+ 		if (control & BMU_OWN)
+ 			break;
+ 
+-		skge_tx_free(skge, e, control);
++		skge_tx_unmap(skge->hw->pdev, e, control);
++
++		if (control & BMU_EOF) {
++			netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev,
++				     "tx done slot %td\n",
++				     e - skge->tx_ring.start);
++
++			pkts_compl++;
++			bytes_compl += e->skb->len;
++
++			dev_kfree_skb(e->skb);
++		}
+ 	}
++	netdev_completed_queue(dev, pkts_compl, bytes_compl);
+ 	skge->tx_ring.to_clean = e;
+ 
+ 	/* Can run lockless until we need to synchronize to restart queue. */

Added: dists/sid/linux/debian/patches/features/all/bql/sky2-add-bql-support.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/sky2-add-bql-support.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,72 @@
+From: stephen hemminger <shemminger at vyatta.com>
+Date: Tue, 29 Nov 2011 15:15:33 +0000
+Subject: sky2: add bql support
+
+commit ec2a5466b3ce680c92e8e05617b020fd825854b9 upstream.
+
+This adds support for byte queue limits and aggregates statistics
+update (suggestion from Eric).
+
+Signed-off-by: Stephen Hemminger <shemminger at vyatta.com>
+Signed-off-by: David S. Miller <davem at drr.davemloft.net>
+---
+ drivers/net/ethernet/marvell/sky2.c |   18 +++++++++++++-----
+ 1 file changed, 13 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c
+index 29adc78..760c2b1 100644
+--- a/drivers/net/ethernet/marvell/sky2.c
++++ b/drivers/net/ethernet/marvell/sky2.c
+@@ -1110,6 +1110,7 @@ static void tx_init(struct sky2_port *sky2)
+ 	sky2->tx_prod = sky2->tx_cons = 0;
+ 	sky2->tx_tcpsum = 0;
+ 	sky2->tx_last_mss = 0;
++	netdev_reset_queue(sky2->netdev);
+ 
+ 	le = get_tx_le(sky2, &sky2->tx_prod);
+ 	le->addr = 0;
+@@ -1971,6 +1972,7 @@ static netdev_tx_t sky2_xmit_frame(struct sk_buff *skb,
+ 	if (tx_avail(sky2) <= MAX_SKB_TX_LE)
+ 		netif_stop_queue(dev);
+ 
++	netdev_sent_queue(dev, skb->len);
+ 	sky2_put_idx(hw, txqaddr[sky2->port], sky2->tx_prod);
+ 
+ 	return NETDEV_TX_OK;
+@@ -2002,7 +2004,8 @@ mapping_error:
+ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+ {
+ 	struct net_device *dev = sky2->netdev;
+-	unsigned idx;
++	u16 idx;
++	unsigned int bytes_compl = 0, pkts_compl = 0;
+ 
+ 	BUG_ON(done >= sky2->tx_ring_size);
+ 
+@@ -2017,10 +2020,8 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+ 			netif_printk(sky2, tx_done, KERN_DEBUG, dev,
+ 				     "tx done %u\n", idx);
+ 
+-			u64_stats_update_begin(&sky2->tx_stats.syncp);
+-			++sky2->tx_stats.packets;
+-			sky2->tx_stats.bytes += skb->len;
+-			u64_stats_update_end(&sky2->tx_stats.syncp);
++			pkts_compl++;
++			bytes_compl += skb->len;
+ 
+ 			re->skb = NULL;
+ 			dev_kfree_skb_any(skb);
+@@ -2031,6 +2032,13 @@ static void sky2_tx_complete(struct sky2_port *sky2, u16 done)
+ 
+ 	sky2->tx_cons = idx;
+ 	smp_mb();
++
++	netdev_completed_queue(dev, pkts_compl, bytes_compl);
++
++	u64_stats_update_begin(&sky2->tx_stats.syncp);
++	sky2->tx_stats.packets += pkts_compl;
++	sky2->tx_stats.bytes += bytes_compl;
++	u64_stats_update_end(&sky2->tx_stats.syncp);
+ }
+ 
+ static void sky2_tx_reset(struct sky2_hw *hw, unsigned port)

Added: dists/sid/linux/debian/patches/features/all/bql/tg3-fix-to-use-multi-queue-bql-interfaces.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/tg3-fix-to-use-multi-queue-bql-interfaces.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,49 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 5 Mar 2012 19:53:50 +0000
+Subject: tg3: Fix to use multi queue BQL interfaces
+
+commit 5cb917bc4f3882ecee87064483111023086757d3 upstream.
+
+Fix tg3 to use BQL multi queue related netdev interfaces since the
+device supports multi queue.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Reported-by: Christoph Lameter <cl at gentwo.org>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/tg3.c |    6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index 423d023..35c2a20 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -5352,7 +5352,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
+ 		}
+ 	}
+ 
+-	netdev_completed_queue(tp->dev, pkts_compl, bytes_compl);
++	netdev_tx_completed_queue(txq, pkts_compl, bytes_compl);
+ 
+ 	tnapi->tx_cons = sw_idx;
+ 
+@@ -6793,7 +6793,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	}
+ 
+ 	skb_tx_timestamp(skb);
+-	netdev_sent_queue(tp->dev, skb->len);
++	netdev_tx_sent_queue(txq, skb->len);
+ 
+ 	/* Packets are ready, update Tx producer idx local and on card. */
+ 	tw32_tx_mbox(tnapi->prodmbox, entry);
+@@ -7275,8 +7275,8 @@ static void tg3_free_rings(struct tg3 *tp)
+ 
+ 			dev_kfree_skb_any(skb);
+ 		}
++		netdev_tx_reset_queue(netdev_get_tx_queue(tp->dev, j));
+ 	}
+-	netdev_reset_queue(tp->dev);
+ }
+ 
+ /* Initialize tx/rx rings for packet processing.

Added: dists/sid/linux/debian/patches/features/all/bql/tg3-support-for-byte-queue-limits.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/tg3-support-for-byte-queue-limits.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,62 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:30 +0000
+Subject: tg3: Support for byte queue limits
+
+commit 298376d3e8f00147548c426959ce79efc47b669a upstream.
+
+Changes to tg3 to use byte queue limits.
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ drivers/net/ethernet/broadcom/tg3.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
+index aa413d6..cf36312 100644
+--- a/drivers/net/ethernet/broadcom/tg3.c
++++ b/drivers/net/ethernet/broadcom/tg3.c
+@@ -5302,6 +5302,7 @@ static void tg3_tx(struct tg3_napi *tnapi)
+ 	u32 sw_idx = tnapi->tx_cons;
+ 	struct netdev_queue *txq;
+ 	int index = tnapi - tp->napi;
++	unsigned int pkts_compl = 0, bytes_compl = 0;
+ 
+ 	if (tg3_flag(tp, ENABLE_TSS))
+ 		index--;
+@@ -5352,6 +5353,9 @@ static void tg3_tx(struct tg3_napi *tnapi)
+ 			sw_idx = NEXT_TX(sw_idx);
+ 		}
+ 
++		pkts_compl++;
++		bytes_compl += skb->len;
++
+ 		dev_kfree_skb(skb);
+ 
+ 		if (unlikely(tx_bug)) {
+@@ -5360,6 +5364,8 @@ static void tg3_tx(struct tg3_napi *tnapi)
+ 		}
+ 	}
+ 
++	netdev_completed_queue(tp->dev, pkts_compl, bytes_compl);
++
+ 	tnapi->tx_cons = sw_idx;
+ 
+ 	/* Need to make the tx_cons update visible to tg3_start_xmit()
+@@ -6804,6 +6810,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ 	}
+ 
+ 	skb_tx_timestamp(skb);
++	netdev_sent_queue(tp->dev, skb->len);
+ 
+ 	/* Packets are ready, update Tx producer idx local and on card. */
+ 	tw32_tx_mbox(tnapi->prodmbox, entry);
+@@ -7286,6 +7293,7 @@ static void tg3_free_rings(struct tg3 *tp)
+ 			dev_kfree_skb_any(skb);
+ 		}
+ 	}
++	netdev_reset_queue(tp->dev);
+ }
+ 
+ /* Initialize tx/rx rings for packet processing.

Added: dists/sid/linux/debian/patches/features/all/bql/xps-add-xps_queue_release-function.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux/debian/patches/features/all/bql/xps-add-xps_queue_release-function.patch	Sat Aug  4 13:32:28 2012	(r19307)
@@ -0,0 +1,126 @@
+From: Tom Herbert <therbert at google.com>
+Date: Mon, 28 Nov 2011 16:33:02 +0000
+Subject: xps: Add xps_queue_release function
+
+commit 927fbec13e40648d3c87cbb1daaac5b1fb9c8775 upstream.
+
+This patch moves the xps specific parts in netdev_queue_release into
+its own function which netdev_queue_release can call.  This allows
+netdev_queue_release to be more generic (for adding new attributes
+to tx queues).
+
+Signed-off-by: Tom Herbert <therbert at google.com>
+Acked-by: Eric Dumazet <eric.dumazet at gmail.com>
+Signed-off-by: David S. Miller <davem at davemloft.net>
+---
+ net/core/net-sysfs.c |   89 ++++++++++++++++++++++++++------------------------
+ 1 file changed, 47 insertions(+), 42 deletions(-)
+
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
+index db6c2f8..b17c14a 100644
+--- a/net/core/net-sysfs.c
++++ b/net/core/net-sysfs.c
+@@ -910,6 +910,52 @@ static DEFINE_MUTEX(xps_map_mutex);
+ #define xmap_dereference(P)		\
+ 	rcu_dereference_protected((P), lockdep_is_held(&xps_map_mutex))
+ 
++static void xps_queue_release(struct netdev_queue *queue)
++{
++	struct net_device *dev = queue->dev;
++	struct xps_dev_maps *dev_maps;
++	struct xps_map *map;
++	unsigned long index;
++	int i, pos, nonempty = 0;
++
++	index = get_netdev_queue_index(queue);
++
++	mutex_lock(&xps_map_mutex);
++	dev_maps = xmap_dereference(dev->xps_maps);
++
++	if (dev_maps) {
++		for_each_possible_cpu(i) {
++			map = xmap_dereference(dev_maps->cpu_map[i]);
++			if (!map)
++				continue;
++
++			for (pos = 0; pos < map->len; pos++)
++				if (map->queues[pos] == index)
++					break;
++
++			if (pos < map->len) {
++				if (map->len > 1)
++					map->queues[pos] =
++					    map->queues[--map->len];
++				else {
++					RCU_INIT_POINTER(dev_maps->cpu_map[i],
++					    NULL);
++					kfree_rcu(map, rcu);
++					map = NULL;
++				}
++			}
++			if (map)
++				nonempty = 1;
++		}
++
++		if (!nonempty) {
++			RCU_INIT_POINTER(dev->xps_maps, NULL);
++			kfree_rcu(dev_maps, rcu);
++		}
++	}
++	mutex_unlock(&xps_map_mutex);
++}
++
+ static ssize_t store_xps_map(struct netdev_queue *queue,
+ 		      struct netdev_queue_attribute *attribute,
+ 		      const char *buf, size_t len)
+@@ -1054,49 +1100,8 @@ static struct attribute *netdev_queue_default_attrs[] = {
+ static void netdev_queue_release(struct kobject *kobj)
+ {
+ 	struct netdev_queue *queue = to_netdev_queue(kobj);
+-	struct net_device *dev = queue->dev;
+-	struct xps_dev_maps *dev_maps;
+-	struct xps_map *map;
+-	unsigned long index;
+-	int i, pos, nonempty = 0;
+-
+-	index = get_netdev_queue_index(queue);
+-
+-	mutex_lock(&xps_map_mutex);
+-	dev_maps = xmap_dereference(dev->xps_maps);
+ 
+-	if (dev_maps) {
+-		for_each_possible_cpu(i) {
+-			map = xmap_dereference(dev_maps->cpu_map[i]);
+-			if (!map)
+-				continue;
+-
+-			for (pos = 0; pos < map->len; pos++)
+-				if (map->queues[pos] == index)
+-					break;
+-
+-			if (pos < map->len) {
+-				if (map->len > 1)
+-					map->queues[pos] =
+-					    map->queues[--map->len];
+-				else {
+-					RCU_INIT_POINTER(dev_maps->cpu_map[i],
+-					    NULL);
+-					kfree_rcu(map, rcu);
+-					map = NULL;
+-				}
+-			}
+-			if (map)
+-				nonempty = 1;
+-		}
+-
+-		if (!nonempty) {
+-			RCU_INIT_POINTER(dev->xps_maps, NULL);
+-			kfree_rcu(dev_maps, rcu);
+-		}
+-	}
+-
+-	mutex_unlock(&xps_map_mutex);
++	xps_queue_release(queue);
+ 
+ 	memset(kobj, 0, sizeof(*kobj));
+ 	dev_put(queue->dev);

Modified: dists/sid/linux/debian/patches/series
==============================================================================
--- dists/sid/linux/debian/patches/series	Fri Aug  3 01:55:45 2012	(r19306)
+++ dists/sid/linux/debian/patches/series	Sat Aug  4 13:32:28 2012	(r19307)
@@ -357,3 +357,36 @@
 
 features/all/debugfs-add-mode-uid-and-gid-options.patch
 debian/debugfs-set-default-mode-to-700.patch
+
+# Byte Queue Limits from 3.3; fixes and additional driver support from 3.4, 3.5
+features/all/bql/net-new-counter-for-tx_timeout-errors-in-sysfs.patch
+features/all/bql/dql-dynamic-queue-limits.patch
+features/all/bql/net-add-queue-state-xoff-flag-for-stack.patch
+features/all/bql/net-add-netdev-interfaces-for-recording-sends-comp.patch
+features/all/bql/xps-add-xps_queue_release-function.patch
+features/all/bql/bql-byte-queue-limits.patch
+features/all/bql/bql-fix-config_xps-n-build.patch
+features/all/bql/bql-fix-inconsistency-between-file-mode-and-attr-method.patch
+features/all/bql/dql-fix-undefined-jiffies.patch
+features/all/bql/bql-fix-posdiff-to-integer-overflow-aware.patch
+features/all/bql/bql-avoid-unneeded-limit-decrement.patch
+features/all/bql/bql-avoid-possible-inconsistent-calculation.patch
+features/all/bql/e1000e-support-for-byte-queue-limits.patch
+features/all/bql/forcedeth-support-for-byte-queue-limits.patch
+features/all/bql/forcedeath-fix-bql-support-for-forcedeath.patch
+features/all/bql/tg3-support-for-byte-queue-limits.patch
+features/all/bql/tg3-fix-to-use-multi-queue-bql-interfaces.patch
+features/all/bql/bnx2x-remove-unused-variable.patch
+features/all/bql/bnx2x-support-for-byte-queue-limits.patch
+features/all/bql/bnx2x-fix-crash-while-ethtool-t.patch
+features/all/bql/sfc-support-for-byte-queue-limits.patch
+features/all/bql/sfc-fix-race-in-efx_enqueue_skb_tso.patch
+features/all/bql/sky2-add-bql-support.patch
+features/all/bql/bnx2-support-for-byte-queue-limits.patch
+features/all/bql/igb-add-support-for-byte-queue-limits.patch
+features/all/bql/igb-fix-ethtool-offline-test.patch
+features/all/bql/net-fix-issue-with-netdev_tx_reset_queue-not-resetting-queue-from.patch
+features/all/bql/ixgbe-add-support-for-byte-queue-limits.patch
+features/all/bql/igb-ixgbe-netdev_tx_reset_queue-incorrectly-called-from-tx-init.patch
+features/all/bql/skge-add-byte-queue-limit-support.patch
+features/all/bql/r8169-add-byte-queue-limit-support.patch



More information about the Kernel-svn-changes mailing list