diff options
author | Patrick McHardy <kaber@trash.net> | 2009-09-04 06:41:20 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-09-06 02:07:05 -0700 |
commit | 589983cd21f4a2e4ed74a958805a90fa676845c5 (patch) | |
tree | 21ce556958da203400d3e9d30911ff330be39e90 /net/sched/sch_generic.c | |
parent | af356afa010f3cd2c8b8fcc3bce90f7a7b7ec02a (diff) |
net_sched: move dev_graft_qdisc() to sch_generic.c
It will be used in a following patch by the multiqueue qdisc.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
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 a91f079fb47..e7c47ceb009 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c @@ -623,6 +623,31 @@ void qdisc_destroy(struct Qdisc *qdisc) } EXPORT_SYMBOL(qdisc_destroy); +/* Attach toplevel qdisc to device queue. */ +struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue, + struct Qdisc *qdisc) +{ + struct Qdisc *oqdisc = dev_queue->qdisc_sleeping; + spinlock_t *root_lock; + + root_lock = qdisc_lock(oqdisc); + spin_lock_bh(root_lock); + + /* Prune old scheduler */ + if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1) + qdisc_reset(oqdisc); + + /* ... and graft new one */ + if (qdisc == NULL) + qdisc = &noop_qdisc; + dev_queue->qdisc_sleeping = qdisc; + rcu_assign_pointer(dev_queue->qdisc, &noop_qdisc); + + spin_unlock_bh(root_lock); + + return oqdisc; +} + static void attach_one_default_qdisc(struct net_device *dev, struct netdev_queue *dev_queue, void *_unused) |