[PATCH perf/core 07/11] libbpf: Add support to attach generic unique uprobe

Jiri Olsa posted 11 patches 1 month ago
[PATCH perf/core 07/11] libbpf: Add support to attach generic unique uprobe
Posted by Jiri Olsa 1 month ago
Adding support to attach unique generic uprobe by adding the 'unique'
bool flag to struct bpf_uprobe_opts.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
---
 tools/lib/bpf/libbpf.c | 29 ++++++++++++++++++++++++-----
 tools/lib/bpf/libbpf.h |  4 +++-
 2 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 1f613a5f95b6..aac2bd4fb95e 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -11045,11 +11045,19 @@ static int determine_uprobe_retprobe_bit(void)
 	return parse_uint_from_file(file, "config:%d\n");
 }
 
+static int determine_uprobe_unique_bit(void)
+{
+	const char *file = "/sys/bus/event_source/devices/uprobe/format/unique";
+
+	return parse_uint_from_file(file, "config:%d\n");
+}
+
 #define PERF_UPROBE_REF_CTR_OFFSET_BITS 32
 #define PERF_UPROBE_REF_CTR_OFFSET_SHIFT 32
 
 static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
-				 uint64_t offset, int pid, size_t ref_ctr_off)
+				 uint64_t offset, int pid, size_t ref_ctr_off,
+				 bool unique)
 {
 	const size_t attr_sz = sizeof(struct perf_event_attr);
 	struct perf_event_attr attr;
@@ -11080,6 +11088,16 @@ static int perf_event_open_probe(bool uprobe, bool retprobe, const char *name,
 		}
 		attr.config |= 1 << bit;
 	}
+	if (uprobe && unique) {
+		int bit = determine_uprobe_unique_bit();
+
+		if (bit < 0) {
+			pr_warn("failed to determine uprobe unique bit: %s\n",
+				errstr(bit));
+			return bit;
+		}
+		attr.config |= 1 << bit;
+	}
 	attr.size = attr_sz;
 	attr.type = type;
 	attr.config |= (__u64)ref_ctr_off << PERF_UPROBE_REF_CTR_OFFSET_SHIFT;
@@ -11286,7 +11304,7 @@ int probe_kern_syscall_wrapper(int token_fd)
 	if (determine_kprobe_perf_type() >= 0) {
 		int pfd;
 
-		pfd = perf_event_open_probe(false, false, syscall_name, 0, getpid(), 0);
+		pfd = perf_event_open_probe(false, false, syscall_name, 0, getpid(), 0, false);
 		if (pfd >= 0)
 			close(pfd);
 
@@ -11348,7 +11366,7 @@ bpf_program__attach_kprobe_opts(const struct bpf_program *prog,
 	if (!legacy) {
 		pfd = perf_event_open_probe(false /* uprobe */, retprobe,
 					    func_name, offset,
-					    -1 /* pid */, 0 /* ref_ctr_off */);
+					    -1 /* pid */, 0 /* ref_ctr_off */, false /* unique */);
 	} else {
 		char probe_name[MAX_EVENT_NAME_LEN];
 
@@ -12251,7 +12269,7 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
 	struct bpf_link *link;
 	size_t ref_ctr_off;
 	int pfd, err;
-	bool retprobe, legacy;
+	bool retprobe, legacy, unique;
 	const char *func_name;
 
 	if (!OPTS_VALID(opts, bpf_uprobe_opts))
@@ -12261,6 +12279,7 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
 	retprobe = OPTS_GET(opts, retprobe, false);
 	ref_ctr_off = OPTS_GET(opts, ref_ctr_offset, 0);
 	pe_opts.bpf_cookie = OPTS_GET(opts, bpf_cookie, 0);
+	unique = OPTS_GET(opts, unique, false);
 
 	if (!binary_path)
 		return libbpf_err_ptr(-EINVAL);
@@ -12321,7 +12340,7 @@ bpf_program__attach_uprobe_opts(const struct bpf_program *prog, pid_t pid,
 
 	if (!legacy) {
 		pfd = perf_event_open_probe(true /* uprobe */, retprobe, binary_path,
-					    func_offset, pid, ref_ctr_off);
+					    func_offset, pid, ref_ctr_off, unique);
 	} else {
 		char probe_name[MAX_EVENT_NAME_LEN];
 
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 13a10299331b..0a38dee1d9c1 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -701,9 +701,11 @@ struct bpf_uprobe_opts {
 	const char *func_name;
 	/* uprobe attach mode */
 	enum probe_attach_mode attach_mode;
+	/* create unique uprobe */
+	bool unique;
 	size_t :0;
 };
-#define bpf_uprobe_opts__last_field attach_mode
+#define bpf_uprobe_opts__last_field unique
 
 /**
  * @brief **bpf_program__attach_uprobe()** attaches a BPF program
-- 
2.51.0
Re: [PATCH perf/core 07/11] libbpf: Add support to attach generic unique uprobe
Posted by Andrii Nakryiko 4 weeks, 1 day ago
On Tue, Sep 2, 2025 at 7:36 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Adding support to attach unique generic uprobe by adding the 'unique'
> bool flag to struct bpf_uprobe_opts.
>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
>  tools/lib/bpf/libbpf.c | 29 ++++++++++++++++++++++++-----
>  tools/lib/bpf/libbpf.h |  4 +++-
>  2 files changed, 27 insertions(+), 6 deletions(-)
>
> diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
> index 1f613a5f95b6..aac2bd4fb95e 100644
> --- a/tools/lib/bpf/libbpf.c
> +++ b/tools/lib/bpf/libbpf.c
> @@ -11045,11 +11045,19 @@ static int determine_uprobe_retprobe_bit(void)
>         return parse_uint_from_file(file, "config:%d\n");
>  }
>
> +static int determine_uprobe_unique_bit(void)
> +{
> +       const char *file = "/sys/bus/event_source/devices/uprobe/format/unique";
> +
> +       return parse_uint_from_file(file, "config:%d\n");
> +}

perf event-based attachment is legacy and libbpf will automatically
try to use BPF_LINK_CREATE, so I don't think we need to add this at
all.

But I also feel like we don't really need any special thing for
"exclusive uprobe", because ultimately we just want to let uprobe
override user registers, which we can allow for normal uprobes, as I
mentioned in the other email.

[...]