From: Varun R Mallya <varunrmallya@gmail.com>
To: andrii@kernel.org, alan.maguire@oracle.com
Cc: ast@kernel.org, daniel@iogearbox.net, bpf@vger.kernel.org,
linux-kernel@vger.kernel.org, varunrmallya@gmail.com
Subject: [RFC PATCH bpf-next 1/1] libbpf: Auto-upgrade uprobes to multi-uprobes when supported
Date: Thu, 12 Feb 2026 20:50:13 +0530 [thread overview]
Message-ID: <20260212152013.17351-2-varunrmallya@gmail.com> (raw)
In-Reply-To: <20260212152013.17351-1-varunrmallya@gmail.com>
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.
Signed-off-by: Varun R Mallya <varunrmallya@gmail.com>
---
tools/lib/bpf/libbpf.c | 42 ++++++++++++++++++++++++++++++++++++------
1 file changed, 36 insertions(+), 6 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 0c8bf0b5cce4..a32f221d3245 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -8265,6 +8265,22 @@ static int bpf_object_init_progs(struct bpf_object *obj, const struct bpf_object
prog->type = prog->sec_def->prog_type;
prog->expected_attach_type = prog->sec_def->expected_attach_type;
+ /* set BPF_TRACE_UPROBE_MULTI if sec_name matches "u[ret]probe"
+ * otherwise, leave alone.
+ */
+ if (kernel_supports(obj, FEAT_UPROBE_MULTI_LINK)) {
+ char *probe_type = NULL;
+ int n;
+
+ n = sscanf(prog->sec_name, "%m[^/]", &probe_type);
+ if (n >= 1)
+ if (!strcmp(probe_type, "uprobe") ||
+ !strcmp(probe_type, "uretprobe"))
+ prog->expected_attach_type = BPF_TRACE_UPROBE_MULTI;
+
+ free(probe_type);
+ }
+
/* sec_def can have custom callback which should be called
* after bpf_program is initialized to adjust its properties
*/
@@ -9822,9 +9838,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),
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),
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),
@@ -12722,10 +12740,10 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
*/
static int attach_uprobe(const struct bpf_program *prog, long cookie, struct bpf_link **link)
{
- DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts);
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;
@@ -12752,15 +12770,27 @@ 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.func_name = func_name;
- *link = bpf_program__attach_uprobe_opts(prog, -1, binary_path, offset, &opts);
+ if (prog->expected_attach_type == BPF_TRACE_UPROBE_MULTI) {
+ DECLARE_LIBBPF_OPTS(bpf_uprobe_multi_opts, opts);
+
+ opts.retprobe = is_retprobe;
+ *link = bpf_program__attach_uprobe_multi(prog, -1, binary_path,
+ func_name, &opts);
+ } else {
+ DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts);
+
+ opts.retprobe = is_retprobe;
+ opts.func_name = func_name;
+ *link = bpf_program__attach_uprobe_opts(prog, -1, binary_path,
+ offset, &opts);
+ }
ret = libbpf_get_error(*link);
break;
default:
--
2.52.0
next prev parent reply other threads:[~2026-02-12 15:20 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-12 15:20 [RFC PATCH bpf-next 0/1] Upgrading uprobe and kprobe to their `multi` counterparts Varun R Mallya
2026-02-12 15:20 ` Varun R Mallya [this message]
2026-02-13 0:06 ` [RFC PATCH bpf-next 1/1] libbpf: Auto-upgrade uprobes to multi-uprobes when supported Yonghong Song
2026-02-13 17:22 ` Varun R Mallya
2026-02-14 5:25 ` Yonghong Song
2026-02-18 19:07 ` Andrii Nakryiko
2026-02-19 5:31 ` Yonghong Song
2026-02-18 19:03 ` Andrii Nakryiko
2026-02-18 19:07 ` [RFC PATCH bpf-next 0/1] Upgrading uprobe and kprobe to their `multi` counterparts Andrii Nakryiko
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=20260212152013.17351-2-varunrmallya@gmail.com \
--to=varunrmallya@gmail.com \
--cc=alan.maguire@oracle.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®