aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorKrishna Kumar <krkumar2@in.ibm.com>2009-08-05 21:44:21 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-06 23:10:18 -0400
commitbbd8a0d3a3b65d341437f8b99c828fa5cc29c739 (patch)
treea4055c65be5ce3f8fd4987a32a38dfab1642ec95 /net/core
parent9f519f68cfffba022978634f724944a0b971fec1 (diff)
net: Avoid enqueuing skb for default qdiscs
dev_queue_xmit enqueue's a skb and calls qdisc_run which dequeue's the skb and xmits it. In most cases, the skb that is enqueue'd is the same one that is dequeue'd (unless the queue gets stopped or multiple cpu's write to the same queue and ends in a race with qdisc_run). For default qdiscs, we can remove the redundant enqueue/dequeue and simply xmit the skb since the default qdisc is work-conserving. The patch uses a new flag - TCQ_F_CAN_BYPASS to identify the default fast queue. The controversial part of the patch is incrementing qlen when a skb is requeued - this is to avoid checks like the second line below: + } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) && >> !q->gso_skb && + !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) { Results of a 2 hour testing for multiple netperf sessions (1, 2, 4, 8, 12 sessions on a 4 cpu system-X). The BW numbers are aggregate Mb/s across iterations tested with this version on System-X boxes with Chelsio 10gbps cards: ---------------------------------- Size | ORG BW NEW BW | ---------------------------------- 128K | 156964 159381 | 256K | 158650 162042 | ---------------------------------- Changes from ver1: 1. Move sch_direct_xmit declaration from sch_generic.h to pkt_sched.h 2. Update qdisc basic statistics for direct xmit path. 3. Set qlen to zero in qdisc_reset. 4. Changed some function names to more meaningful ones. Signed-off-by: Krishna Kumar <krkumar2@in.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c48
1 files changed, 35 insertions, 13 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index f01a9c41f112..a0bc087616a4 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1786,6 +1786,40 @@ static struct netdev_queue *dev_pick_tx(struct net_device *dev,
1786 return netdev_get_tx_queue(dev, queue_index); 1786 return netdev_get_tx_queue(dev, queue_index);
1787} 1787}
1788 1788
1789static inline int __dev_xmit_skb(struct sk_buff *skb, struct Qdisc *q,
1790 struct net_device *dev,
1791 struct netdev_queue *txq)
1792{
1793 spinlock_t *root_lock = qdisc_lock(q);
1794 int rc;
1795
1796 spin_lock(root_lock);
1797 if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
1798 kfree_skb(skb);
1799 rc = NET_XMIT_DROP;
1800 } else if ((q->flags & TCQ_F_CAN_BYPASS) && !qdisc_qlen(q) &&
1801 !test_and_set_bit(__QDISC_STATE_RUNNING, &q->state)) {
1802 /*
1803 * This is a work-conserving queue; there are no old skbs
1804 * waiting to be sent out; and the qdisc is not running -
1805 * xmit the skb directly.
1806 */
1807 __qdisc_update_bstats(q, skb->len);
1808 if (sch_direct_xmit(skb, q, dev, txq, root_lock))
1809 __qdisc_run(q);
1810 else
1811 clear_bit(__QDISC_STATE_RUNNING, &q->state);
1812
1813 rc = NET_XMIT_SUCCESS;
1814 } else {
1815 rc = qdisc_enqueue_root(skb, q);
1816 qdisc_run(q);
1817 }
1818 spin_unlock(root_lock);
1819
1820 return rc;
1821}
1822
1789/** 1823/**
1790 * dev_queue_xmit - transmit a buffer 1824 * dev_queue_xmit - transmit a buffer
1791 * @skb: buffer to transmit 1825 * @skb: buffer to transmit
@@ -1859,19 +1893,7 @@ gso:
1859 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS); 1893 skb->tc_verd = SET_TC_AT(skb->tc_verd,AT_EGRESS);
1860#endif 1894#endif
1861 if (q->enqueue) { 1895 if (q->enqueue) {
1862 spinlock_t *root_lock = qdisc_lock(q); 1896 rc = __dev_xmit_skb(skb, q, dev, txq);
1863
1864 spin_lock(root_lock);
1865
1866 if (unlikely(test_bit(__QDISC_STATE_DEACTIVATED, &q->state))) {
1867 kfree_skb(skb);
1868 rc = NET_XMIT_DROP;
1869 } else {
1870 rc = qdisc_enqueue_root(skb, q);
1871 qdisc_run(q);
1872 }
1873 spin_unlock(root_lock);
1874
1875 goto out; 1897 goto out;
1876 } 1898 }
1877 1899