diff options
Diffstat (limited to 'net/sched/cls_bpf.c')
| -rw-r--r-- | net/sched/cls_bpf.c | 19 | 
1 files changed, 17 insertions, 2 deletions
| diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 520c5027646a..037a3ae86829 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c @@ -49,7 +49,10 @@ struct cls_bpf_prog {  	struct sock_filter *bpf_ops;  	const char *bpf_name;  	struct tcf_proto *tp; -	struct rcu_head rcu; +	union { +		struct work_struct work; +		struct rcu_head rcu; +	};  };  static const struct nla_policy bpf_policy[TCA_BPF_MAX + 1] = { @@ -257,9 +260,21 @@ static void __cls_bpf_delete_prog(struct cls_bpf_prog *prog)  	kfree(prog);  } +static void cls_bpf_delete_prog_work(struct work_struct *work) +{ +	struct cls_bpf_prog *prog = container_of(work, struct cls_bpf_prog, work); + +	rtnl_lock(); +	__cls_bpf_delete_prog(prog); +	rtnl_unlock(); +} +  static void cls_bpf_delete_prog_rcu(struct rcu_head *rcu)  { -	__cls_bpf_delete_prog(container_of(rcu, struct cls_bpf_prog, rcu)); +	struct cls_bpf_prog *prog = container_of(rcu, struct cls_bpf_prog, rcu); + +	INIT_WORK(&prog->work, cls_bpf_delete_prog_work); +	tcf_queue_work(&prog->work);  }  static void __cls_bpf_delete(struct tcf_proto *tp, struct cls_bpf_prog *prog) | 
