aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/sch_generic.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r--net/sched/sch_generic.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index efa418a1b34e..8cdf0b4a6a5a 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -563,11 +563,15 @@ static void __qdisc_destroy(struct rcu_head *head)
563 563
564void qdisc_destroy(struct Qdisc *qdisc) 564void qdisc_destroy(struct Qdisc *qdisc)
565{ 565{
566 struct net_device *dev = qdisc_dev(qdisc);
567
566 if (qdisc->flags & TCQ_F_BUILTIN || 568 if (qdisc->flags & TCQ_F_BUILTIN ||
567 !atomic_dec_and_test(&qdisc->refcnt)) 569 !atomic_dec_and_test(&qdisc->refcnt))
568 return; 570 return;
569 571
572 spin_lock_bh(&dev->qdisc_list_lock);
570 list_del(&qdisc->list); 573 list_del(&qdisc->list);
574 spin_unlock_bh(&dev->qdisc_list_lock);
571 575
572 call_rcu(&qdisc->q_rcu, __qdisc_destroy); 576 call_rcu(&qdisc->q_rcu, __qdisc_destroy);
573} 577}
@@ -599,7 +603,9 @@ static void attach_one_default_qdisc(struct net_device *dev,
599 printk(KERN_INFO "%s: activation failed\n", dev->name); 603 printk(KERN_INFO "%s: activation failed\n", dev->name);
600 return; 604 return;
601 } 605 }
602 list_add_tail(&qdisc->list, &dev_queue->qdisc_list); 606 spin_lock_bh(&dev->qdisc_list_lock);
607 list_add_tail(&qdisc->list, &dev->qdisc_list);
608 spin_unlock_bh(&dev->qdisc_list_lock);
603 } else { 609 } else {
604 qdisc = &noqueue_qdisc; 610 qdisc = &noqueue_qdisc;
605 } 611 }
@@ -738,7 +744,6 @@ static void dev_init_scheduler_queue(struct net_device *dev,
738 744
739 dev_queue->qdisc = qdisc; 745 dev_queue->qdisc = qdisc;
740 dev_queue->qdisc_sleeping = qdisc; 746 dev_queue->qdisc_sleeping = qdisc;
741 INIT_LIST_HEAD(&dev_queue->qdisc_list);
742} 747}
743 748
744void dev_init_scheduler(struct net_device *dev) 749void dev_init_scheduler(struct net_device *dev)