aboutsummaryrefslogtreecommitdiffstats
path: root/include/net
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 /include/net
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 'include/net')
-rw-r--r--include/net/pkt_sched.h3
-rw-r--r--include/net/sch_generic.h15
2 files changed, 16 insertions, 2 deletions
diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h
index 82a3191375f5..f911ec7598ef 100644
--- a/include/net/pkt_sched.h
+++ b/include/net/pkt_sched.h
@@ -87,6 +87,9 @@ extern struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
87extern void qdisc_put_rtab(struct qdisc_rate_table *tab); 87extern void qdisc_put_rtab(struct qdisc_rate_table *tab);
88extern void qdisc_put_stab(struct qdisc_size_table *tab); 88extern void qdisc_put_stab(struct qdisc_size_table *tab);
89extern void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc); 89extern void qdisc_warn_nonwc(char *txt, struct Qdisc *qdisc);
90extern int sch_direct_xmit(struct sk_buff *skb, struct Qdisc *q,
91 struct net_device *dev, struct netdev_queue *txq,
92 spinlock_t *root_lock);
90 93
91extern void __qdisc_run(struct Qdisc *q); 94extern void __qdisc_run(struct Qdisc *q);
92 95
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 964ffa0d8815..84b3fc2aef0f 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -45,6 +45,7 @@ struct Qdisc
45#define TCQ_F_BUILTIN 1 45#define TCQ_F_BUILTIN 1
46#define TCQ_F_THROTTLED 2 46#define TCQ_F_THROTTLED 2
47#define TCQ_F_INGRESS 4 47#define TCQ_F_INGRESS 4
48#define TCQ_F_CAN_BYPASS 8
48#define TCQ_F_WARN_NONWC (1 << 16) 49#define TCQ_F_WARN_NONWC (1 << 16)
49 int padded; 50 int padded;
50 struct Qdisc_ops *ops; 51 struct Qdisc_ops *ops;
@@ -182,6 +183,11 @@ struct qdisc_skb_cb {
182 char data[]; 183 char data[];
183}; 184};
184 185
186static inline int qdisc_qlen(struct Qdisc *q)
187{
188 return q->q.qlen;
189}
190
185static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb) 191static inline struct qdisc_skb_cb *qdisc_skb_cb(struct sk_buff *skb)
186{ 192{
187 return (struct qdisc_skb_cb *)skb->cb; 193 return (struct qdisc_skb_cb *)skb->cb;
@@ -387,13 +393,18 @@ static inline int qdisc_enqueue_root(struct sk_buff *skb, struct Qdisc *sch)
387 return qdisc_enqueue(skb, sch) & NET_XMIT_MASK; 393 return qdisc_enqueue(skb, sch) & NET_XMIT_MASK;
388} 394}
389 395
396static inline void __qdisc_update_bstats(struct Qdisc *sch, unsigned int len)
397{
398 sch->bstats.bytes += len;
399 sch->bstats.packets++;
400}
401
390static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch, 402static inline int __qdisc_enqueue_tail(struct sk_buff *skb, struct Qdisc *sch,
391 struct sk_buff_head *list) 403 struct sk_buff_head *list)
392{ 404{
393 __skb_queue_tail(list, skb); 405 __skb_queue_tail(list, skb);
394 sch->qstats.backlog += qdisc_pkt_len(skb); 406 sch->qstats.backlog += qdisc_pkt_len(skb);
395 sch->bstats.bytes += qdisc_pkt_len(skb); 407 __qdisc_update_bstats(sch, qdisc_pkt_len(skb));
396 sch->bstats.packets++;
397 408
398 return NET_XMIT_SUCCESS; 409 return NET_XMIT_SUCCESS;
399} 410}