diff options
Diffstat (limited to 'net/sched/sch_fifo.c')
-rw-r--r-- | net/sched/sch_fifo.c | 49 |
1 files changed, 46 insertions, 3 deletions
diff --git a/net/sched/sch_fifo.c b/net/sched/sch_fifo.c index 95ed48221652..23d258bfe8ac 100644 --- a/net/sched/sch_fifo.c +++ b/net/sched/sch_fifo.c | |||
@@ -27,7 +27,7 @@ static int bfifo_enqueue(struct sk_buff *skb, struct Qdisc* sch) | |||
27 | { | 27 | { |
28 | struct fifo_sched_data *q = qdisc_priv(sch); | 28 | struct fifo_sched_data *q = qdisc_priv(sch); |
29 | 29 | ||
30 | if (likely(sch->qstats.backlog + skb->len <= q->limit)) | 30 | if (likely(sch->qstats.backlog + qdisc_pkt_len(skb) <= q->limit)) |
31 | return qdisc_enqueue_tail(skb, sch); | 31 | return qdisc_enqueue_tail(skb, sch); |
32 | 32 | ||
33 | return qdisc_reshape_fail(skb, sch); | 33 | return qdisc_reshape_fail(skb, sch); |
@@ -48,10 +48,10 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt) | |||
48 | struct fifo_sched_data *q = qdisc_priv(sch); | 48 | struct fifo_sched_data *q = qdisc_priv(sch); |
49 | 49 | ||
50 | if (opt == NULL) { | 50 | if (opt == NULL) { |
51 | u32 limit = sch->dev->tx_queue_len ? : 1; | 51 | u32 limit = qdisc_dev(sch)->tx_queue_len ? : 1; |
52 | 52 | ||
53 | if (sch->ops == &bfifo_qdisc_ops) | 53 | if (sch->ops == &bfifo_qdisc_ops) |
54 | limit *= sch->dev->mtu; | 54 | limit *= qdisc_dev(sch)->mtu; |
55 | 55 | ||
56 | q->limit = limit; | 56 | q->limit = limit; |
57 | } else { | 57 | } else { |
@@ -107,3 +107,46 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = { | |||
107 | .owner = THIS_MODULE, | 107 | .owner = THIS_MODULE, |
108 | }; | 108 | }; |
109 | EXPORT_SYMBOL(bfifo_qdisc_ops); | 109 | EXPORT_SYMBOL(bfifo_qdisc_ops); |
110 | |||
111 | /* Pass size change message down to embedded FIFO */ | ||
112 | int fifo_set_limit(struct Qdisc *q, unsigned int limit) | ||
113 | { | ||
114 | struct nlattr *nla; | ||
115 | int ret = -ENOMEM; | ||
116 | |||
117 | /* Hack to avoid sending change message to non-FIFO */ | ||
118 | if (strncmp(q->ops->id + 1, "fifo", 4) != 0) | ||
119 | return 0; | ||
120 | |||
121 | nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); | ||
122 | if (nla) { | ||
123 | nla->nla_type = RTM_NEWQDISC; | ||
124 | nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt)); | ||
125 | ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit; | ||
126 | |||
127 | ret = q->ops->change(q, nla); | ||
128 | kfree(nla); | ||
129 | } | ||
130 | return ret; | ||
131 | } | ||
132 | EXPORT_SYMBOL(fifo_set_limit); | ||
133 | |||
134 | struct Qdisc *fifo_create_dflt(struct Qdisc *sch, struct Qdisc_ops *ops, | ||
135 | unsigned int limit) | ||
136 | { | ||
137 | struct Qdisc *q; | ||
138 | int err = -ENOMEM; | ||
139 | |||
140 | q = qdisc_create_dflt(qdisc_dev(sch), sch->dev_queue, | ||
141 | ops, TC_H_MAKE(sch->handle, 1)); | ||
142 | if (q) { | ||
143 | err = fifo_set_limit(q, limit); | ||
144 | if (err < 0) { | ||
145 | qdisc_destroy(q); | ||
146 | q = NULL; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | return q ? : ERR_PTR(err); | ||
151 | } | ||
152 | EXPORT_SYMBOL(fifo_create_dflt); | ||