diff options
Diffstat (limited to 'net/sched/sch_tbf.c')
-rw-r--r-- | net/sched/sch_tbf.c | 47 |
1 files changed, 15 insertions, 32 deletions
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 85da8daa61d2..53862953baaf 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <linux/etherdevice.h> | 32 | #include <linux/etherdevice.h> |
33 | #include <linux/notifier.h> | 33 | #include <linux/notifier.h> |
34 | #include <net/ip.h> | 34 | #include <net/ip.h> |
35 | #include <net/netlink.h> | ||
35 | #include <net/route.h> | 36 | #include <net/route.h> |
36 | #include <linux/skbuff.h> | 37 | #include <linux/skbuff.h> |
37 | #include <net/sock.h> | 38 | #include <net/sock.h> |
@@ -127,8 +128,8 @@ struct tbf_sched_data | |||
127 | long tokens; /* Current number of B tokens */ | 128 | long tokens; /* Current number of B tokens */ |
128 | long ptokens; /* Current number of P tokens */ | 129 | long ptokens; /* Current number of P tokens */ |
129 | psched_time_t t_c; /* Time check-point */ | 130 | psched_time_t t_c; /* Time check-point */ |
130 | struct timer_list wd_timer; /* Watchdog timer */ | ||
131 | struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */ | 131 | struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */ |
132 | struct qdisc_watchdog watchdog; /* Watchdog timer */ | ||
132 | }; | 133 | }; |
133 | 134 | ||
134 | #define L2T(q,L) ((q)->R_tab->data[(L)>>(q)->R_tab->rate.cell_log]) | 135 | #define L2T(q,L) ((q)->R_tab->data[(L)>>(q)->R_tab->rate.cell_log]) |
@@ -185,14 +186,6 @@ static unsigned int tbf_drop(struct Qdisc* sch) | |||
185 | return len; | 186 | return len; |
186 | } | 187 | } |
187 | 188 | ||
188 | static void tbf_watchdog(unsigned long arg) | ||
189 | { | ||
190 | struct Qdisc *sch = (struct Qdisc*)arg; | ||
191 | |||
192 | sch->flags &= ~TCQ_F_THROTTLED; | ||
193 | netif_schedule(sch->dev); | ||
194 | } | ||
195 | |||
196 | static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | 189 | static struct sk_buff *tbf_dequeue(struct Qdisc* sch) |
197 | { | 190 | { |
198 | struct tbf_sched_data *q = qdisc_priv(sch); | 191 | struct tbf_sched_data *q = qdisc_priv(sch); |
@@ -202,13 +195,12 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | |||
202 | 195 | ||
203 | if (skb) { | 196 | if (skb) { |
204 | psched_time_t now; | 197 | psched_time_t now; |
205 | long toks, delay; | 198 | long toks; |
206 | long ptoks = 0; | 199 | long ptoks = 0; |
207 | unsigned int len = skb->len; | 200 | unsigned int len = skb->len; |
208 | 201 | ||
209 | PSCHED_GET_TIME(now); | 202 | now = psched_get_time(); |
210 | 203 | toks = psched_tdiff_bounded(now, q->t_c, q->buffer); | |
211 | toks = PSCHED_TDIFF_SAFE(now, q->t_c, q->buffer); | ||
212 | 204 | ||
213 | if (q->P_tab) { | 205 | if (q->P_tab) { |
214 | ptoks = toks + q->ptokens; | 206 | ptoks = toks + q->ptokens; |
@@ -230,12 +222,8 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | |||
230 | return skb; | 222 | return skb; |
231 | } | 223 | } |
232 | 224 | ||
233 | delay = PSCHED_US2JIFFIE(max_t(long, -toks, -ptoks)); | 225 | qdisc_watchdog_schedule(&q->watchdog, |
234 | 226 | now + max_t(long, -toks, -ptoks)); | |
235 | if (delay == 0) | ||
236 | delay = 1; | ||
237 | |||
238 | mod_timer(&q->wd_timer, jiffies+delay); | ||
239 | 227 | ||
240 | /* Maybe we have a shorter packet in the queue, | 228 | /* Maybe we have a shorter packet in the queue, |
241 | which can be sent now. It sounds cool, | 229 | which can be sent now. It sounds cool, |
@@ -254,7 +242,6 @@ static struct sk_buff *tbf_dequeue(struct Qdisc* sch) | |||
254 | sch->qstats.drops++; | 242 | sch->qstats.drops++; |
255 | } | 243 | } |
256 | 244 | ||
257 | sch->flags |= TCQ_F_THROTTLED; | ||
258 | sch->qstats.overlimits++; | 245 | sch->qstats.overlimits++; |
259 | } | 246 | } |
260 | return NULL; | 247 | return NULL; |
@@ -266,11 +253,10 @@ static void tbf_reset(struct Qdisc* sch) | |||
266 | 253 | ||
267 | qdisc_reset(q->qdisc); | 254 | qdisc_reset(q->qdisc); |
268 | sch->q.qlen = 0; | 255 | sch->q.qlen = 0; |
269 | PSCHED_GET_TIME(q->t_c); | 256 | q->t_c = psched_get_time(); |
270 | q->tokens = q->buffer; | 257 | q->tokens = q->buffer; |
271 | q->ptokens = q->mtu; | 258 | q->ptokens = q->mtu; |
272 | sch->flags &= ~TCQ_F_THROTTLED; | 259 | qdisc_watchdog_cancel(&q->watchdog); |
273 | del_timer(&q->wd_timer); | ||
274 | } | 260 | } |
275 | 261 | ||
276 | static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) | 262 | static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) |
@@ -377,11 +363,8 @@ static int tbf_init(struct Qdisc* sch, struct rtattr *opt) | |||
377 | if (opt == NULL) | 363 | if (opt == NULL) |
378 | return -EINVAL; | 364 | return -EINVAL; |
379 | 365 | ||
380 | PSCHED_GET_TIME(q->t_c); | 366 | q->t_c = psched_get_time(); |
381 | init_timer(&q->wd_timer); | 367 | qdisc_watchdog_init(&q->watchdog, sch); |
382 | q->wd_timer.function = tbf_watchdog; | ||
383 | q->wd_timer.data = (unsigned long)sch; | ||
384 | |||
385 | q->qdisc = &noop_qdisc; | 368 | q->qdisc = &noop_qdisc; |
386 | 369 | ||
387 | return tbf_change(sch, opt); | 370 | return tbf_change(sch, opt); |
@@ -391,7 +374,7 @@ static void tbf_destroy(struct Qdisc *sch) | |||
391 | { | 374 | { |
392 | struct tbf_sched_data *q = qdisc_priv(sch); | 375 | struct tbf_sched_data *q = qdisc_priv(sch); |
393 | 376 | ||
394 | del_timer(&q->wd_timer); | 377 | qdisc_watchdog_cancel(&q->watchdog); |
395 | 378 | ||
396 | if (q->P_tab) | 379 | if (q->P_tab) |
397 | qdisc_put_rtab(q->P_tab); | 380 | qdisc_put_rtab(q->P_tab); |
@@ -404,7 +387,7 @@ static void tbf_destroy(struct Qdisc *sch) | |||
404 | static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) | 387 | static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) |
405 | { | 388 | { |
406 | struct tbf_sched_data *q = qdisc_priv(sch); | 389 | struct tbf_sched_data *q = qdisc_priv(sch); |
407 | unsigned char *b = skb->tail; | 390 | unsigned char *b = skb_tail_pointer(skb); |
408 | struct rtattr *rta; | 391 | struct rtattr *rta; |
409 | struct tc_tbf_qopt opt; | 392 | struct tc_tbf_qopt opt; |
410 | 393 | ||
@@ -420,12 +403,12 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
420 | opt.mtu = q->mtu; | 403 | opt.mtu = q->mtu; |
421 | opt.buffer = q->buffer; | 404 | opt.buffer = q->buffer; |
422 | RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); | 405 | RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); |
423 | rta->rta_len = skb->tail - b; | 406 | rta->rta_len = skb_tail_pointer(skb) - b; |
424 | 407 | ||
425 | return skb->len; | 408 | return skb->len; |
426 | 409 | ||
427 | rtattr_failure: | 410 | rtattr_failure: |
428 | skb_trim(skb, b - skb->data); | 411 | nlmsg_trim(skb, b); |
429 | return -1; | 412 | return -1; |
430 | } | 413 | } |
431 | 414 | ||