diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-19 00:03:15 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-19 00:06:19 -0400 |
commit | 4d8863a29c4755a0461cd31b6865026187d6c43a (patch) | |
tree | 502b355314b1ff2e6cef52bf3778aba3bdae80cd /net/sched/sch_api.c | |
parent | 25bfcd5a78a377ea4c54a3c21e44590e2fc478a6 (diff) |
pkt_sched: Don't hold qdisc lock over qdisc_destroy().
Based upon reports by Denys Fedoryshchenko, and feedback
and help from Jarek Poplawski and Herbert Xu.
We always either:
1) Never made an external reference to this qdisc.
or
2) Did a dev_deactivate() which purged all asynchronous
references.
So do not lock the qdisc when we call qdisc_destroy(),
it's illegal anyways as when we drop the lock this is
free'd memory.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 13 |
1 files changed, 2 insertions, 11 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 7d7070b1eebd..d91a2338877c 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -638,11 +638,8 @@ static void notify_and_destroy(struct sk_buff *skb, struct nlmsghdr *n, u32 clid | |||
638 | if (new || old) | 638 | if (new || old) |
639 | qdisc_notify(skb, n, clid, old, new); | 639 | qdisc_notify(skb, n, clid, old, new); |
640 | 640 | ||
641 | if (old) { | 641 | if (old) |
642 | sch_tree_lock(old); | ||
643 | qdisc_destroy(old); | 642 | qdisc_destroy(old); |
644 | sch_tree_unlock(old); | ||
645 | } | ||
646 | } | 643 | } |
647 | 644 | ||
648 | /* Graft qdisc "new" to class "classid" of qdisc "parent" or | 645 | /* Graft qdisc "new" to class "classid" of qdisc "parent" or |
@@ -1092,16 +1089,10 @@ create_n_graft: | |||
1092 | 1089 | ||
1093 | graft: | 1090 | graft: |
1094 | if (1) { | 1091 | if (1) { |
1095 | spinlock_t *root_lock; | ||
1096 | |||
1097 | err = qdisc_graft(dev, p, skb, n, clid, q, NULL); | 1092 | err = qdisc_graft(dev, p, skb, n, clid, q, NULL); |
1098 | if (err) { | 1093 | if (err) { |
1099 | if (q) { | 1094 | if (q) |
1100 | root_lock = qdisc_root_lock(q); | ||
1101 | spin_lock_bh(root_lock); | ||
1102 | qdisc_destroy(q); | 1095 | qdisc_destroy(q); |
1103 | spin_unlock_bh(root_lock); | ||
1104 | } | ||
1105 | return err; | 1096 | return err; |
1106 | } | 1097 | } |
1107 | } | 1098 | } |