diff options
author | Thomas Graf <tgraf@suug.ch> | 2004-12-19 23:13:21 -0800 |
---|---|---|
committer | David S. Miller <davem@nuts.davemloft.net> | 2004-12-19 23:13:21 -0800 |
commit | ee6fa69bab390c192b760c138603b270c05aa803 (patch) | |
tree | 1fe3a1a668dfa4afd63431eb072b7f95cca53341 /net | |
parent | 1777c9de754bd46189e7ad84cc7b9c6d24ee1bb9 (diff) | |
download | history-ee6fa69bab390c192b760c138603b270c05aa803.tar.gz |
[PKT_SCHED]: Fix double locking in tcindex destroy path.
tcindex's destroy uses its own delete functions to destroy its
configuration. The delete function (correctly) takes the qdisc_tree_lock
to prevent list walkings from happening while removing from the list.
The qdisc_tree_lock is already held if we're comming via the destroy
path and thus a double locking takes place.
Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/sched/cls_tcindex.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c index 709cf821252ab4..c520afb5b0455b 100644 --- a/net/sched/cls_tcindex.c +++ b/net/sched/cls_tcindex.c @@ -160,7 +160,8 @@ static int tcindex_init(struct tcf_proto *tp) } -static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) +static int +__tcindex_delete(struct tcf_proto *tp, unsigned long arg, int lock) { struct tcindex_data *p = PRIV(tp); struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; @@ -182,9 +183,11 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) found: f = *walk; - tcf_tree_lock(tp); + if (lock) + tcf_tree_lock(tp); *walk = f->next; - tcf_tree_unlock(tp); + if (lock) + tcf_tree_unlock(tp); } tcf_unbind_filter(tp, &r->res); #ifdef CONFIG_NET_CLS_POLICE @@ -195,6 +198,10 @@ found: return 0; } +static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) +{ + return __tcindex_delete(tp, arg, 1); +} /* * There are no parameters for tcindex_init, so we overload tcindex_change @@ -384,7 +391,7 @@ static void tcindex_walk(struct tcf_proto *tp, struct tcf_walker *walker) static int tcindex_destroy_element(struct tcf_proto *tp, unsigned long arg, struct tcf_walker *walker) { - return tcindex_delete(tp,arg); + return __tcindex_delete(tp, arg, 0); } |