Commit ee6fa69b authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

[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: default avatarThomas Graf <tgraf@suug.ch>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1777c9de
...@@ -160,7 +160,8 @@ static int tcindex_init(struct tcf_proto *tp) ...@@ -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_data *p = PRIV(tp);
struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg; struct tcindex_filter_result *r = (struct tcindex_filter_result *) arg;
...@@ -182,8 +183,10 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) ...@@ -182,8 +183,10 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
found: found:
f = *walk; f = *walk;
if (lock)
tcf_tree_lock(tp); tcf_tree_lock(tp);
*walk = f->next; *walk = f->next;
if (lock)
tcf_tree_unlock(tp); tcf_tree_unlock(tp);
} }
tcf_unbind_filter(tp, &r->res); tcf_unbind_filter(tp, &r->res);
...@@ -195,6 +198,10 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg) ...@@ -195,6 +198,10 @@ static int tcindex_delete(struct tcf_proto *tp, unsigned long arg)
return 0; 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 * 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) ...@@ -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, static int tcindex_destroy_element(struct tcf_proto *tp,
unsigned long arg, struct tcf_walker *walker) unsigned long arg, struct tcf_walker *walker)
{ {
return tcindex_delete(tp,arg); return __tcindex_delete(tp, arg, 0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment