aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPatrick McHardy <kaber@trash.net>2004-08-03 19:24:45 -0700
committerDavid S. Miller <davem@nuts.davemloft.net>2004-08-03 19:24:45 -0700
commite30421178c47ace2aa492114be615115c137b1b2 (patch)
tree6691af72ffc1693a372bf32d3668464d3946a9aa /net
parent10cf6595ebba3ea12233b7ff459fa68798d7ff21 (diff)
downloadhistory-e30421178c47ace2aa492114be615115c137b1b2.tar.gz
[PKT_SCHED]: Refcount qdisc->dev for __qdisc_destroy rcu-callback
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@redhat.com>
Diffstat (limited to 'net')
-rw-r--r--net/sched/sch_api.c1
-rw-r--r--net/sched/sch_generic.c3
2 files changed, 4 insertions, 0 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 5d601c2cf48182..f73f495d44d308 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -430,6 +430,7 @@ qdisc_create(struct net_device *dev, u32 handle, struct rtattr **tca, int *errp)
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev = dev;
+ dev_hold(dev);
atomic_set(&sch->refcnt, 1);
sch->stats_lock = &dev->queue_lock;
if (handle == 0) {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 34c75b5020b2c1..deed19c3e9012b 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -399,6 +399,7 @@ struct Qdisc * qdisc_create_dflt(struct net_device *dev, struct Qdisc_ops *ops)
sch->enqueue = ops->enqueue;
sch->dequeue = ops->dequeue;
sch->dev = dev;
+ dev_hold(dev);
sch->stats_lock = &dev->queue_lock;
atomic_set(&sch->refcnt, 1);
/* enqueue is accessed locklessly - make sure it's visible
@@ -440,6 +441,8 @@ static void __qdisc_destroy(struct rcu_head *head)
write_unlock(&qdisc_tree_lock);
module_put(ops->owner);
+ if (qdisc->dev)
+ dev_put(qdisc->dev);
if (!(qdisc->flags&TCQ_F_BUILTIN))
kfree(qdisc);
}