aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched')
-rw-r--r--net/sched/cls_api.c2
-rw-r--r--net/sched/sch_api.c95
-rw-r--r--net/sched/sch_cbq.c6
-rw-r--r--net/sched/sch_generic.c67
-rw-r--r--net/sched/sch_htb.c4
-rw-r--r--net/sched/sch_prio.c4
-rw-r--r--net/sched/sch_tbf.c11
7 files changed, 95 insertions, 94 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index d2b6f54a6261..5cafdd4c8018 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -280,7 +280,7 @@ replay:
280 if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { 280 if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
281 spin_lock_bh(root_lock); 281 spin_lock_bh(root_lock);
282 *back = tp->next; 282 *back = tp->next;
283 spin_lock_bh(root_lock); 283 spin_unlock_bh(root_lock);
284 284
285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); 285 tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER);
286 tcf_destroy(tp); 286 tcf_destroy(tp);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index c25465e5607a..e7fb9e0d21b4 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -27,6 +27,7 @@
27#include <linux/kmod.h> 27#include <linux/kmod.h>
28#include <linux/list.h> 28#include <linux/list.h>
29#include <linux/hrtimer.h> 29#include <linux/hrtimer.h>
30#include <linux/lockdep.h>
30 31
31#include <net/net_namespace.h> 32#include <net/net_namespace.h>
32#include <net/sock.h> 33#include <net/sock.h>
@@ -198,19 +199,53 @@ struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
198 return NULL; 199 return NULL;
199} 200}
200 201
202/*
203 * This lock is needed until some qdiscs stop calling qdisc_tree_decrease_qlen()
204 * without rtnl_lock(); currently hfsc_dequeue(), netem_dequeue(), tbf_dequeue()
205 */
206static DEFINE_SPINLOCK(qdisc_list_lock);
207
208static void qdisc_list_add(struct Qdisc *q)
209{
210 if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
211 spin_lock_bh(&qdisc_list_lock);
212 list_add_tail(&q->list, &qdisc_root_sleeping(q)->list);
213 spin_unlock_bh(&qdisc_list_lock);
214 }
215}
216
217void qdisc_list_del(struct Qdisc *q)
218{
219 if ((q->parent != TC_H_ROOT) && !(q->flags & TCQ_F_INGRESS)) {
220 spin_lock_bh(&qdisc_list_lock);
221 list_del(&q->list);
222 spin_unlock_bh(&qdisc_list_lock);
223 }
224}
225EXPORT_SYMBOL(qdisc_list_del);
226
201struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle) 227struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
202{ 228{
203 unsigned int i; 229 unsigned int i;
230 struct Qdisc *q;
231
232 spin_lock_bh(&qdisc_list_lock);
204 233
205 for (i = 0; i < dev->num_tx_queues; i++) { 234 for (i = 0; i < dev->num_tx_queues; i++) {
206 struct netdev_queue *txq = netdev_get_tx_queue(dev, i); 235 struct netdev_queue *txq = netdev_get_tx_queue(dev, i);
207 struct Qdisc *q, *txq_root = txq->qdisc_sleeping; 236 struct Qdisc *txq_root = txq->qdisc_sleeping;
208 237
209 q = qdisc_match_from_root(txq_root, handle); 238 q = qdisc_match_from_root(txq_root, handle);
210 if (q) 239 if (q)
211 return q; 240 goto unlock;
212 } 241 }
213 return qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle); 242
243 q = qdisc_match_from_root(dev->rx_queue.qdisc_sleeping, handle);
244
245unlock:
246 spin_unlock_bh(&qdisc_list_lock);
247
248 return q;
214} 249}
215 250
216static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid) 251static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
@@ -331,7 +366,7 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
331 if (!s || tsize != s->tsize || (!tab && tsize > 0)) 366 if (!s || tsize != s->tsize || (!tab && tsize > 0))
332 return ERR_PTR(-EINVAL); 367 return ERR_PTR(-EINVAL);
333 368
334 spin_lock_bh(&qdisc_stab_lock); 369 spin_lock(&qdisc_stab_lock);
335 370
336 list_for_each_entry(stab, &qdisc_stab_list, list) { 371 list_for_each_entry(stab, &qdisc_stab_list, list) {
337 if (memcmp(&stab->szopts, s, sizeof(*s))) 372 if (memcmp(&stab->szopts, s, sizeof(*s)))
@@ -339,11 +374,11 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
339 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16))) 374 if (tsize > 0 && memcmp(stab->data, tab, tsize * sizeof(u16)))
340 continue; 375 continue;
341 stab->refcnt++; 376 stab->refcnt++;
342 spin_unlock_bh(&qdisc_stab_lock); 377 spin_unlock(&qdisc_stab_lock);
343 return stab; 378 return stab;
344 } 379 }
345 380
346 spin_unlock_bh(&qdisc_stab_lock); 381 spin_unlock(&qdisc_stab_lock);
347 382
348 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL); 383 stab = kmalloc(sizeof(*stab) + tsize * sizeof(u16), GFP_KERNEL);
349 if (!stab) 384 if (!stab)
@@ -354,9 +389,9 @@ static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt)
354 if (tsize > 0) 389 if (tsize > 0)
355 memcpy(stab->data, tab, tsize * sizeof(u16)); 390 memcpy(stab->data, tab, tsize * sizeof(u16));
356 391
357 spin_lock_bh(&qdisc_stab_lock); 392 spin_lock(&qdisc_stab_lock);
358 list_add_tail(&stab->list, &qdisc_stab_list); 393 list_add_tail(&stab->list, &qdisc_stab_list);
359 spin_unlock_bh(&qdisc_stab_lock); 394 spin_unlock(&qdisc_stab_lock);
360 395
361 return stab; 396 return stab;
362} 397}
@@ -366,14 +401,14 @@ void qdisc_put_stab(struct qdisc_size_table *tab)
366 if (!tab) 401 if (!tab)
367 return; 402 return;
368 403
369 spin_lock_bh(&qdisc_stab_lock); 404 spin_lock(&qdisc_stab_lock);
370 405
371 if (--tab->refcnt == 0) { 406 if (--tab->refcnt == 0) {
372 list_del(&tab->list); 407 list_del(&tab->list);
373 kfree(tab); 408 kfree(tab);
374 } 409 }
375 410
376 spin_unlock_bh(&qdisc_stab_lock); 411 spin_unlock(&qdisc_stab_lock);
377} 412}
378EXPORT_SYMBOL(qdisc_put_stab); 413EXPORT_SYMBOL(qdisc_put_stab);
379 414
@@ -426,7 +461,7 @@ static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
426 461
427 wd->qdisc->flags &= ~TCQ_F_THROTTLED; 462 wd->qdisc->flags &= ~TCQ_F_THROTTLED;
428 smp_wmb(); 463 smp_wmb();
429 __netif_schedule(wd->qdisc); 464 __netif_schedule(qdisc_root(wd->qdisc));
430 465
431 return HRTIMER_NORESTART; 466 return HRTIMER_NORESTART;
432} 467}
@@ -443,6 +478,10 @@ void qdisc_watchdog_schedule(struct qdisc_watchdog *wd, psched_time_t expires)
443{ 478{
444 ktime_t time; 479 ktime_t time;
445 480
481 if (test_bit(__QDISC_STATE_DEACTIVATED,
482 &qdisc_root_sleeping(wd->qdisc)->state))
483 return;
484
446 wd->qdisc->flags |= TCQ_F_THROTTLED; 485 wd->qdisc->flags |= TCQ_F_THROTTLED;
447 time = ktime_set(0, 0); 486 time = ktime_set(0, 0);
448 time = ktime_add_ns(time, PSCHED_US2NS(expires)); 487 time = ktime_add_ns(time, PSCHED_US2NS(expires));
@@ -637,11 +676,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid
637 if (new || old) 676 if (new || old)
638 qdisc_notify(skb, n, clid, old, new); 677 qdisc_notify(skb, n, clid, old, new);
639 678
640 if (old) { 679 if (old)
641 spin_lock_bh(&old->q.lock);
642 qdisc_destroy(old); 680 qdisc_destroy(old);
643 spin_unlock_bh(&old->q.lock);
644 }
645} 681}
646 682
647/* Graft qdisc "new" to class "classid" of qdisc "parent" or 683/* Graft qdisc "new" to class "classid" of qdisc "parent" or
@@ -707,6 +743,10 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
707 return err; 743 return err;
708} 744}
709 745
746/* lockdep annotation is needed for ingress; egress gets it only for name */
747static struct lock_class_key qdisc_tx_lock;
748static struct lock_class_key qdisc_rx_lock;
749
710/* 750/*
711 Allocate and initialize new qdisc. 751 Allocate and initialize new qdisc.
712 752
@@ -767,6 +807,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
767 if (handle == TC_H_INGRESS) { 807 if (handle == TC_H_INGRESS) {
768 sch->flags |= TCQ_F_INGRESS; 808 sch->flags |= TCQ_F_INGRESS;
769 handle = TC_H_MAKE(TC_H_INGRESS, 0); 809 handle = TC_H_MAKE(TC_H_INGRESS, 0);
810 lockdep_set_class(qdisc_lock(sch), &qdisc_rx_lock);
770 } else { 811 } else {
771 if (handle == 0) { 812 if (handle == 0) {
772 handle = qdisc_alloc_handle(dev); 813 handle = qdisc_alloc_handle(dev);
@@ -774,6 +815,7 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
774 if (handle == 0) 815 if (handle == 0)
775 goto err_out3; 816 goto err_out3;
776 } 817 }
818 lockdep_set_class(qdisc_lock(sch), &qdisc_tx_lock);
777 } 819 }
778 820
779 sch->handle = handle; 821 sch->handle = handle;
@@ -802,8 +844,8 @@ qdisc_create(struct net_device *dev, struct netdev_queue *dev_queue,
802 goto err_out3; 844 goto err_out3;
803 } 845 }
804 } 846 }
805 if ((parent != TC_H_ROOT) && !(sch->flags & TCQ_F_INGRESS)) 847
806 list_add_tail(&sch->list, &dev_queue->qdisc_sleeping->list); 848 qdisc_list_add(sch);
807 849
808 return sch; 850 return sch;
809 } 851 }
@@ -1084,20 +1126,13 @@ create_n_graft:
1084 } 1126 }
1085 1127
1086graft: 1128graft:
1087 if (1) { 1129 err = qdisc_graft(dev, p, skb, n, clid, q, NULL);
1088 spinlock_t *root_lock; 1130 if (err) {
1089 1131 if (q)
1090 err = qdisc_graft(dev, p, skb, n, clid, q, NULL); 1132 qdisc_destroy(q);
1091 if (err) { 1133 return err;
1092 if (q) {
1093 root_lock = qdisc_root_lock(q);
1094 spin_lock_bh(root_lock);
1095 qdisc_destroy(q);
1096 spin_unlock_bh(root_lock);
1097 }
1098 return err;
1099 }
1100 } 1134 }
1135
1101 return 0; 1136 return 0;
1102} 1137}
1103 1138
diff --git a/net/sched/sch_cbq.c b/net/sched/sch_cbq.c
index 4e261ce62f48..8fa90d68ec6d 100644
--- a/net/sched/sch_cbq.c
+++ b/net/sched/sch_cbq.c
@@ -521,6 +521,10 @@ static void cbq_ovl_delay(struct cbq_class *cl)
521 struct cbq_sched_data *q = qdisc_priv(cl->qdisc); 521 struct cbq_sched_data *q = qdisc_priv(cl->qdisc);
522 psched_tdiff_t delay = cl->undertime - q->now; 522 psched_tdiff_t delay = cl->undertime - q->now;
523 523
524 if (test_bit(__QDISC_STATE_DEACTIVATED,
525 &qdisc_root_sleeping(cl->qdisc)->state))
526 return;
527
524 if (!cl->delayed) { 528 if (!cl->delayed) {
525 psched_time_t sched = q->now; 529 psched_time_t sched = q->now;
526 ktime_t expires; 530 ktime_t expires;
@@ -654,7 +658,7 @@ static enum hrtimer_restart cbq_undelay(struct hrtimer *timer)
654 } 658 }
655 659
656 sch->flags &= ~TCQ_F_THROTTLED; 660 sch->flags &= ~TCQ_F_THROTTLED;
657 __netif_schedule(sch); 661 __netif_schedule(qdisc_root(sch));
658 return HRTIMER_NORESTART; 662 return HRTIMER_NORESTART;
659} 663}
660 664
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 468574682caa..5f0ade7806a7 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -518,15 +518,17 @@ void qdisc_reset(struct Qdisc *qdisc)
518} 518}
519EXPORT_SYMBOL(qdisc_reset); 519EXPORT_SYMBOL(qdisc_reset);
520 520
521/* this is the rcu callback function to clean up a qdisc when there 521void qdisc_destroy(struct Qdisc *qdisc)
522 * are no further references to it */
523
524static void __qdisc_destroy(struct rcu_head *head)
525{ 522{
526 struct Qdisc *qdisc = container_of(head, struct Qdisc, q_rcu);
527 const struct Qdisc_ops *ops = qdisc->ops; 523 const struct Qdisc_ops *ops = qdisc->ops;
528 524
525 if (qdisc->flags & TCQ_F_BUILTIN ||
526 !atomic_dec_and_test(&qdisc->refcnt))
527 return;
528
529#ifdef CONFIG_NET_SCHED 529#ifdef CONFIG_NET_SCHED
530 qdisc_list_del(qdisc);
531
530 qdisc_put_stab(qdisc->stab); 532 qdisc_put_stab(qdisc->stab);
531#endif 533#endif
532 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est); 534 gen_kill_estimator(&qdisc->bstats, &qdisc->rate_est);
@@ -542,20 +544,6 @@ static void __qdisc_destroy(struct rcu_head *head)
542 544
543 kfree((char *) qdisc - qdisc->padded); 545 kfree((char *) qdisc - qdisc->padded);
544} 546}
545
546/* Under qdisc_lock(qdisc) and BH! */
547
548void qdisc_destroy(struct Qdisc *qdisc)
549{
550 if (qdisc->flags & TCQ_F_BUILTIN ||
551 !atomic_dec_and_test(&qdisc->refcnt))
552 return;
553
554 if (qdisc->parent)
555 list_del(&qdisc->list);
556
557 call_rcu(&qdisc->q_rcu, __qdisc_destroy);
558}
559EXPORT_SYMBOL(qdisc_destroy); 547EXPORT_SYMBOL(qdisc_destroy);
560 548
561static bool dev_all_qdisc_sleeping_noop(struct net_device *dev) 549static bool dev_all_qdisc_sleeping_noop(struct net_device *dev)
@@ -597,6 +585,9 @@ static void transition_one_qdisc(struct net_device *dev,
597 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping; 585 struct Qdisc *new_qdisc = dev_queue->qdisc_sleeping;
598 int *need_watchdog_p = _need_watchdog; 586 int *need_watchdog_p = _need_watchdog;
599 587
588 if (!(new_qdisc->flags & TCQ_F_BUILTIN))
589 clear_bit(__QDISC_STATE_DEACTIVATED, &new_qdisc->state);
590
600 rcu_assign_pointer(dev_queue->qdisc, new_qdisc); 591 rcu_assign_pointer(dev_queue->qdisc, new_qdisc);
601 if (need_watchdog_p && new_qdisc != &noqueue_qdisc) 592 if (need_watchdog_p && new_qdisc != &noqueue_qdisc)
602 *need_watchdog_p = 1; 593 *need_watchdog_p = 1;
@@ -640,6 +631,9 @@ static void dev_deactivate_queue(struct net_device *dev,
640 if (qdisc) { 631 if (qdisc) {
641 spin_lock_bh(qdisc_lock(qdisc)); 632 spin_lock_bh(qdisc_lock(qdisc));
642 633
634 if (!(qdisc->flags & TCQ_F_BUILTIN))
635 set_bit(__QDISC_STATE_DEACTIVATED, &qdisc->state);
636
643 dev_queue->qdisc = qdisc_default; 637 dev_queue->qdisc = qdisc_default;
644 qdisc_reset(qdisc); 638 qdisc_reset(qdisc);
645 639
@@ -647,7 +641,7 @@ static void dev_deactivate_queue(struct net_device *dev,
647 } 641 }
648} 642}
649 643
650static bool some_qdisc_is_busy(struct net_device *dev, int lock) 644static bool some_qdisc_is_busy(struct net_device *dev)
651{ 645{
652 unsigned int i; 646 unsigned int i;
653 647
@@ -661,14 +655,12 @@ static bool some_qdisc_is_busy(struct net_device *dev, int lock)
661 q = dev_queue->qdisc_sleeping; 655 q = dev_queue->qdisc_sleeping;
662 root_lock = qdisc_lock(q); 656 root_lock = qdisc_lock(q);
663 657
664 if (lock) 658 spin_lock_bh(root_lock);
665 spin_lock_bh(root_lock);
666 659
667 val = (test_bit(__QDISC_STATE_RUNNING, &q->state) || 660 val = (test_bit(__QDISC_STATE_RUNNING, &q->state) ||
668 test_bit(__QDISC_STATE_SCHED, &q->state)); 661 test_bit(__QDISC_STATE_SCHED, &q->state));
669 662
670 if (lock) 663 spin_unlock_bh(root_lock);
671 spin_unlock_bh(root_lock);
672 664
673 if (val) 665 if (val)
674 return true; 666 return true;
@@ -678,8 +670,6 @@ static bool some_qdisc_is_busy(struct net_device *dev, int lock)
678 670
679void dev_deactivate(struct net_device *dev) 671void dev_deactivate(struct net_device *dev)
680{ 672{
681 bool running;
682
683 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc); 673 netdev_for_each_tx_queue(dev, dev_deactivate_queue, &noop_qdisc);
684 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc); 674 dev_deactivate_queue(dev, &dev->rx_queue, &noop_qdisc);
685 675
@@ -689,25 +679,8 @@ void dev_deactivate(struct net_device *dev)
689 synchronize_rcu(); 679 synchronize_rcu();
690 680
691 /* Wait for outstanding qdisc_run calls. */ 681 /* Wait for outstanding qdisc_run calls. */
692 do { 682 while (some_qdisc_is_busy(dev))
693 while (some_qdisc_is_busy(dev, 0)) 683 yield();
694 yield();
695
696 /*
697 * Double-check inside queue lock to ensure that all effects
698 * of the queue run are visible when we return.
699 */
700 running = some_qdisc_is_busy(dev, 1);
701
702 /*
703 * The running flag should never be set at this point because
704 * we've already set dev->qdisc to noop_qdisc *inside* the same
705 * pair of spin locks. That is, if any qdisc_run starts after
706 * our initial test it should see the noop_qdisc and then
707 * clear the RUNNING bit before dropping the queue lock. So
708 * if it is set here then we've found a bug.
709 */
710 } while (WARN_ON_ONCE(running));
711} 684}
712 685
713static void dev_init_scheduler_queue(struct net_device *dev, 686static void dev_init_scheduler_queue(struct net_device *dev,
@@ -736,14 +709,10 @@ static void shutdown_scheduler_queue(struct net_device *dev,
736 struct Qdisc *qdisc_default = _qdisc_default; 709 struct Qdisc *qdisc_default = _qdisc_default;
737 710
738 if (qdisc) { 711 if (qdisc) {
739 spinlock_t *root_lock = qdisc_lock(qdisc);
740
741 dev_queue->qdisc = qdisc_default; 712 dev_queue->qdisc = qdisc_default;
742 dev_queue->qdisc_sleeping = qdisc_default; 713 dev_queue->qdisc_sleeping = qdisc_default;
743 714
744 spin_lock_bh(root_lock);
745 qdisc_destroy(qdisc); 715 qdisc_destroy(qdisc);
746 spin_unlock_bh(root_lock);
747 } 716 }
748} 717}
749 718
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 6febd245e62b..0df0df202ed0 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -577,7 +577,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch)
577 sch->qstats.drops++; 577 sch->qstats.drops++;
578 cl->qstats.drops++; 578 cl->qstats.drops++;
579 } 579 }
580 return NET_XMIT_DROP; 580 return ret;
581 } else { 581 } else {
582 cl->bstats.packets += 582 cl->bstats.packets +=
583 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1; 583 skb_is_gso(skb)?skb_shinfo(skb)->gso_segs:1;
@@ -623,7 +623,7 @@ static int htb_requeue(struct sk_buff *skb, struct Qdisc *sch)
623 sch->qstats.drops++; 623 sch->qstats.drops++;
624 cl->qstats.drops++; 624 cl->qstats.drops++;
625 } 625 }
626 return NET_XMIT_DROP; 626 return ret;
627 } else 627 } else
628 htb_activate(q, cl); 628 htb_activate(q, cl);
629 629
diff --git a/net/sched/sch_prio.c b/net/sched/sch_prio.c
index eac197610edf..a6697c686c7f 100644
--- a/net/sched/sch_prio.c
+++ b/net/sched/sch_prio.c
@@ -113,11 +113,11 @@ prio_requeue(struct sk_buff *skb, struct Qdisc* sch)
113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) { 113 if ((ret = qdisc->ops->requeue(skb, qdisc)) == NET_XMIT_SUCCESS) {
114 sch->q.qlen++; 114 sch->q.qlen++;
115 sch->qstats.requeues++; 115 sch->qstats.requeues++;
116 return 0; 116 return NET_XMIT_SUCCESS;
117 } 117 }
118 if (net_xmit_drop_count(ret)) 118 if (net_xmit_drop_count(ret))
119 sch->qstats.drops++; 119 sch->qstats.drops++;
120 return NET_XMIT_DROP; 120 return ret;
121} 121}
122 122
123 123
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c
index 7d3b7ff3bf07..94c61598b86a 100644
--- a/net/sched/sch_tbf.c
+++ b/net/sched/sch_tbf.c
@@ -123,15 +123,8 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc* sch)
123 struct tbf_sched_data *q = qdisc_priv(sch); 123 struct tbf_sched_data *q = qdisc_priv(sch);
124 int ret; 124 int ret;
125 125
126 if (qdisc_pkt_len(skb) > q->max_size) { 126 if (qdisc_pkt_len(skb) > q->max_size)
127 sch->qstats.drops++; 127 return qdisc_reshape_fail(skb, sch);
128#ifdef CONFIG_NET_CLS_ACT
129 if (sch->reshape_fail == NULL || sch->reshape_fail(skb, sch))
130#endif
131 kfree_skb(skb);
132
133 return NET_XMIT_DROP;
134 }
135 128
136 ret = qdisc_enqueue(skb, q->qdisc); 129 ret = qdisc_enqueue(skb, q->qdisc);
137 if (ret != 0) { 130 if (ret != 0) {