summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2020-09-29 23:09:24 +0300
committerAlexei Starovoitov <ast@kernel.org>2020-09-29 23:12:03 +0300
commit93b8713d61982377faf2f87994a303c6f7df0162 (patch)
tree1963385635b40446667c35f61b2bf74f1c9779d1 /include
parent85e3f318506ece12714535821d0b3186f7121b5b (diff)
parentbee4b7e6268be9267e288936f5b1215fec3d4368 (diff)
downloadlinux-93b8713d61982377faf2f87994a303c6f7df0162.tar.xz
Merge branch 'bpf: Support multi-attach for freplace'
Toke Høiland-Jørgensen says: ==================== This series adds support attaching freplace BPF programs to multiple targets. This is needed to support incremental attachment of multiple XDP programs using the libxdp dispatcher model. Patch 1 moves prog_aux->linked_prog and the trampoline to be embedded in bpf_tracing_link on attach, and freed by the link release logic, and introduces a mutex to protect the writing of the pointers in prog->aux. Based on this refactoring (and previously applied patches), it becomes pretty straight-forward to support multiple-attach for freplace programs (patch 2). This is simply a matter of creating a second bpf_tracing_link if a target is supplied. However, for API consistency with other types of link attach, this option is added to the BPF_LINK_CREATE API instead of extending bpf_raw_tracepoint_open(). Patch 3 is a port of Jiri Olsa's patch to support fentry/fexit on freplace programs. His approach of getting the target type from the target program reference no longer works after we've gotten rid of linked_prog (because the bpf_tracing_link reference disappears on attach). Instead, we used the saved reference to the target prog type that is also used to verify compatibility on secondary freplace attachment. Patch 4 is the accompanying libbpf update, and patches 5-7 are selftests: patch 5 tests for the multi-freplace functionality itself; patch 6 is Jiri's previous selftest for the fentry-to-freplace fix; patch 7 is a test for the change introduced in the previously-applied patches, blocking MODIFY_RETURN functions from attaching to other BPF programs. With this series, libxdp and xdp-tools can successfully attach multiple programs one at a time. To play with this, use the 'freplace-multi-attach' branch of xdp-tools: $ git clone --recurse-submodules --branch freplace-multi-attach https://github.com/xdp-project/xdp-tools $ cd xdp-tools/xdp-loader $ make $ sudo ./xdp-loader load veth0 ../lib/testing/xdp_drop.o $ sudo ./xdp-loader load veth0 ../lib/testing/xdp_pass.o $ sudo ./xdp-loader status The series is also available here: https://git.kernel.org/pub/scm/linux/kernel/git/toke/linux.git/log/?h=bpf-freplace-multi-attach-alt-10 Changelog: v10: - Dial back the s/tgt_/dst_/ replacement a bit - Fix smatch warning (from ktest robot) - Rebase to bpf-next, drop already-applied patches v9: - Clarify commit message of patch 3 - Add new struct bpf_attach_target_info for returning from bpf_check_attach_target() and passing to bpf_trampoline_get() - Move trampoline key computation into a helper - Make sure we don't break bpffs debug umh - Add some comment blocks explaining the logic flow in bpf_tracing_prog_attach() - s/tgt_/dst_/ in prog->aux, and for local variables using those members - Always drop dst_trampoline and dst_prog from prog->aux on first attach - Don't remove syscall fmod_ret test from selftest benchmarks - Add saved_ prefix to dst_{prog,attach}_type members in prog_aux - Drop prog argument from check_attach_modify_return() - Add comment about possible NULL of tr_link->tgt_prog on link_release() v8: - Add a separate error message when trying to attach FMOD_REPLACE to tgt_prog - Better error messages in bpf_program__attach_freplace() - Don't lock mutex when setting tgt_* pointers in prog create and verifier - Remove fmod_ret programs from benchmarks in selftests (new patch 11) - Fix a few other nits in selftests v7: - Add back missing ptype == prog->type check in link_create() - Use tracing_bpf_link_attach() instead of separate freplace_bpf_link_attach() - Don't break attachment of bpf_iters in libbpf (by clobbering link_create.iter_info) v6: - Rebase to latest bpf-next - Simplify logic in bpf_tracing_prog_attach() - Don't create a new attach_type for link_create(), disambiguate on prog->type instead - Use raw_tracepoint_open() in libbpf bpf_program__attach_ftrace() if called with NULL target - Switch bpf_program__attach_ftrace() to take function name as parameter instead of btf_id - Add a patch disallowing MODIFY_RETURN programs from attaching to other BPF programs, and an accompanying selftest (patches 1 and 10) v5: - Fix typo in inline function definition of bpf_trampoline_get() - Don't put bpf_tracing_link in prog->aux, use a mutex to protect tgt_prog and trampoline instead, and move them to the link on attach. - Restore Jiri as author of the last selftest patch v4: - Cleanup the refactored check_attach_btf_id() to make the logic easier to follow - Fix cleanup paths for bpf_tracing_link - Use xchg() for removing the bpf_tracing_link from prog->aux and restore on (some) failures - Use BPF_LINK_CREATE operation to create link with target instead of extending raw_tracepoint_open - Fold update of tools/ UAPI header into main patch - Update arg dereference patch to use skeletons and set_attach_target() v3: - Get rid of prog_aux->linked_prog entirely in favour of a bpf_tracing_link - Incorporate Jiri's fix for attaching fentry to freplace programs v2: - Drop the log arguments from bpf_raw_tracepoint_open - Fix kbot errors - Rebase to latest bpf-next ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/linux/bpf.h17
-rw-r--r--include/uapi/linux/bpf.h9
2 files changed, 18 insertions, 8 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 768b533ba48e..50e5c4b52bd1 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -640,8 +640,8 @@ static __always_inline unsigned int bpf_dispatcher_nop_func(
return bpf_func(ctx, insnsi);
}
#ifdef CONFIG_BPF_JIT
-int bpf_trampoline_link_prog(struct bpf_prog *prog);
-int bpf_trampoline_unlink_prog(struct bpf_prog *prog);
+int bpf_trampoline_link_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
+int bpf_trampoline_unlink_prog(struct bpf_prog *prog, struct bpf_trampoline *tr);
struct bpf_trampoline *bpf_trampoline_get(u64 key,
struct bpf_attach_target_info *tgt_info);
void bpf_trampoline_put(struct bpf_trampoline *tr);
@@ -688,11 +688,13 @@ void bpf_image_ksym_del(struct bpf_ksym *ksym);
void bpf_ksym_add(struct bpf_ksym *ksym);
void bpf_ksym_del(struct bpf_ksym *ksym);
#else
-static inline int bpf_trampoline_link_prog(struct bpf_prog *prog)
+static inline int bpf_trampoline_link_prog(struct bpf_prog *prog,
+ struct bpf_trampoline *tr)
{
return -ENOTSUPP;
}
-static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog)
+static inline int bpf_trampoline_unlink_prog(struct bpf_prog *prog,
+ struct bpf_trampoline *tr)
{
return -ENOTSUPP;
}
@@ -763,7 +765,11 @@ struct bpf_prog_aux {
u32 max_rdonly_access;
u32 max_rdwr_access;
const struct bpf_ctx_arg_aux *ctx_arg_info;
- struct bpf_prog *linked_prog;
+ struct mutex dst_mutex; /* protects dst_* pointers below, *after* prog becomes visible */
+ struct bpf_prog *dst_prog;
+ struct bpf_trampoline *dst_trampoline;
+ enum bpf_prog_type saved_dst_prog_type;
+ enum bpf_attach_type saved_dst_attach_type;
bool verifier_zext; /* Zero extensions has been inserted by verifier. */
bool offload_requested;
bool attach_btf_trace; /* true if attaching to BTF-enabled raw tp */
@@ -771,7 +777,6 @@ struct bpf_prog_aux {
bool sleepable;
bool tail_call_reachable;
enum bpf_tramp_prog_type trampoline_prog_type;
- struct bpf_trampoline *trampoline;
struct hlist_node tramp_hlist;
/* BTF_KIND_FUNC_PROTO for valid attach_btf_id */
const struct btf_type *attach_func_proto;
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 96ddb00b91dc..2b1d3f16cbd1 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -639,8 +639,13 @@ union bpf_attr {
};
__u32 attach_type; /* attach type */
__u32 flags; /* extra flags */
- __aligned_u64 iter_info; /* extra bpf_iter_link_info */
- __u32 iter_info_len; /* iter_info length */
+ 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;
struct { /* struct used by BPF_LINK_UPDATE command */