Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jikos/trivial
[safe/jmp/linux-2.6] / net / sched / sch_fifo.c
index 95ed482..69188e8 100644 (file)
@@ -27,7 +27,7 @@ static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch)
 {
        struct fifo_sched_data *q = qdisc_priv(sch);
 
-       if (likely(sch->qstats.backlog + skb->len <= q->limit))
+       if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= q->limit))
                return qdisc_enqueue_tail(skb, sch);
 
        return qdisc_reshape_fail(skb, sch);
@@ -48,10 +48,10 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
        struct fifo_sched_data *q = qdisc_priv(sch);
 
        if (opt == NULL) {
-               u32 limit = sch->dev->tx_queue_len ? : 1;
+               u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1;
 
                if (sch->ops == &bfifo_qdisc_ops)
-                       limit *= sch->dev->mtu;
+                       limit *= psched_mtu(qdisc_dev(sch));
 
                q->limit = limit;
        } else {
@@ -83,7 +83,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       pfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
-       .requeue        =       qdisc_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       qdisc_queue_drop,
        .init           =       fifo_init,
        .reset          =       qdisc_reset_queue,
@@ -98,7 +98,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
        .priv_size      =       sizeof(struct fifo_sched_data),
        .enqueue        =       bfifo_enqueue,
        .dequeue        =       qdisc_dequeue_head,
-       .requeue        =       qdisc_requeue,
+       .peek           =       qdisc_peek_head,
        .drop           =       qdisc_queue_drop,
        .init           =       fifo_init,
        .reset          =       qdisc_reset_queue,
@@ -107,3 +107,46 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
        .owner          =       THIS_MODULE,
 };
 EXPORT_SYMBOL(bfifo_qdisc_ops);
+
+/* Pass size change message down to embedded FIFO */
+int fifo_set_limit(struct Qdisc *q, unsigned int limit)
+{
+       struct nlattr *nla;
+       int ret = -ENOMEM;
+
+       /* Hack to avoid sending change message to non-FIFO */
+       if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+               return 0;
+
+       nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
+       if (nla) {
+               nla->nla_type = RTM_NEWQDISC;
+               nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt));
+               ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit;
+
+               ret = q->ops->change(q, nla);
+               kfree(nla);
+       }
+       return ret;
+}
+EXPORT_SYMBOL(fifo_set_limit);
+
+struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops,
+                              unsigned int limit)
+{
+       struct Qdisc *q;
+       int err = -ENOMEM;
+
+       q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue,
+                             ops, TC_H_MAKE(sch->handle, 1));
+       if (q) {
+               err = fifo_set_limit(q, limit);
+               if (err < 0) {
+                       qdisc_destroy(q);
+                       q = NULL;
+               }
+       }
+
+       return q ? : ERR_PTR(err);
+}
+EXPORT_SYMBOL(fifo_create_dflt);