aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/sched/cls_matchall.c9
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
26static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp, 27static int mall_classify(struct sk_buff *skb, const struct tcf_proto *tp,
@@ -258,7 +259,11 @@ err_exts_init:
258static int mall_delete(struct tcf_proto *tp, void *arg, bool *last, 259static 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
264static void mall_walk(struct tcf_proto *tp, struct tcf_walker *arg, 269static 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;