Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libbpf: Add support for uprobe multi session attach

Adding support to attach program in uprobe session mode
with bpf_program__attach_uprobe_multi function.

Adding session bool to bpf_uprobe_multi_opts struct that allows
to load and attach the bpf program via uprobe session.
the attachment to create uprobe multi session.

Also adding new program loader section that allows:
SEC("uprobe.session/bpf_fentry_test*")

and loads/attaches uprobe program as uprobe session.

Adding sleepable hook (uprobe.session.s) as well.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Andrii Nakryiko <andrii@kernel.org>
Link: https://lore.kernel.org/bpf/20241108134544.480660-6-jolsa@kernel.org

authored by

Jiri Olsa and committed by
Andrii Nakryiko
022367ec 99b403d2

+20 -3
+1
tools/lib/bpf/bpf.c
··· 776 776 return libbpf_err(-EINVAL); 777 777 break; 778 778 case BPF_TRACE_UPROBE_MULTI: 779 + case BPF_TRACE_UPROBE_SESSION: 779 780 attr.link_create.uprobe_multi.flags = OPTS_GET(opts, uprobe_multi.flags, 0); 780 781 attr.link_create.uprobe_multi.cnt = OPTS_GET(opts, uprobe_multi.cnt, 0); 781 782 attr.link_create.uprobe_multi.path = ptr_to_u64(OPTS_GET(opts, uprobe_multi.path, 0));
+16 -2
tools/lib/bpf/libbpf.c
··· 9442 9442 SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session), 9443 9443 SEC_DEF("uprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi), 9444 9444 SEC_DEF("uretprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi), 9445 + SEC_DEF("uprobe.session+", KPROBE, BPF_TRACE_UPROBE_SESSION, SEC_NONE, attach_uprobe_multi), 9445 9446 SEC_DEF("uprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi), 9446 9447 SEC_DEF("uretprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi), 9448 + SEC_DEF("uprobe.session.s+", KPROBE, BPF_TRACE_UPROBE_SESSION, SEC_SLEEPABLE, attach_uprobe_multi), 9447 9449 SEC_DEF("ksyscall+", KPROBE, 0, SEC_NONE, attach_ksyscall), 9448 9450 SEC_DEF("kretsyscall+", KPROBE, 0, SEC_NONE, attach_ksyscall), 9449 9451 SEC_DEF("usdt+", KPROBE, 0, SEC_USDT, attach_usdt), ··· 11767 11765 ret = 0; 11768 11766 break; 11769 11767 case 3: 11768 + opts.session = str_has_pfx(probe_type, "uprobe.session"); 11770 11769 opts.retprobe = str_has_pfx(probe_type, "uretprobe.multi"); 11770 + 11771 11771 *link = bpf_program__attach_uprobe_multi(prog, -1, binary_path, func_name, &opts); 11772 11772 ret = libbpf_get_error(*link); 11773 11773 break; ··· 12018 12014 const unsigned long *ref_ctr_offsets = NULL, *offsets = NULL; 12019 12015 LIBBPF_OPTS(bpf_link_create_opts, lopts); 12020 12016 unsigned long *resolved_offsets = NULL; 12017 + enum bpf_attach_type attach_type; 12021 12018 int err = 0, link_fd, prog_fd; 12022 12019 struct bpf_link *link = NULL; 12023 12020 char errmsg[STRERR_BUFSIZE]; 12024 12021 char full_path[PATH_MAX]; 12022 + bool retprobe, session; 12025 12023 const __u64 *cookies; 12026 12024 const char **syms; 12027 12025 size_t cnt; ··· 12094 12088 offsets = resolved_offsets; 12095 12089 } 12096 12090 12091 + retprobe = OPTS_GET(opts, retprobe, false); 12092 + session = OPTS_GET(opts, session, false); 12093 + 12094 + if (retprobe && session) 12095 + return libbpf_err_ptr(-EINVAL); 12096 + 12097 + attach_type = session ? BPF_TRACE_UPROBE_SESSION : BPF_TRACE_UPROBE_MULTI; 12098 + 12097 12099 lopts.uprobe_multi.path = path; 12098 12100 lopts.uprobe_multi.offsets = offsets; 12099 12101 lopts.uprobe_multi.ref_ctr_offsets = ref_ctr_offsets; 12100 12102 lopts.uprobe_multi.cookies = cookies; 12101 12103 lopts.uprobe_multi.cnt = cnt; 12102 - lopts.uprobe_multi.flags = OPTS_GET(opts, retprobe, false) ? BPF_F_UPROBE_MULTI_RETURN : 0; 12104 + lopts.uprobe_multi.flags = retprobe ? BPF_F_UPROBE_MULTI_RETURN : 0; 12103 12105 12104 12106 if (pid == 0) 12105 12107 pid = getpid(); ··· 12121 12107 } 12122 12108 link->detach = &bpf_link__detach_fd; 12123 12109 12124 - link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_UPROBE_MULTI, &lopts); 12110 + link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts); 12125 12111 if (link_fd < 0) { 12126 12112 err = -errno; 12127 12113 pr_warn("prog '%s': failed to attach multi-uprobe: %s\n",
+3 -1
tools/lib/bpf/libbpf.h
··· 577 577 size_t cnt; 578 578 /* create return uprobes */ 579 579 bool retprobe; 580 + /* create session kprobes */ 581 + bool session; 580 582 size_t :0; 581 583 }; 582 584 583 - #define bpf_uprobe_multi_opts__last_field retprobe 585 + #define bpf_uprobe_multi_opts__last_field session 584 586 585 587 /** 586 588 * @brief **bpf_program__attach_uprobe_multi()** attaches a BPF program