diff options
-rw-r--r-- | net/sched/cls_matchall.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/net/sched/cls_matchall.c b/net/sched/cls_matchall.c index 38c0a9f0f296..a30d2f8feb32 100644 --- a/net/sched/cls_matchall.c +++ b/net/sched/cls_matchall.c | |||
@@ -21,6 +21,7 @@ struct cls_mall_head { | |||
21 | unsigned int in_hw_count; | 21 | unsigned int in_hw_count; |
22 | struct tc_matchall_pcnt __percpu *pf; | 22 | struct tc_matchall_pcnt __percpu *pf; |
23 | struct rcu_work rwork; | 23 | struct rcu_work rwork; |
24 | bool deleting; | ||
24 | }; | 25 | }; |
25 | 26 | ||
26 | static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, | 27 | static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
@@ -258,7 +259,11 @@ err_exts_init: | |||
258 | static int mall_delete(struct tcf_proto *tp, void *arg, bool *last, | 259 | static int mall_delete(struct tcf_proto *tp, void *arg, bool *last, |
259 | bool rtnl_held, struct netlink_ext_ack *extack) | 260 | bool rtnl_held, struct netlink_ext_ack *extack) |
260 | { | 261 | { |
261 | return -EOPNOTSUPP; | 262 | struct cls_mall_head *head = rtnl_dereference(tp->root); |
263 | |||
264 | head->deleting = true; | ||
265 | *last = true; | ||
266 | return 0; | ||
262 | } | 267 | } |
263 | 268 | ||
264 | static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg, | 269 | static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg, |
@@ -269,7 +274,7 @@ static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg, | |||
269 | if (arg->count < arg->skip) | 274 | if (arg->count < arg->skip) |
270 | goto skip; | 275 | goto skip; |
271 | 276 | ||
272 | if (!head) | 277 | if (!head || head->deleting) |
273 | return; | 278 | return; |
274 | if (arg->fn(tp, head, arg) < 0) | 279 | if (arg->fn(tp, head, arg) < 0) |
275 | arg->stop = 1; | 280 | arg->stop = 1; |