diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c index a5212a3f86e2f2e4110c217e92770768e55f0af7..8ff6945b9f8f4db3dc0c87689b700d35a0e6d11c 100644 --- a/net/sched/cls_flower.c +++ b/net/sched/cls_flower.c @@ -2169,18 +2169,24 @@ static void fl_walk(struct tcf_proto *tp, struct tcf_walker *arg, arg->count = arg->skip; + rcu_read_lock(); idr_for_each_entry_continue_ul(&head->handle_idr, f, tmp, id) { /* don't return filters that are being deleted */ if (!refcount_inc_not_zero(&f->refcnt)) continue; + rcu_read_unlock(); + if (arg->fn(tp, f, arg) < 0) { __fl_put(f); arg->stop = 1; + rcu_read_lock(); break; } __fl_put(f); arg->count++; + rcu_read_lock(); } + rcu_read_unlock(); arg->cookie = id; }