From: Jiri Olsa <olsajiri@gmail.com>
To: Varun R Mallya <varunrmallya@gmail.com>
Cc: andrii@kernel.org, alan.maguire@oracle.com,
yonghong.song@linux.dev, song@kernel.org, bpf@vger.kernel.org,
ast@kernel.org, daniel@iogearbox.net, memxor@gmail.com,
eddyz87@gmail.com, martin.lau@linux.dev,
menglong8.dong@gmail.com, puranjay@kernel.org, bjorn@kernel.org,
leon.hwang@linux.dev, linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH bpf-next v2 1/3] libbpf: Auto-upgrade uprobes to multi-uprobes when supported
Date: Mon, 30 Mar 2026 16:52:27 +0200 [thread overview]
Message-ID: <acqOKws88JsU3riu@krava> (raw)
In-Reply-To: <20260330110019.549079-2-varunrmallya@gmail.com>
On Mon, Mar 30, 2026 at 04:30:17PM +0530, Varun R Mallya wrote:
> This patch modifies libbpf to automatically "upgrade" standard
> SEC("uprobe") and SEC("uretprobe") programs to use the multi-uprobe
> infrastructure (BPF_TRACE_UPROBE_MULTI) at load time if the kernel
> supports it, making them compatible with BPF tokens.
>
> To maintain backward compatibility and handle rare cases where singular
> uprobes are required, new SEC("uprobe.single") and SEC("uretprobe.single")
> section types are introduced. These force libbpf to use the legacy
> perf_event_open() attachment path.
>
> tools/testing/selftests/bpf/progs/test_fill_link_info.c has been
> modified to use SEC("uprobe.single") as it asserts the program type to be
> `BPF_LINK_TYPE_PERF_EVENT` and checks properties related to uprobes that
> use perf.
>
> Signed-off-by: Varun R Mallya <varunrmallya@gmail.com>
> ---
> tools/lib/bpf/libbpf.c | 53 +++++++++++++++++--
> .../selftests/bpf/progs/test_fill_link_info.c | 2 +-
> 2 files changed, 51 insertions(+), 4 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 1eaa7527d4da..bd7b6f486430 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -8248,6 +8248,23 @@ static int bpf_object_prepare_progs(struct bpf_object *obj)
>
> for (i = 0; i < obj->nr_programs; i++) {
> prog = &obj->programs[i];
> +
> + if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) {
> + const char *sec_name = prog->sec_name;
> + /* Here, we filter out for u[ret]probe or "u[ret]probe/"
> + * but we leave out anything with an '@'
> + * in it as uprobe_multi does not support versioned
> + * symbols yet, so we don't upgrade.
> + */
nice, I missed that uprobe.multi does not support versioned symbols,
I guess we should fix that
> + if (((strncmp(sec_name, "uprobe", 6) == 0 &&
str_has_pfx ?
> + (sec_name[6] == '/' || sec_name[6] == '\0')) ||
> + (strncmp(sec_name, "uretprobe", 9) == 0 &&
> + (sec_name[9] == '/' || sec_name[9] == '\0'))) &&
> + !strchr(sec_name, '@')) {
> + prog->expected_attach_type = BPF_TRACE_UPROBE_MULTI;
> + }
> + }
> +
> err = bpf_object__sanitize_prog(obj, prog);
> if (err)
> return err;
> @@ -9909,9 +9926,11 @@ static const struct bpf_sec_def section_defs[] = {
> SEC_DEF("kprobe+", KPROBE, 0, SEC_NONE, attach_kprobe),
> SEC_DEF("uprobe+", KPROBE, 0, SEC_NONE, attach_uprobe),
> SEC_DEF("uprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
> + SEC_DEF("uprobe.single+", KPROBE, 0, SEC_NONE, attach_uprobe),
should we add sleepable counterparts?
> SEC_DEF("kretprobe+", KPROBE, 0, SEC_NONE, attach_kprobe),
> SEC_DEF("uretprobe+", KPROBE, 0, SEC_NONE, attach_uprobe),
> SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
> + SEC_DEF("uretprobe.single+", KPROBE, 0, SEC_NONE, attach_uprobe),
just an idea for discussion.. I wonder if it'd be better to add new uprobe
section that will upgrade itself to uprobe.multi if it's present, instead
of changing the existing (expected) type
but I guess we want existing uprobe programs to benefit from that and
there's not really a reason anyone would want perf based uprobe when
uprobe_multi is supported
ok I talked myself out of it ;-)
> SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
> SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
> SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session),
> @@ -12737,6 +12756,32 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
> func_offset += sym_off;
> }
>
> + /* This provides backwards compatibility to programs using uprobe, but
> + * have been auto-upgraded to multi uprobe.
> + */
> + if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI) {
> + LIBBPF_OPTS(bpf_uprobe_multi_opts, multi_opts);
> + unsigned long offsets[1] = {func_offset};
> + __u64 bpf_cookie;
> +
> + multi_opts.retprobe = OPTS_GET(opts, retprobe, false);
> + if (offsets[0] || func_name) {
> + multi_opts.offsets = offsets;
could we do the same as for ref_ctr_off case and drop the offsets array?
multi_opts.offsets = &func_offset;
> + multi_opts.cnt = 1;
> + }
> + if (ref_ctr_off) {
> + multi_opts.ref_ctr_offsets = &ref_ctr_off;
> + multi_opts.cnt = 1;
> + }
> + bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
> + if (bpf_cookie) {
> + multi_opts.cookies = &bpf_cookie;
> + multi_opts.cnt = 1;
I think it's better just to set multi_opts.cnt = 1 once outside those if conditions
> + }
> +
> + return bpf_program__attach_uprobe_multi(prog, pid, binary_path,
> + NULL, &multi_opts);
> + }
> legacy = determine_uprobe_perf_type() < 0;
> switch (attach_mode) {
> case PROBE_ATTACH_MODE_LEGACY:
> @@ -12830,6 +12875,7 @@ static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf
> char *probe_type = NULL, *binary_path = NULL, *func_name = NULL, *func_off;
> int n, c, ret = -EINVAL;
> long offset = 0;
> + bool is_retprobe;
>
> *link = NULL;
>
> @@ -12856,13 +12902,14 @@ static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf
> else
> offset = 0;
> }
> - opts.retprobe = strcmp(probe_type, "uretprobe") == 0 ||
> - strcmp(probe_type, "uretprobe.s") == 0;
> - if (opts.retprobe && offset != 0) {
> + is_retprobe = strcmp(probe_type, "uretprobe") == 0 ||
> + strcmp(probe_type, "uretprobe.s") == 0;
> + if (is_retprobe && offset != 0) {
> pr_warn("prog '%s': uretprobes do not support offset specification\n",
> prog->name);
> break;
> }
> + opts.retprobe = is_retprobe;
is there any functional change above? looks like just opts.retprobe
is replaced with is_retprobe ?
jirka
next prev parent reply other threads:[~2026-03-30 14:52 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-30 11:00 [RFC PATCH bpf-next v2 0/3] Upgrading uprobe and kprobe to their `multi` counterparts Varun R Mallya
2026-03-30 11:00 ` [RFC PATCH bpf-next v2 1/3] libbpf: Auto-upgrade uprobes to multi-uprobes when supported Varun R Mallya
2026-03-30 11:47 ` bot+bpf-ci
2026-03-30 14:52 ` Jiri Olsa [this message]
2026-04-01 9:56 ` Varun R Mallya
2026-03-30 11:00 ` [RFC PATCH bpf-next v2 2/3] libbpf: Add FEAT_KPROBE_MULTI_LINK feature probe Varun R Mallya
2026-03-30 14:42 ` Leon Hwang
2026-04-01 9:57 ` Varun R Mallya
2026-03-30 14:52 ` Jiri Olsa
2026-04-01 9:49 ` Varun R Mallya
2026-03-30 11:00 ` [RFC PATCH bpf-next v2 3/3] libbpf: Auto-upgrade kprobes to multi-kprobes when supported Varun R Mallya
2026-03-30 11:47 ` bot+bpf-ci
2026-04-01 9:59 ` Varun R Mallya
2026-03-30 14:53 ` Jiri Olsa
2026-04-01 10:53 ` Varun R Mallya
2026-04-01 11:11 ` Varun R Mallya
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=acqOKws88JsU3riu@krava \
--to=olsajiri@gmail.com \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bjorn@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=leon.hwang@linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=menglong8.dong@gmail.com \
--cc=puranjay@kernel.org \
--cc=song@kernel.org \
--cc=varunrmallya@gmail.com \
--cc=yonghong.song@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.