Re: [PATCH v2 bpf-next 05/14] bpf: allow to specify user-provided context value for BPF perf links
From: Yonghong Song <hidden>
Date: 2021-07-29 18:00:34
On 7/26/21 9:12 AM, Andrii Nakryiko wrote:
quoted hunk ↗ jump to hunk
Add ability for users to specify custom u64 value when creating BPF link for perf_event-backed BPF programs (kprobe/uprobe, perf_event, tracepoints). This is useful for cases when the same BPF program is used for attaching and processing invocation of different tracepoints/kprobes/uprobes in a generic fashion, but such that each invocation is distinguished from each other (e.g., BPF program can look up additional information associated with a specific kernel function without having to rely on function IP lookups). This enables new use cases to be implemented simply and efficiently that previously were possible only through code generation (and thus multiple instances of almost identical BPF program) or compilation at runtime (BCC-style) on target hosts (even more expensive resource-wise). For uprobes it is not even possible in some cases to know function IP before hand (e.g., when attaching to shared library without PID filtering, in which case base load address is not known for a library). This is done by storing u64 user_ctx in struct bpf_prog_array_item, corresponding to each attached and run BPF program. Given cgroup BPF programs already use 2 8-byte pointers for their needs and cgroup BPF programs don't have (yet?) support for user_ctx, reuse that space through union of cgroup_storage and new user_ctx field. Make it available to kprobe/tracepoint BPF programs through bpf_trace_run_ctx. This is set by BPF_PROG_RUN_ARRAY, used by kprobe/uprobe/tracepoint BPF program execution code, which luckily is now also split from BPF_PROG_RUN_ARRAY_CG. This run context will be utilized by a new BPF helper giving access to this user context value from inside a BPF program. Generic perf_event BPF programs will access this value from perf_event itself through passed in BPF program context. Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> --- drivers/media/rc/bpf-lirc.c | 4 ++-- include/linux/bpf.h | 16 +++++++++++++++- include/linux/perf_event.h | 1 + include/linux/trace_events.h | 6 +++--- include/uapi/linux/bpf.h | 7 +++++++ kernel/bpf/core.c | 29 ++++++++++++++++++----------- kernel/bpf/syscall.c | 2 +- kernel/events/core.c | 21 ++++++++++++++------- kernel/trace/bpf_trace.c | 8 +++++--- tools/include/uapi/linux/bpf.h | 7 +++++++ 10 files changed, 73 insertions(+), 28 deletions(-)diff --git a/drivers/media/rc/bpf-lirc.c b/drivers/media/rc/bpf-lirc.c index afae0afe3f81..7490494273e4 100644 --- a/drivers/media/rc/bpf-lirc.c +++ b/drivers/media/rc/bpf-lirc.c@@ -160,7 +160,7 @@ static int lirc_bpf_attach(struct rc_dev *rcdev, struct bpf_prog *prog) goto unlock; } - ret = bpf_prog_array_copy(old_array, NULL, prog, &new_array); + ret = bpf_prog_array_copy(old_array, NULL, prog, 0, &new_array); if (ret < 0) goto unlock;
[...]
quoted hunk ↗ jump to hunk
void bpf_trace_run1(struct bpf_prog *prog, u64 arg1);diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 00b1267ab4f0..bc1fd54a8f58 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h@@ -1448,6 +1448,13 @@ union bpf_attr { __aligned_u64 iter_info; /* extra bpf_iter_link_info */ __u32 iter_info_len; /* iter_info length */ }; + struct { + /* black box user-provided value passed through + * to BPF program at the execution time and + * accessible through bpf_get_user_ctx() BPF helper + */ + __u64 user_ctx; + } perf_event;
Is it possible to fold this field into previous union?
union {
__u32 target_btf_id; /* btf_id of
target to attach to */
struct {
__aligned_u64 iter_info; /*
extra bpf_iter_link_info */
__u32 iter_info_len; /*
iter_info length */
};
};
}; } link_create;
[...]