Skip to content

Commit 0552c8a

Browse files
congwangdavem330
authored andcommitted
net_sched: use tcf_queue_work() in flower filter
Defer the tcf_exts_destroy() in RCU callback to tc filter workqueue and get RTNL lock. Reported-by: Chris Mi <[email protected]> Cc: Daniel Borkmann <[email protected]> Cc: Jiri Pirko <[email protected]> Cc: John Fastabend <[email protected]> Cc: Jamal Hadi Salim <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 94cdb47 commit 0552c8a

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

net/sched/cls_flower.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ struct cls_fl_filter {
8787
struct list_head list;
8888
u32 handle;
8989
u32 flags;
90-
struct rcu_head rcu;
90+
union {
91+
struct work_struct work;
92+
struct rcu_head rcu;
93+
};
9194
struct net_device *hw_dev;
9295
};
9396

@@ -215,12 +218,22 @@ static int fl_init(struct tcf_proto *tp)
215218
return 0;
216219
}
217220

218-
static void fl_destroy_filter(struct rcu_head *head)
221+
static void fl_destroy_filter_work(struct work_struct *work)
219222
{
220-
struct cls_fl_filter *f = container_of(head, struct cls_fl_filter, rcu);
223+
struct cls_fl_filter *f = container_of(work, struct cls_fl_filter, work);
221224

225+
rtnl_lock();
222226
tcf_exts_destroy(&f->exts);
223227
kfree(f);
228+
rtnl_unlock();
229+
}
230+
231+
static void fl_destroy_filter(struct rcu_head *head)
232+
{
233+
struct cls_fl_filter *f = container_of(head, struct cls_fl_filter, rcu);
234+
235+
INIT_WORK(&f->work, fl_destroy_filter_work);
236+
tcf_queue_work(&f->work);
224237
}
225238

226239
static void fl_hw_destroy_filter(struct tcf_proto *tp, struct cls_fl_filter *f)

0 commit comments

Comments
 (0)