diff options
Diffstat (limited to 'net/sched')
-rw-r--r-- | net/sched/cls_api.c | 11 |
1 files changed, 7 insertions, 4 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index d0b0a9b14394..d2b6f54a6261 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -120,6 +120,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) | |||
120 | { | 120 | { |
121 | struct net *net = sock_net(skb->sk); | 121 | struct net *net = sock_net(skb->sk); |
122 | struct nlattr *tca[TCA_MAX + 1]; | 122 | struct nlattr *tca[TCA_MAX + 1]; |
123 | spinlock_t *root_lock; | ||
123 | struct tcmsg *t; | 124 | struct tcmsg *t; |
124 | u32 protocol; | 125 | u32 protocol; |
125 | u32 prio; | 126 | u32 prio; |
@@ -204,6 +205,8 @@ replay: | |||
204 | } | 205 | } |
205 | } | 206 | } |
206 | 207 | ||
208 | root_lock = qdisc_root_lock(q); | ||
209 | |||
207 | if (tp == NULL) { | 210 | if (tp == NULL) { |
208 | /* Proto-tcf does not exist, create new one */ | 211 | /* Proto-tcf does not exist, create new one */ |
209 | 212 | ||
@@ -263,10 +266,10 @@ replay: | |||
263 | goto errout; | 266 | goto errout; |
264 | } | 267 | } |
265 | 268 | ||
266 | qdisc_lock_tree(dev); | 269 | spin_lock_bh(root_lock); |
267 | tp->next = *back; | 270 | tp->next = *back; |
268 | *back = tp; | 271 | *back = tp; |
269 | qdisc_unlock_tree(dev); | 272 | spin_unlock_bh(root_lock); |
270 | 273 | ||
271 | } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) | 274 | } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind)) |
272 | goto errout; | 275 | goto errout; |
@@ -275,9 +278,9 @@ replay: | |||
275 | 278 | ||
276 | if (fh == 0) { | 279 | if (fh == 0) { |
277 | if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { | 280 | if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { |
278 | qdisc_lock_tree(dev); | 281 | spin_lock_bh(root_lock); |
279 | *back = tp->next; | 282 | *back = tp->next; |
280 | qdisc_unlock_tree(dev); | 283 | spin_lock_bh(root_lock); |
281 | 284 | ||
282 | tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); | 285 | tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); |
283 | tcf_destroy(tp); | 286 | tcf_destroy(tp); |