net_sched: TCQ_F_CAN_BYPASS generalization
authorEric Dumazet <eric.dumazet@gmail.com>
Sat, 22 Jan 2011 00:26:09 +0000 (16:26 -0800)
committerDavid S. Miller <davem@davemloft.net>
Sat, 22 Jan 2011 00:26:09 +0000 (16:26 -0800)
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>
net/sched/sch_fifo.c
net/sched/sch_generic.c
net/sched/sch_mq.c
net/sched/sch_mqprio.c
net/sched/sch_sfq.c

index b3075f8a196b5d325ab070061e10593653bc4d20..f7290d2542c2f873b7884abf94d74f858b77b1b3 100644 (file)
@@ -64,11 +64,13 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
 {
        struct fifo_sched_data *q = qdisc_priv(sch);
+       bool bypass;
+       bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
 
        if (opt == NULL) {
                u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
 
-               if (sch->ops == &bfifo_qdisc_ops)
+               if (is_bfifo)
                        limit *= psched_mtu(qdisc_dev(sch));
 
                q->limit = limit;
@@ -81,6 +83,15 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
                q->limit = ctl->limit;
        }
 
+       if (is_bfifo)
+               bypass = q->limit >= psched_mtu(qdisc_dev(sch));
+       else
+               bypass = q->limit >= 1;
+
+       if (bypass)
+               sch->flags |= TCQ_F_CAN_BYPASS;
+       else
+               sch->flags &= ~TCQ_F_CAN_BYPASS;
        return 0;
 }
 
index cc17e794c41ede14b8b6c3b71ad50e0737aea8a2..0da09d50873718481c4fbcfec1265db710975090 100644 (file)
@@ -527,6 +527,8 @@ static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt)
        for (prio = 0; prio < PFIFO_FAST_BANDS; prio++)
                skb_queue_head_init(band2list(priv, prio));
 
+       /* Can by-pass the queue discipline */
+       qdisc->flags |= TCQ_F_CAN_BYPASS;
        return 0;
 }
 
@@ -691,9 +693,6 @@ static void attach_one_default_qdisc(struct net_device *dev,
                        netdev_info(dev, "activation failed\n");
                        return;
                }
-
-               /* Can by-pass the queue discipline for default qdisc */
-               qdisc->flags |= TCQ_F_CAN_BYPASS;
        }
        dev_queue->qdisc_sleeping = qdisc;
 }
index ecc302f4d2a1ce35dde04a15fd810617a76807ee..ec5cbc8489636738b7c4bc02c9f9e0096d0d7e92 100644 (file)
@@ -61,7 +61,6 @@ static int mq_init(struct Qdisc *sch, struct nlattr *opt)
                                                    TC_H_MIN(ntx + 1)));
                if (qdisc == NULL)
                        goto err;
-               qdisc->flags |= TCQ_F_CAN_BYPASS;
                priv->qdiscs[ntx] = qdisc;
        }
 
index 8620c65f480a895929126288cb0ea36b5e95c084..fbc6f53cb1b777783a19b1b237f76ee6eec038c0 100644 (file)
@@ -130,7 +130,6 @@ static int mqprio_init(struct Qdisc *sch, struct nlattr *opt)
                        err = -ENOMEM;
                        goto err;
                }
-               qdisc->flags |= TCQ_F_CAN_BYPASS;
                priv->qdiscs[i] = qdisc;
        }
 
index 156ad30980b58425c4fb5642975e385a477294b9..fdba52aa053df808345a68b4d838fa1157999189 100644 (file)
@@ -560,6 +560,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
                slot_queue_init(&q->slots[i]);
                sfq_link(q, i);
        }
+       if (q->limit >= 1)
+               sch->flags |= TCQ_F_CAN_BYPASS;
+       else
+               sch->flags &= ~TCQ_F_CAN_BYPASS;
        return 0;
 }
 
@@ -611,6 +615,8 @@ static unsigned long sfq_get(struct Qdisc *sch, u32 classid)
 static unsigned long sfq_bind(struct Qdisc *sch, unsigned long parent,
                              u32 classid)
 {
+       /* we cannot bypass queue discipline anymore */
+       sch->flags &= ~TCQ_F_CAN_BYPASS;
        return 0;
 }
 
This page took 0.028777 seconds and 5 git commands to generate.