aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/cls_api.c11
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);