diff options
Diffstat (limited to 'net/sched/sch_generic.c')
-rw-r--r-- | net/sched/sch_generic.c | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index a91f079fb47a..e7c47ceb0098 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -623,6 +623,31 @@ void qdisc_destroy(struct Qdisc *qdisc) | |||
623 | } | 623 | } |
624 | EXPORT_SYMBOL(qdisc_destroy); | 624 | EXPORT_SYMBOL(qdisc_destroy); |
625 | 625 | ||
626 | /* Attach toplevel qdisc to device queue. */ | ||
627 | struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, | ||
628 | struct Qdisc *qdisc) | ||
629 | { | ||
630 | struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; | ||
631 | spinlock_t *root_lock; | ||
632 | |||
633 | root_lock = qdisc_lock(oqdisc); | ||
634 | spin_lock_bh(root_lock); | ||
635 | |||
636 | /* Prune old scheduler */ | ||
637 | if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) | ||
638 | qdisc_reset(oqdisc); | ||
639 | |||
640 | /* ... and graft new one */ | ||
641 | if (qdisc == NULL) | ||
642 | qdisc = &noop_qdisc; | ||
643 | dev_queue->qdisc_sleeping = qdisc; | ||
644 | rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc); | ||
645 | |||
646 | spin_unlock_bh(root_lock); | ||
647 | |||
648 | return oqdisc; | ||
649 | } | ||
650 | |||
626 | static void attach_one_default_qdisc(struct net_device *dev, | 651 | static void attach_one_default_qdisc(struct net_device *dev, |
627 | struct netdev_queue *dev_queue, | 652 | struct netdev_queue *dev_queue, |
628 | void *_unused) | 653 | void *_unused) |