aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-01-21 19:26:09 -0500
committerDavid S. Miller <davem@davemloft.net>2011-01-21 19:26:09 -0500
commit23624935e0c4b04730ed8d7d21f0cd25b2c2cda1 (patch)
tree3fedc885d6bcd72c94fc239ae2ef98937f77c722
parentbb134d2298b49f50cf6d9388410fba96272905dc (diff)
net_sched: TCQ_F_CAN_BYPASS generalization
Now qdisc stab is handled before TCQ_F_CAN_BYPASS test in __dev_xmit_skb(), we can generalize TCQ_F_CAN_BYPASS to other qdiscs than pfifo_fast : pfifo, bfifo, pfifo_head_drop and sfq SFQ is special because it can have external classifiers, and in these cases, we cannot bypass queue discipline (packet could be dropped by classifier) without admin asking it, or further changes. Its worth doing this, especially for SFQ, avoiding dirtying memory in case no packets are already waiting in queue. Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sched/sch_fifo.c13
-rw-r--r--net/sched/sch_generic.c5
-rw-r--r--net/sched/sch_mq.c1
-rw-r--r--net/sched/sch_mqprio.c1
-rw-r--r--net/sched/sch_sfq.c6
5 files changed, 20 insertions, 6 deletions
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c
index b3075f8a196..f7290d2542c 100644
--- a/net/sched/sch_fifo.c
+++ b/net/sched/sch_fifo.c
@@ -64,11 +64,13 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)
64static int fifo_init(struct Qdisc *sch, struct nlattr *opt) 64static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
65{ 65{
66 struct fifo_sched_data *q = qdisc_priv(sch); 66 struct fifo_sched_data *q = qdisc_priv(sch);
67 bool bypass;
68 bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
67 69
68 if (opt == NULL) { 70 if (opt == NULL) {
69 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1; 71 u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
70 72
71 if (sch->ops == &bfifo_qdisc_ops) 73 if (is_bfifo)
72 limit *= psched_mtu(qdisc_dev(sch)); 74 limit *= psched_mtu(qdisc_dev(sch));
73 75
74 q->limit = limit; 76 q->limit = limit;
@@ -81,6 +83,15 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
81 q->limit = ctl->limit; 83 q->limit = ctl->limit;
82 } 84 }
83 85
86 if (is_bfifo)
87 bypass = q->limit >= psched_mtu(qdisc_dev(sch));
88 else
89 bypass = q->limit >= 1;
90
91 if (bypass)
92 sch->flags |= TCQ_F_CAN_BYPASS;
93 else
94 sch->flags &= ~TCQ_F_CAN_BYPASS;
84 return 0; 95 return 0;
85} 96}
86 97
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index cc17e794c41..0da09d50873 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -527,6 +527,8 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
527 for (prio = 0; prio < PFIFO_FAST_BANDS; prio++) 527 for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
528 skb_queue_head_init(band2list(priv, prio)); 528 skb_queue_head_init(band2list(priv, prio));
529 529
530 /* Can by-pass the queue discipline */
531 qdisc->flags |= TCQ_F_CAN_BYPASS;
530 return 0; 532 return 0;
531} 533}
532 534
@@ -691,9 +693,6 @@ static void attach_one_default_qdisc(struct net_device *dev,
691 netdev_info(dev, "activation failed\n"); 693 netdev_info(dev, "activation failed\n");
692 return; 694 return;
693 } 695 }
694
695 /* Can by-pass the queue discipline for default qdisc */
696 qdisc->flags |= TCQ_F_CAN_BYPASS;
697 } 696 }
698 dev_queue->qdisc_sleeping = qdisc; 697 dev_queue->qdisc_sleeping = qdisc;
699} 698}
diff --git a/net/sched/sch_mq.c b/net/sched/sch_mq.c
index ecc302f4d2a..ec5cbc84896 100644
--- a/net/sched/sch_mq.c
+++ b/net/sched/sch_mq.c
@@ -61,7 +61,6 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
61 TC_H_MIN(ntx + 1))); 61 TC_H_MIN(ntx + 1)));
62 if (qdisc == NULL) 62 if (qdisc == NULL)
63 goto err; 63 goto err;
64 qdisc->flags |= TCQ_F_CAN_BYPASS;
65 priv->qdiscs[ntx] = qdisc; 64 priv->qdiscs[ntx] = qdisc;
66 } 65 }
67 66
diff --git a/net/sched/sch_mqprio.c b/net/sched/sch_mqprio.c
index 8620c65f480..fbc6f53cb1b 100644
--- a/net/sched/sch_mqprio.c
+++ b/net/sched/sch_mqprio.c
@@ -130,7 +130,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
130 err = -ENOMEM; 130 err = -ENOMEM;
131 goto err; 131 goto err;
132 } 132 }
133 qdisc->flags |= TCQ_F_CAN_BYPASS;
134 priv->qdiscs[i] = qdisc; 133 priv->qdiscs[i] = qdisc;
135 } 134 }
136 135
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 156ad30980b..fdba52aa053 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -560,6 +560,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
560 slot_queue_init(&q->slots[i]); 560 slot_queue_init(&q->slots[i]);
561 sfq_link(q, i); 561 sfq_link(q, i);
562 } 562 }
563 if (q->limit >= 1)
564 sch->flags |= TCQ_F_CAN_BYPASS;
565 else
566 sch->flags &= ~TCQ_F_CAN_BYPASS;
563 return 0; 567 return 0;
564} 568}
565 569
@@ -611,6 +615,8 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
611static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent, 615static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
612 u32 classid) 616 u32 classid)
613{ 617{
618 /* we cannot bypass queue discipline anymore */
619 sch->flags &= ~TCQ_F_CAN_BYPASS;
614 return 0; 620 return 0;
615} 621}
616 622