Messages in this thread Patch in this message | | | From | Roman Gushchin <> | Subject | [PATCH v2 bpf 3/5] bpf: bpf_prog_array_free() should take a generic non-rcu pointer | Date | Fri, 13 Jul 2018 12:41:12 -0700 |
| |
bpf_prog_array_free() should take a generic non-rcu pointer as an argument, as freeing the objects assumes that we're holding an exclusive rights on it.
rcu_access_pointer() can be used to convert a __rcu pointer to a generic pointer before passing it to bpf_prog_array_free(), if necessary.
This patch eliminates the following sparse warning: kernel/bpf/core.c:1556:9: warning: incorrect type in argument 1 (different address spaces) kernel/bpf/core.c:1556:9: expected struct callback_head *head kernel/bpf/core.c:1556:9: got struct callback_head [noderef] <asn:4>*<noident>
Fixes: 324bda9e6c5a ("bpf: multi program support for cgroup+bpf") Signed-off-by: Roman Gushchin <guro@fb.com> Cc: Alexei Starovoitov <ast@kernel.org> Cc: Daniel Borkmann <daniel@iogearbox.net> --- drivers/media/rc/bpf-lirc.c | 6 +++--- include/linux/bpf.h | 2 +- kernel/bpf/cgroup.c | 11 ++++++----- kernel/bpf/core.c | 5 ++--- kernel/trace/bpf_trace.c | 8 ++++---- 5 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index fcfab6635f9c..509b262aa0dc 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c @@ -135,7 +135,7 @@ static int lirc_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog) goto unlock; rcu_assign_pointer(raw->progs, new_array); - bpf_prog_array_free(old_array); + bpf_prog_array_free(rcu_access_pointer(old_array)); unlock: mutex_unlock(&ir_raw_handler_lock); @@ -173,7 +173,7 @@ static int lirc_bpf_detach(struct rc_dev *rcdev, struct bpf_prog *prog) goto unlock; rcu_assign_pointer(raw->progs, new_array); - bpf_prog_array_free(old_array); + bpf_prog_array_free(rcu_access_pointer(old_array)); unlock: mutex_unlock(&ir_raw_handler_lock); return ret; @@ -204,7 +204,7 @@ void lirc_bpf_free(struct rc_dev *rcdev) while (*progs) bpf_prog_put(*progs++); - bpf_prog_array_free(rcdev->raw->progs); + bpf_prog_array_free(rcu_access_pointer(rcdev->raw->progs)); } int lirc_prog_attach(const union bpf_attr *attr, struct bpf_prog *prog) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 943fb08d8287..329026baef6e 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -353,7 +353,7 @@ struct bpf_prog_array { }; struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags); -void bpf_prog_array_free(struct bpf_prog_array __rcu *progs); +void bpf_prog_array_free(struct bpf_prog_array *progs); int bpf_prog_array_length(struct bpf_prog_array __rcu *progs); int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs, __u32 __user *prog_ids, u32 cnt); diff --git a/kernel/bpf/cgroup.c b/kernel/bpf/cgroup.c index badabb0b435c..9ac0c9b51d0d 100644 --- a/kernel/bpf/cgroup.c +++ b/kernel/bpf/cgroup.c @@ -37,7 +37,8 @@ void cgroup_bpf_put(struct cgroup *cgrp) kfree(pl); static_branch_dec(&cgroup_bpf_enabled_key); } - bpf_prog_array_free(cgrp->bpf.effective[type]); + bpf_prog_array_free(rcu_access_pointer( + cgrp->bpf.effective[type])); } } @@ -139,7 +140,7 @@ static void activate_effective_progs(struct cgroup *cgrp, /* free prog array after grace period, since __cgroup_bpf_run_*() * might be still walking the array */ - bpf_prog_array_free(old_array); + bpf_prog_array_free(rcu_access_pointer(old_array)); } /** @@ -168,7 +169,7 @@ int cgroup_bpf_inherit(struct cgroup *cgrp) return 0; cleanup: for (i = 0; i < NR; i++) - bpf_prog_array_free(arrays[i]); + bpf_prog_array_free(rcu_access_pointer(arrays[i])); return -ENOMEM; } @@ -270,7 +271,7 @@ int __cgroup_bpf_attach(struct cgroup *cgrp, struct bpf_prog *prog, css_for_each_descendant_pre(css, &cgrp->self) { struct cgroup *desc = container_of(css, struct cgroup, self); - bpf_prog_array_free(desc->bpf.inactive); + bpf_prog_array_free(rcu_access_pointer(desc->bpf.inactive)); desc->bpf.inactive = NULL; } @@ -372,7 +373,7 @@ int __cgroup_bpf_detach(struct cgroup *cgrp, struct bpf_prog *prog, css_for_each_descendant_pre(css, &cgrp->self) { struct cgroup *desc = container_of(css, struct cgroup, self); - bpf_prog_array_free(desc->bpf.inactive); + bpf_prog_array_free(rcu_access_pointer(desc->bpf.inactive)); desc->bpf.inactive = NULL; } diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c index 253aa8e79c7b..fdf961f70deb 100644 --- a/kernel/bpf/core.c +++ b/kernel/bpf/core.c @@ -1548,10 +1548,9 @@ struct bpf_prog_array *bpf_prog_array_alloc(u32 prog_cnt, gfp_t flags) return &empty_prog_array.hdr; } -void bpf_prog_array_free(struct bpf_prog_array __rcu *progs) +void bpf_prog_array_free(struct bpf_prog_array *progs) { - if (!progs || - progs == (struct bpf_prog_array __rcu *)&empty_prog_array.hdr) + if (!progs || progs == &empty_prog_array.hdr) return; kfree_rcu(progs, rcu); } diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c index 0ae6829804bc..5dace25d3088 100644 --- a/kernel/trace/bpf_trace.c +++ b/kernel/trace/bpf_trace.c @@ -995,8 +995,8 @@ int perf_event_attach_bpf_prog(struct perf_event *event, /* set the new array to event->tp_event and set event->prog */ event->prog = prog; - rcu_assign_pointer(event->tp_event->prog_array, new_array); - bpf_prog_array_free(old_array); + rcu_swap_protected(event->tp_event->prog_array, new_array, 1); + bpf_prog_array_free(new_array); unlock: mutex_unlock(&bpf_event_mutex); @@ -1021,8 +1021,8 @@ void perf_event_detach_bpf_prog(struct perf_event *event) if (ret < 0) { bpf_prog_array_delete_safe(old_array, event->prog); } else { - rcu_assign_pointer(event->tp_event->prog_array, new_array); - bpf_prog_array_free(old_array); + rcu_swap_protected(event->tp_event->prog_array, new_array, 1); + bpf_prog_array_free(new_array); } bpf_prog_put(event->prog); -- 2.14.4
| |