* [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe
@ 2025-02-24 16:59 Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 1/5] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
` (5 more replies)
0 siblings, 6 replies; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen
More and more kfunc functions are being added to the kernel.
Different prog types have different restrictions when using kfunc.
Therefore, prog_kfunc probe is added to check whether it is supported,
and the use of this api will be added to bpftool later.
Change list:
- v7 -> v8:
- fix "kfuncs require device-bound" verifier info
- init expected_attach_type for kprobe prog type
- patchset Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
- v7
https://lore.kernel.org/bpf/20250212153912.24116-1-chen.dylane@gmail.com/
- v6 -> v7:
- wrap err with libbpf_err
- comments fix
- handle btf_fd < 0 as vmlinux
- patchset Reviewed-by: Jiri Olsa <jolsa@kernel.org>
- v6
https://lore.kernel.org/bpf/20250211111859.6029-1-chen.dylane@gmail.com
- v5 -> v6:
- remove fd_array_cnt
- test case clean code
- v5
https://lore.kernel.org/bpf/20250210055945.27192-1-chen.dylane@gmail.com
- v4 -> v5:
- use fd_array on stack
- declare the scope of use of btf_fd
- v4
https://lore.kernel.org/bpf/20250206051557.27913-1-chen.dylane@gmail.com/
- v3 -> v4:
- add fd_array init for kfunc in mod btf
- add test case for kfunc in mod btf
- refactor common part as prog load type check for
libbpf_probe_bpf_{helper,kfunc}
- v3
https://lore.kernel.org/bpf/20250124144411.13468-1-chen.dylane@gmail.com
- v2 -> v3:
- rename parameter off with btf_fd
- extract the common part for libbpf_probe_bpf_{helper,kfunc}
- v2
https://lore.kernel.org/bpf/20250123170555.291896-1-chen.dylane@gmail.com
- v1 -> v2:
- check unsupported prog type like probe_bpf_helper
- add off parameter for module btf
- check verifier info when kfunc id invalid
- v1
https://lore.kernel.org/bpf/20250122171359.232791-1-chen.dylane@gmail.com
Tao Chen (5):
libbpf: Extract prog load type check from libbpf_probe_bpf_helper
libbpf: Init fd_array when prog probe load
libbpf: Add libbpf_probe_bpf_kfunc API
libbpf: Init kprobe prog expected_attach_type for kfunc probe
selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
tools/lib/bpf/libbpf.h | 19 ++-
tools/lib/bpf/libbpf.map | 1 +
tools/lib/bpf/libbpf_probes.c | 90 +++++++++++---
.../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
4 files changed, 205 insertions(+), 16 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH bpf-next v8 1/5] libbpf: Extract prog load type check from libbpf_probe_bpf_helper
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
@ 2025-02-24 16:59 ` Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 2/5] libbpf: Init fd_array when prog probe load Tao Chen
` (4 subsequent siblings)
5 siblings, 0 replies; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen, Tao Chen
Extract prog load type check part from libbpf_probe_bpf_helper
suggested by Andrii, which will be used in both
libbpf_probe_bpf_{helper, kfunc}.
Cc: Tao Chen <dylane.chen@didiglobal.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Tao Chen <chen.dylane@linux.dev>
---
tools/lib/bpf/libbpf_probes.c | 31 +++++++++++++++++++------------
1 file changed, 19 insertions(+), 12 deletions(-)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index 9dfbe7750f56..a48a557314f6 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -413,6 +413,23 @@ int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void *opts)
return libbpf_err(ret);
}
+static bool can_probe_prog_type(enum bpf_prog_type prog_type)
+{
+ /* we can't successfully load all prog types to check for BPF helper
+ * and kfunc support.
+ */
+ switch (prog_type) {
+ case BPF_PROG_TYPE_TRACING:
+ case BPF_PROG_TYPE_EXT:
+ case BPF_PROG_TYPE_LSM:
+ case BPF_PROG_TYPE_STRUCT_OPS:
+ return false;
+ default:
+ break;
+ }
+ return true;
+}
+
int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
const void *opts)
{
@@ -427,18 +444,8 @@ int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helpe
if (opts)
return libbpf_err(-EINVAL);
- /* we can't successfully load all prog types to check for BPF helper
- * support, so bail out with -EOPNOTSUPP error
- */
- switch (prog_type) {
- case BPF_PROG_TYPE_TRACING:
- case BPF_PROG_TYPE_EXT:
- case BPF_PROG_TYPE_LSM:
- case BPF_PROG_TYPE_STRUCT_OPS:
- return -EOPNOTSUPP;
- default:
- break;
- }
+ if (!can_probe_prog_type(prog_type))
+ return libbpf_err(-EOPNOTSUPP);
buf[0] = '\0';
ret = probe_prog_load(prog_type, insns, insn_cnt, buf, sizeof(buf));
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v8 2/5] libbpf: Init fd_array when prog probe load
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 1/5] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
@ 2025-02-24 16:59 ` Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
` (3 subsequent siblings)
5 siblings, 0 replies; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen, Tao Chen
fd_array used to store module btf fd, which will
be used for kfunc probe in module btf.
Cc: Tao Chen <dylane.chen@didiglobal.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Tao Chen <chen.dylane@linux.dev>
---
tools/lib/bpf/libbpf_probes.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index a48a557314f6..de2b1205b436 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -102,12 +102,13 @@ __u32 get_kernel_version(void)
static int probe_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, size_t insns_cnt,
- char *log_buf, size_t log_buf_sz)
+ int *fd_array, char *log_buf, size_t log_buf_sz)
{
LIBBPF_OPTS(bpf_prog_load_opts, opts,
.log_buf = log_buf,
.log_size = log_buf_sz,
.log_level = log_buf ? 1 : 0,
+ .fd_array = fd_array,
);
int fd, err, exp_err = 0;
const char *exp_msg = NULL;
@@ -214,7 +215,7 @@ int libbpf_probe_bpf_prog_type(enum bpf_prog_type prog_type, const void *opts)
if (opts)
return libbpf_err(-EINVAL);
- ret = probe_prog_load(prog_type, insns, insn_cnt, NULL, 0);
+ ret = probe_prog_load(prog_type, insns, insn_cnt, NULL, NULL, 0);
return libbpf_err(ret);
}
@@ -448,7 +449,7 @@ int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helpe
return libbpf_err(-EOPNOTSUPP);
buf[0] = '\0';
- ret = probe_prog_load(prog_type, insns, insn_cnt, buf, sizeof(buf));
+ ret = probe_prog_load(prog_type, insns, insn_cnt, NULL, buf, sizeof(buf));
if (ret < 0)
return libbpf_err(ret);
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 1/5] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 2/5] libbpf: Init fd_array when prog probe load Tao Chen
@ 2025-02-24 16:59 ` Tao Chen
2025-02-25 1:15 ` Andrii Nakryiko
2025-02-24 16:59 ` [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe Tao Chen
` (2 subsequent siblings)
5 siblings, 1 reply; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen, Tao Chen
Similarly to libbpf_probe_bpf_helper, the libbpf_probe_bpf_kfunc
used to test the availability of the different eBPF kfuncs on the
current system.
Cc: Tao Chen <dylane.chen@didiglobal.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Tao Chen <chen.dylane@linux.dev>
---
tools/lib/bpf/libbpf.h | 19 ++++++++++++-
tools/lib/bpf/libbpf.map | 1 +
tools/lib/bpf/libbpf_probes.c | 51 +++++++++++++++++++++++++++++++++++
3 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h
index 3020ee45303a..c79b4475b956 100644
--- a/tools/lib/bpf/libbpf.h
+++ b/tools/lib/bpf/libbpf.h
@@ -1680,7 +1680,24 @@ LIBBPF_API int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void
*/
LIBBPF_API int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type,
enum bpf_func_id helper_id, const void *opts);
-
+/**
+ * @brief **libbpf_probe_bpf_kfunc()** detects if host kernel supports the
+ * use of a given BPF kfunc from specified BPF program type.
+ * @param prog_type BPF program type used to check the support of BPF kfunc
+ * @param kfunc_id The btf ID of BPF kfunc to check support for
+ * @param btf_fd The module BTF FD, if kfunc is defined in kernel module,
+ * btf_fd is used to point to module's BTF, which is >= 0, and < 0 means kfunc
+ * defined in vmlinux.
+ * @param opts reserved for future extensibility, should be NULL
+ * @return 1, if given combination of program type and kfunc is supported; 0,
+ * if the combination is not supported; negative error code if feature
+ * detection for provided input arguments failed or can't be performed
+ *
+ * Make sure the process has required set of CAP_* permissions (or runs as
+ * root) when performing feature checking.
+ */
+LIBBPF_API int libbpf_probe_bpf_kfunc(enum bpf_prog_type prog_type,
+ int kfunc_id, int btf_fd, const void *opts);
/**
* @brief **libbpf_num_possible_cpus()** is a helper function to get the
* number of possible CPUs that the host kernel supports and expects.
diff --git a/tools/lib/bpf/libbpf.map b/tools/lib/bpf/libbpf.map
index b5a838de6f47..3bbfe13aeb6a 100644
--- a/tools/lib/bpf/libbpf.map
+++ b/tools/lib/bpf/libbpf.map
@@ -438,4 +438,5 @@ LIBBPF_1.6.0 {
bpf_linker__new_fd;
btf__add_decl_attr;
btf__add_type_attr;
+ libbpf_probe_bpf_kfunc;
} LIBBPF_1.5.0;
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index de2b1205b436..8efebc18a215 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -431,6 +431,57 @@ static bool can_probe_prog_type(enum bpf_prog_type prog_type)
return true;
}
+int libbpf_probe_bpf_kfunc(enum bpf_prog_type prog_type, int kfunc_id, int btf_fd,
+ const void *opts)
+{
+ struct bpf_insn insns[] = {
+ BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 1, kfunc_id),
+ BPF_EXIT_INSN(),
+ };
+ const size_t insn_cnt = ARRAY_SIZE(insns);
+ char buf[4096];
+ int fd_array[2] = {-1};
+ int ret;
+
+ if (opts)
+ return libbpf_err(-EINVAL);
+
+ if (!can_probe_prog_type(prog_type))
+ return libbpf_err(-EOPNOTSUPP);
+
+ if (btf_fd >= 0)
+ fd_array[1] = btf_fd;
+ else
+ /* insn.off = 0, means vmlinux btf */
+ insns[0].off = 0;
+
+ buf[0] = '\0';
+ ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
+ buf, sizeof(buf));
+ if (ret < 0)
+ return libbpf_err(ret);
+
+ if (ret > 0)
+ return 1; /* assume supported */
+
+ /* If BPF verifier recognizes BPF kfunc but it's not supported for
+ * given BPF program type, it will emit "calling kernel function
+ * <name> is not allowed". If the kfunc id is invalid,
+ * it will emit "kernel btf_id <id> is not a function". If BTF fd
+ * invalid in module BTF, it will emit "invalid module BTF fd specified" or
+ * "negative offset disallowed for kernel module function call". If
+ * kfunc prog not dev buound, it will emit "metadata kfuncs require
+ * device-bound program".
+ */
+ if (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
+ strstr(buf, "invalid module BTF fd") ||
+ strstr(buf, "negative offset disallowed") ||
+ strstr(buf, "device-bound program"))
+ return 0;
+
+ return 1;
+}
+
int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
const void *opts)
{
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
` (2 preceding siblings ...)
2025-02-24 16:59 ` [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
@ 2025-02-24 16:59 ` Tao Chen
2025-02-25 1:15 ` Andrii Nakryiko
2025-02-24 16:59 ` [PATCH bpf-next v8 5/5] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
2025-02-24 17:13 ` [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
5 siblings, 1 reply; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen
Kprobe prog type kfuncs like bpf_session_is_return and
bpf_session_cookie will check the expected_attach_type,
so init the expected_attach_type here.
Signed-off-by: Tao Chen <chen.dylane@linux.dev>
---
tools/lib/bpf/libbpf_probes.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index 8efebc18a215..bb5b457ddc80 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
break;
case BPF_PROG_TYPE_KPROBE:
opts.kern_version = get_kernel_version();
+ opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
break;
case BPF_PROG_TYPE_LIRC_MODE2:
opts.expected_attach_type = BPF_LIRC_MODE2;
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH bpf-next v8 5/5] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
` (3 preceding siblings ...)
2025-02-24 16:59 ` [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe Tao Chen
@ 2025-02-24 16:59 ` Tao Chen
2025-02-24 17:13 ` [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
5 siblings, 0 replies; 16+ messages in thread
From: Tao Chen @ 2025-02-24 16:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, Tao Chen, Tao Chen
Add selftests for prog_kfunc feature probing.
./test_progs -t libbpf_probe_kfuncs
#153 libbpf_probe_kfuncs:OK
Summary: 1/0 PASSED, 0 SKIPPED, 0 FAILED
Cc: Tao Chen <dylane.chen@didiglobal.com>
Reviewed-by: Jiri Olsa <jolsa@kernel.org>
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Tao Chen <chen.dylane@linux.dev>
---
.../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
1 file changed, 111 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c b/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
index 4ed46ed58a7b..d8f5475a94ce 100644
--- a/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
+++ b/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
@@ -126,3 +126,114 @@ void test_libbpf_probe_helpers(void)
ASSERT_EQ(res, d->supported, buf);
}
}
+
+static int module_btf_fd(char *module)
+{
+ int fd, err;
+ __u32 id = 0, len;
+ struct bpf_btf_info info;
+ char name[64];
+
+ while (true) {
+ err = bpf_btf_get_next_id(id, &id);
+ if (err)
+ return -1;
+
+ fd = bpf_btf_get_fd_by_id(id);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ continue;
+ return -1;
+ }
+ len = sizeof(info);
+ memset(&info, 0, sizeof(info));
+ info.name = ptr_to_u64(name);
+ info.name_len = sizeof(name);
+ err = bpf_btf_get_info_by_fd(fd, &info, &len);
+ if (err) {
+ close(fd);
+ return -1;
+ }
+ /* find target module BTF */
+ if (!strcmp(name, module))
+ break;
+
+ close(fd);
+ }
+
+ return fd;
+}
+
+void test_libbpf_probe_kfuncs(void)
+{
+ int ret, kfunc_id, fd;
+ char *kfunc = "bpf_cpumask_create";
+ struct btf *vmlinux_btf = NULL;
+ struct btf *module_btf = NULL;
+
+ vmlinux_btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
+ if (!ASSERT_OK_PTR(vmlinux_btf, "btf_parse"))
+ return;
+
+ kfunc_id = btf__find_by_name_kind(vmlinux_btf, kfunc, BTF_KIND_FUNC);
+ if (!ASSERT_GT(kfunc_id, 0, kfunc))
+ goto cleanup;
+
+ /* prog BPF_PROG_TYPE_SYSCALL supports kfunc bpf_cpumask_create */
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_SYSCALL, kfunc_id, -1, NULL);
+ if (!ASSERT_EQ(ret, 1, "kfunc in vmlinux support"))
+ goto cleanup;
+
+ /* prog BPF_PROG_TYPE_KPROBE does not support kfunc bpf_cpumask_create */
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_KPROBE, kfunc_id, -1, NULL);
+ if (!ASSERT_EQ(ret, 0, "kfunc in vmlinux not suuport"))
+ goto cleanup;
+
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_KPROBE, -1, -1, NULL);
+ if (!ASSERT_EQ(ret, 0, "invalid kfunc id:-1"))
+ goto cleanup;
+
+ ret = libbpf_probe_bpf_kfunc(100000, kfunc_id, -1, NULL);
+ if (!ASSERT_ERR(ret, "invalid prog type:100000"))
+ goto cleanup;
+
+ if (!env.has_testmod)
+ goto cleanup;
+
+ module_btf = btf__load_module_btf("bpf_testmod", vmlinux_btf);
+ if (!ASSERT_OK_PTR(module_btf, "load module BTF"))
+ goto cleanup;
+
+ kfunc_id = btf__find_by_name(module_btf, "bpf_kfunc_call_test1");
+ if (!ASSERT_GT(kfunc_id, 0, "func not found"))
+ goto cleanup;
+
+ fd = module_btf_fd("bpf_testmod");
+ if (!ASSERT_GE(fd, 0, "module BTF fd"))
+ goto cleanup;
+
+ /* prog BPF_PROG_TYPE_SYSCALL supports kfunc bpf_kfunc_call_test1 in bpf_testmod */
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_SYSCALL, kfunc_id, fd, NULL);
+ if (!ASSERT_EQ(ret, 1, "kfunc in module BTF support"))
+ goto cleanup_fd;
+
+ /* prog BPF_PROG_TYPE_KPROBE does not support kfunc bpf_kfunc_call_test1
+ * in bpf_testmod
+ */
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_KPROBE, kfunc_id, fd, NULL);
+ if (!ASSERT_EQ(ret, 0, "kfunc in module BTF not support"))
+ goto cleanup_fd;
+
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_SYSCALL, -1, fd, NULL);
+ if (!ASSERT_EQ(ret, 0, "invalid kfunc id in module BTF"))
+ goto cleanup_fd;
+
+ ret = libbpf_probe_bpf_kfunc(BPF_PROG_TYPE_SYSCALL, kfunc_id, 100, NULL);
+ ASSERT_EQ(ret, 0, "invalid BTF fd in module BTF");
+
+cleanup_fd:
+ close(fd);
+cleanup:
+ btf__free(vmlinux_btf);
+ btf__free(module_btf);
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
` (4 preceding siblings ...)
2025-02-24 16:59 ` [PATCH bpf-next v8 5/5] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
@ 2025-02-24 17:13 ` Tao Chen
2025-02-25 1:28 ` Eduard Zingerman
5 siblings, 1 reply; 16+ messages in thread
From: Tao Chen @ 2025-02-24 17:13 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
在 2025/2/25 00:59, Tao Chen 写道:
> More and more kfunc functions are being added to the kernel.
> Different prog types have different restrictions when using kfunc.
> Therefore, prog_kfunc probe is added to check whether it is supported,
> and the use of this api will be added to bpftool later.
>
> Change list:
> - v7 -> v8:
> - fix "kfuncs require device-bound" verifier info
> - init expected_attach_type for kprobe prog type
> - patchset Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
> - v7
> https://lore.kernel.org/bpf/20250212153912.24116-1-chen.dylane@gmail.com/
>
> - v6 -> v7:
> - wrap err with libbpf_err
> - comments fix
> - handle btf_fd < 0 as vmlinux
> - patchset Reviewed-by: Jiri Olsa <jolsa@kernel.org>
> - v6
> https://lore.kernel.org/bpf/20250211111859.6029-1-chen.dylane@gmail.com
>
> - v5 -> v6:
> - remove fd_array_cnt
> - test case clean code
> - v5
> https://lore.kernel.org/bpf/20250210055945.27192-1-chen.dylane@gmail.com
>
> - v4 -> v5:
> - use fd_array on stack
> - declare the scope of use of btf_fd
> - v4
> https://lore.kernel.org/bpf/20250206051557.27913-1-chen.dylane@gmail.com/
>
> - v3 -> v4:
> - add fd_array init for kfunc in mod btf
> - add test case for kfunc in mod btf
> - refactor common part as prog load type check for
> libbpf_probe_bpf_{helper,kfunc}
> - v3
> https://lore.kernel.org/bpf/20250124144411.13468-1-chen.dylane@gmail.com
>
> - v2 -> v3:
> - rename parameter off with btf_fd
> - extract the common part for libbpf_probe_bpf_{helper,kfunc}
> - v2
> https://lore.kernel.org/bpf/20250123170555.291896-1-chen.dylane@gmail.com
>
> - v1 -> v2:
> - check unsupported prog type like probe_bpf_helper
> - add off parameter for module btf
> - check verifier info when kfunc id invalid
> - v1
> https://lore.kernel.org/bpf/20250122171359.232791-1-chen.dylane@gmail.com
>
> Tao Chen (5):
> libbpf: Extract prog load type check from libbpf_probe_bpf_helper
> libbpf: Init fd_array when prog probe load
> libbpf: Add libbpf_probe_bpf_kfunc API
> libbpf: Init kprobe prog expected_attach_type for kfunc probe
> selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
>
> tools/lib/bpf/libbpf.h | 19 ++-
> tools/lib/bpf/libbpf.map | 1 +
> tools/lib/bpf/libbpf_probes.c | 90 +++++++++++---
> .../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
> 4 files changed, 205 insertions(+), 16 deletions(-)
>
Hi Eduard,
I used a simple script to find all kfunc prog types and comapre it with
your program, most of them are consistent, the results are as follows,
and i add pathch 4 additionally to fix kfunc probe like
bpf_session_is_return.
-------------------------------------------------
The script results:
hid_bpf_allocate_context: SYSCALL
hid_bpf_release_context: SYSCALL
hid_bpf_hw_request: SYSCALL
hid_bpf_hw_output_report: SYSCALL
hid_bpf_input_report: SYSCALL
bpf_session_is_return: KPROBE
bpf_session_cookie: KPROBE
scx_bpf_create_dsq: SYSCALL
scx_bpf_dsq_move_set_slice: SYSCALL
scx_bpf_dsq_move_set_vtime: SYSCALL
scx_bpf_dsq_move: SYSCALL
scx_bpf_dsq_move_vtime: SYSCALL
scx_bpf_dispatch_from_dsq_set_slice: SYSCALL
scx_bpf_dispatch_from_dsq_set_vtime: SYSCALL
scx_bpf_dispatch_from_dsq: SYSCALL
scx_bpf_dispatch_vtime_from_dsq: SYSCALL
scx_bpf_kick_cpu: SYSCALL
scx_bpf_dsq_nr_queued: SYSCALL
scx_bpf_destroy_dsq: SYSCALL
bpf_iter_scx_dsq_new: SYSCALL
bpf_iter_scx_dsq_next: SYSCALL
bpf_iter_scx_dsq_destroy: SYSCALL
scx_bpf_exit_bstr: SYSCALL
scx_bpf_error_bstr: SYSCALL
scx_bpf_dump_bstr: SYSCALL
scx_bpf_cpuperf_cap: SYSCALL
scx_bpf_cpuperf_cur: SYSCALL
scx_bpf_cpuperf_set: SYSCALL
scx_bpf_nr_cpu_ids: SYSCALL
scx_bpf_get_possible_cpumask: SYSCALL
scx_bpf_get_online_cpumask: SYSCALL
scx_bpf_put_cpumask: SYSCALL
scx_bpf_get_idle_cpumask: SYSCALL
scx_bpf_get_idle_smtmask: SYSCALL
scx_bpf_put_idle_cpumask: SYSCALL
scx_bpf_test_and_clear_cpu_idle: SYSCALL
scx_bpf_pick_idle_cpu: SYSCALL
scx_bpf_pick_any_cpu: SYSCALL
scx_bpf_task_running: SYSCALL
scx_bpf_task_cpu: SYSCALL
scx_bpf_cpu_rq: SYSCALL
scx_bpf_task_cgroup: SYSCALL
scx_bpf_now: SYSCALL
bpf_arena_alloc_pages: UNSPEC
bpf_arena_free_pages: UNSPEC
bpf_crypto_decrypt: XDP, SCHED_ACT, SCHED_CLS
bpf_crypto_encrypt: XDP, SCHED_ACT, SCHED_CLS
bpf_crypto_ctx_create: SYSCALL
bpf_crypto_ctx_release: SYSCALL
bpf_crypto_ctx_acquire: SYSCALL
bpf_map_sum_elem_count: UNSPEC
bpf_cpumask_create: SYSCALL
bpf_cpumask_release: SYSCALL
bpf_cpumask_acquire: SYSCALL
bpf_cpumask_first: SYSCALL
bpf_cpumask_first_zero: SYSCALL
bpf_cpumask_first_and: SYSCALL
bpf_cpumask_set_cpu: SYSCALL
bpf_cpumask_clear_cpu: SYSCALL
bpf_cpumask_test_cpu: SYSCALL
bpf_cpumask_test_and_set_cpu: SYSCALL
bpf_cpumask_test_and_clear_cpu: SYSCALL
bpf_cpumask_setall: SYSCALL
bpf_cpumask_clear: SYSCALL
bpf_cpumask_and: SYSCALL
bpf_cpumask_or: SYSCALL
bpf_cpumask_xor: SYSCALL
bpf_cpumask_equal: SYSCALL
bpf_cpumask_intersects: SYSCALL
bpf_cpumask_subset: SYSCALL
bpf_cpumask_empty: SYSCALL
bpf_cpumask_full: SYSCALL
bpf_cpumask_copy: SYSCALL
bpf_cpumask_any_distribute: SYSCALL
bpf_cpumask_any_and_distribute: SYSCALL
bpf_cpumask_weight: SYSCALL
crash_kexec: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_obj_new_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_percpu_obj_new_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_obj_drop_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_percpu_obj_drop_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_refcount_acquire_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_list_push_front_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_list_push_back_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_list_pop_front: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_list_pop_back: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_acquire: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_release: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_rbtree_remove: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_rbtree_add_impl: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_rbtree_first: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_cgroup_acquire: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_cgroup_release: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_cgroup_ancestor: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_cgroup_from_id: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_under_cgroup: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_get_cgroup1: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_from_pid: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_task_from_vpid: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_throw: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_send_signal_task: XDP, SCHED_CLS, CGROUP_SKB, SYSCALL
bpf_cast_to_kern_ctx: UNSPEC
bpf_rdonly_cast: UNSPEC
bpf_rcu_read_lock: UNSPEC
bpf_rcu_read_unlock: UNSPEC
bpf_dynptr_slice: UNSPEC
bpf_dynptr_slice_rdwr: UNSPEC
bpf_iter_num_new: UNSPEC
bpf_iter_num_next: UNSPEC
bpf_iter_num_destroy: UNSPEC
bpf_iter_task_vma_new: UNSPEC
bpf_iter_task_vma_next: UNSPEC
bpf_iter_task_vma_destroy: UNSPEC
bpf_iter_css_task_new: UNSPEC
bpf_iter_css_task_next: UNSPEC
bpf_iter_css_task_destroy: UNSPEC
bpf_iter_css_new: UNSPEC
bpf_iter_css_next: UNSPEC
bpf_iter_css_destroy: UNSPEC
bpf_iter_task_new: UNSPEC
bpf_iter_task_next: UNSPEC
bpf_iter_task_destroy: UNSPEC
bpf_dynptr_adjust: UNSPEC
bpf_dynptr_is_null: UNSPEC
bpf_dynptr_is_rdonly: UNSPEC
bpf_dynptr_size: UNSPEC
bpf_dynptr_clone: UNSPEC
bpf_modify_return_test_tp: UNSPEC
bpf_wq_init: UNSPEC
bpf_wq_set_callback_impl: UNSPEC
bpf_wq_start: UNSPEC
bpf_preempt_disable: UNSPEC
bpf_preempt_enable: UNSPEC
bpf_iter_bits_new: UNSPEC
bpf_iter_bits_next: UNSPEC
bpf_iter_bits_destroy: UNSPEC
bpf_copy_from_user_str: UNSPEC
bpf_get_kmem_cache: UNSPEC
bpf_iter_kmem_cache_new: UNSPEC
bpf_iter_kmem_cache_next: UNSPEC
bpf_iter_kmem_cache_destroy: UNSPEC
bpf_local_irq_save: UNSPEC
bpf_local_irq_restore: UNSPEC
bpf_skb_set_fou_encap: SCHED_CLS
bpf_skb_get_fou_encap: SCHED_CLS
bpf_xdp_ct_alloc: XDP, SCHED_CLS
bpf_xdp_ct_lookup: XDP, SCHED_CLS
bpf_skb_ct_alloc: XDP, SCHED_CLS
bpf_skb_ct_lookup: XDP, SCHED_CLS
bpf_ct_insert_entry: XDP, SCHED_CLS
bpf_ct_release: XDP, SCHED_CLS
bpf_ct_set_timeout: XDP, SCHED_CLS
bpf_ct_change_timeout: XDP, SCHED_CLS
bpf_ct_set_status: XDP, SCHED_CLS
bpf_ct_change_status: XDP, SCHED_CLS
bpf_ct_set_nat_info: XDP, SCHED_CLS
bpf_xdp_flow_lookup: XDP
bpf_skb_get_xfrm_info: SCHED_CLS
bpf_skb_set_xfrm_info: SCHED_CLS
bpf_xdp_get_xfrm_state: XDP
bpf_xdp_xfrm_state_release: XDP
name: XDP
bpf_dynptr_from_skb: LWT_OUT, SCHED_ACT, SCHED_CLS, LWT_XMIT, NETFILTER,
LWT_IN, SK_SKB, LWT_SEG6LOCAL, SOCKET_FILTER, CGROUP_SKB
bpf_dynptr_from_xdp: XDP
bpf_sock_addr_set_sun_path: CGROUP_SOCK_ADDR
bpf_sk_assign_tcp_reqsk: SCHED_CLS
bpf_kfunc_call_test_release: SCHED_CLS, SYSCALL
bpf_kfunc_call_memb_release: SCHED_CLS, SYSCALL
---------------------------------------------------
The c code results:
[106425] scx_bpf_select_cpu_dfl
[106393] scx_bpf_dsq_insert
[106394] scx_bpf_dsq_insert_vtime
[106381] scx_bpf_dispatch
[106391] scx_bpf_dispatch_vtime
[106389] scx_bpf_dispatch_nr_slots
[106382] scx_bpf_dispatch_cancel
[106398] scx_bpf_dsq_move_to_local
[106369] scx_bpf_consume
[106396] scx_bpf_dsq_move_set_slice SYSCALL
[106397] scx_bpf_dsq_move_set_vtime SYSCALL
[106395] scx_bpf_dsq_move SYSCALL
[106399] scx_bpf_dsq_move_vtime SYSCALL
[106386] scx_bpf_dispatch_from_dsq_set_slice SYSCALL
[106388] scx_bpf_dispatch_from_dsq_set_vtime SYSCALL
[106384] scx_bpf_dispatch_from_dsq SYSCALL
[106392] scx_bpf_dispatch_vtime_from_dsq SYSCALL
[106423] scx_bpf_reenqueue_local
[106378] scx_bpf_create_dsq SYSCALL
[106413] scx_bpf_kick_cpu SYSCALL
[106401] scx_bpf_dsq_nr_queued SYSCALL
[106379] scx_bpf_destroy_dsq SYSCALL
[59846 ] bpf_iter_scx_dsq_new SYSCALL
[59848 ] bpf_iter_scx_dsq_next SYSCALL
[59844 ] bpf_iter_scx_dsq_destroy SYSCALL
[106406] scx_bpf_exit_bstr SYSCALL
[106404] scx_bpf_error_bstr SYSCALL
[106403] scx_bpf_dump_bstr SYSCALL
[106373] scx_bpf_cpuperf_cap SYSCALL
[106374] scx_bpf_cpuperf_cur SYSCALL
[106376] scx_bpf_cpuperf_set SYSCALL
[106415] scx_bpf_nr_cpu_ids SYSCALL
[106411] scx_bpf_get_possible_cpumask SYSCALL
[106410] scx_bpf_get_online_cpumask SYSCALL
[106420] scx_bpf_put_cpumask SYSCALL
[106408] scx_bpf_get_idle_cpumask SYSCALL
[106409] scx_bpf_get_idle_smtmask SYSCALL
[106422] scx_bpf_put_idle_cpumask SYSCALL
[106433] scx_bpf_test_and_clear_cpu_idle SYSCALL
[106418] scx_bpf_pick_idle_cpu SYSCALL
[106417] scx_bpf_pick_any_cpu SYSCALL
[106431] scx_bpf_task_running SYSCALL
[106429] scx_bpf_task_cpu SYSCALL
[106371] scx_bpf_cpu_rq SYSCALL
[106427] scx_bpf_task_cgroup SYSCALL
[106414] scx_bpf_now SYSCALL
[62231 ] cgroup_rstat_updated
[62225 ] cgroup_rstat_flush
[60053 ] bpf_lookup_user_key
[60051 ] bpf_lookup_system_key
[59954 ] bpf_key_put
[60551 ] bpf_session_is_return KPROBE
[60550 ] bpf_session_cookie KPROBE
[64314 ] crash_kexec XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60256 ] bpf_obj_new_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60290 ] bpf_percpu_obj_new_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60242 ] bpf_obj_drop_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60289 ] bpf_percpu_obj_drop_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60484 ] bpf_refcount_acquire_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60027 ] bpf_list_push_front_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60026 ] bpf_list_push_back_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60024 ] bpf_list_pop_front XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60023 ] bpf_list_pop_back XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60797 ] bpf_task_acquire XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60808 ] bpf_task_release XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60472 ] bpf_rbtree_remove XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60468 ] bpf_rbtree_add_impl XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60470 ] bpf_rbtree_first XDP SYSCALL SCHED_CLS
CGROUP_SKB
[59305 ] bpf_cgroup_acquire XDP SYSCALL SCHED_CLS
CGROUP_SKB
[59320 ] bpf_cgroup_release XDP SYSCALL SCHED_CLS
CGROUP_SKB
[59307 ] bpf_cgroup_ancestor XDP SYSCALL SCHED_CLS
CGROUP_SKB
[59309 ] bpf_cgroup_from_id XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60818 ] bpf_task_under_cgroup XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60805 ] bpf_task_get_cgroup1 XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60801 ] bpf_task_from_pid XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60803 ] bpf_task_from_vpid XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60871 ] bpf_throw XDP SYSCALL SCHED_CLS
CGROUP_SKB
[60539 ] bpf_send_signal_task XDP SYSCALL SCHED_CLS
CGROUP_SKB
[59303 ] bpf_cast_to_kern_ctx KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60476 ] bpf_rdonly_cast KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60473 ] bpf_rcu_read_lock KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60474 ] bpf_rcu_read_unlock KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59556 ] bpf_dynptr_slice KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59557 ] bpf_dynptr_slice_rdwr KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59834 ] bpf_iter_num_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59836 ] bpf_iter_num_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59832 ] bpf_iter_num_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59867 ] bpf_iter_task_vma_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59869 ] bpf_iter_task_vma_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59865 ] bpf_iter_task_vma_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59774 ] bpf_iter_css_task_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59776 ] bpf_iter_css_task_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59772 ] bpf_iter_css_task_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59768 ] bpf_iter_css_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59770 ] bpf_iter_css_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59766 ] bpf_iter_css_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59858 ] bpf_iter_task_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59860 ] bpf_iter_task_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59854 ] bpf_iter_task_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59528 ] bpf_dynptr_adjust KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59546 ] bpf_dynptr_is_null KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59547 ] bpf_dynptr_is_rdonly KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59554 ] bpf_dynptr_size KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59532 ] bpf_dynptr_clone KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60197 ] bpf_modify_return_test_tp KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60981 ] bpf_wq_init KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60983 ] bpf_wq_set_callback_impl KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60985 ] bpf_wq_start KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60311 ] bpf_preempt_disable KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60312 ] bpf_preempt_enable KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59746 ] bpf_iter_bits_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59748 ] bpf_iter_bits_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59744 ] bpf_iter_bits_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59356 ] bpf_copy_from_user_str KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59657 ] bpf_get_kmem_cache KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59807 ] bpf_iter_kmem_cache_new KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59809 ] bpf_iter_kmem_cache_next KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59805 ] bpf_iter_kmem_cache_destroy KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60030 ] bpf_local_irq_save KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60029 ] bpf_local_irq_restore KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[60153 ] bpf_map_sum_elem_count KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59280 ] bpf_arena_alloc_pages KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59282 ] bpf_arena_free_pages KPROBE XDP SYSCALL SCHED_CLS
SCHED_ACT SK_SKB SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT
LWT_SEG6LOCAL NETFILTER
[59404 ] bpf_cpumask_create SYSCALL
[59416 ] bpf_cpumask_release SYSCALL
[59390 ] bpf_cpumask_acquire SYSCALL
[59409 ] bpf_cpumask_first SYSCALL
[59411 ] bpf_cpumask_first_zero SYSCALL
[59410 ] bpf_cpumask_first_and SYSCALL
[59419 ] bpf_cpumask_set_cpu SYSCALL
[59400 ] bpf_cpumask_clear_cpu SYSCALL
[59426 ] bpf_cpumask_test_cpu SYSCALL
[59424 ] bpf_cpumask_test_and_set_cpu SYSCALL
[59423 ] bpf_cpumask_test_and_clear_cpu SYSCALL
[59420 ] bpf_cpumask_setall SYSCALL
[59398 ] bpf_cpumask_clear SYSCALL
[59392 ] bpf_cpumask_and SYSCALL
[59415 ] bpf_cpumask_or SYSCALL
[59428 ] bpf_cpumask_xor SYSCALL
[59408 ] bpf_cpumask_equal SYSCALL
[59413 ] bpf_cpumask_intersects SYSCALL
[59421 ] bpf_cpumask_subset SYSCALL
[59406 ] bpf_cpumask_empty SYSCALL
[59412 ] bpf_cpumask_full SYSCALL
[59402 ] bpf_cpumask_copy SYSCALL
[59396 ] bpf_cpumask_any_distribute SYSCALL
[59394 ] bpf_cpumask_any_and_distribute SYSCALL
[59427 ] bpf_cpumask_weight SYSCALL
[59434 ] bpf_crypto_ctx_create SYSCALL
[59436 ] bpf_crypto_ctx_release SYSCALL
[59432 ] bpf_crypto_ctx_acquire SYSCALL
[59438 ] bpf_crypto_decrypt XDP SCHED_CLS SCHED_ACT
[59439 ] bpf_crypto_encrypt XDP SCHED_CLS SCHED_ACT
[59538 ] bpf_dynptr_from_skb SCHED_CLS SCHED_ACT SK_SKB
SOCKET_FILTER CGROUP_SKB LWT_OUT LWT_IN LWT_XMIT LWT_SEG6LOCAL NETFILTER
[59542 ] bpf_dynptr_from_xdp XDP
[60702 ] bpf_sock_addr_set_sun_path CGROUP_SKB
[60564 ] bpf_sk_assign_tcp_reqsk SCHED_CLS
[60712 ] bpf_sock_destroy
[61023 ] bpf_xdp_metadata_rx_timestamp
[61021 ] bpf_xdp_metadata_rx_hash
[61025 ] bpf_xdp_metadata_rx_vlan_tag
[60193 ] bpf_modify_return_test
[60195 ] bpf_modify_return_test2
[59582 ] bpf_fentry_test1
[59960 ] bpf_kfunc_call_test_release SYSCALL SCHED_CLS
[59957 ] bpf_kfunc_call_memb_release SYSCALL SCHED_CLS
[60998 ] bpf_xdp_ct_alloc XDP SCHED_CLS
[61000 ] bpf_xdp_ct_lookup XDP SCHED_CLS
[60635 ] bpf_skb_ct_alloc XDP SCHED_CLS
[60637 ] bpf_skb_ct_lookup XDP SCHED_CLS
[59472 ] bpf_ct_insert_entry XDP SCHED_CLS
[59474 ] bpf_ct_release XDP SCHED_CLS
[59480 ] bpf_ct_set_timeout XDP SCHED_CLS
[59470 ] bpf_ct_change_timeout XDP SCHED_CLS
[59478 ] bpf_ct_set_status XDP SCHED_CLS
[59468 ] bpf_ct_change_status XDP SCHED_CLS
[59476 ] bpf_ct_set_nat_info XDP SCHED_CLS
[65211 ] cubictcp_init
[65212 ] cubictcp_recalc_ssthresh
[65208 ] cubictcp_cong_avoid
[65214 ] cubictcp_state
[65210 ] cubictcp_cwnd_event
[65207 ] cubictcp_acked
[113327] tcp_reno_ssthresh
[113326] tcp_reno_cong_avoid
[113328] tcp_reno_undo_cwnd
[113396] tcp_slow_start
[113087] tcp_cong_avoid_ai
[61008 ] bpf_xdp_get_xfrm_state XDP
[61037 ] bpf_xdp_xfrm_state_release XDP
--------------------------------------------------------------
The script:
#!/bin/python3
import os
import re
from collections import defaultdict
# Regular expression to match register_btf_kfunc_id_set calls (supports
multi-line)
register_pattern = re.compile(
r'register_btf_kfunc_id_set\s*\(\s*(BPF_PROG_TYPE_\w+)\s*,' #
Match function name and first argument
r'[\s\S]*?&(\w+)\s*\)', # Match second argument (supports multi-line)
re.DOTALL # Enable multi-line matching
)
# Regular expression to match struct variable definitions and .set
initialization
struct_var_pattern = re.compile(
r'static\s+const\s+struct\s+btf_kfunc_id_set\s+' # Match struct
variable definition
r'(\w+)\s*=\s*\{.*?\.set\s*=\s*&(\w+)\s*,.*?\};', # Match .set
initialization
re.DOTALL # Enable multi-line matching
)
# Regular expression to match BTF_KFUNCS_START and BTF_KFUNCS_END blocks
btf_kfuncs_pattern = re.compile(
r'BTF_KFUNCS_START\s*\(\s*(\w+)\s*\)' # Match BTF_KFUNCS_START
r'([\s\S]*?)' # Match any content (non-greedy)
r'BTF_KFUNCS_END\s*\(\s*\1\s*\)', # Match BTF_KFUNCS_END with the
same parameter
re.DOTALL # Enable multi-line matching
)
# Regular expression to match BTF_ID_FLAGS(func, ...) declared functions
btf_id_flags_pattern = re.compile(
r'BTF_ID_FLAGS\s*\(\s*func\s*,\s*(\w+)\s*(?:,\s*.*?)?\)' # Match
function name
)
# Dictionary to store functions and their corresponding prog_types
func_prog_types = defaultdict(set)
# Set of prog_types to exclude
excluded_prog_types = {
"TRACING",
"EXT",
"LSM",
"STRUCT_OPS",
}
def scan_file(file_path):
"""
Scan a single file to find register_btf_kfunc_id_set calls and
further scan for struct variables and BTF_KFUNCS blocks.
"""
with open(file_path, 'r', encoding='utf-8', errors='ignore') as file:
content = file.read()
content = content.replace('\r\n', '\n')
# Find register_btf_kfunc_id_set calls
register_matches = register_pattern.findall(content)
for prog_type, kfunc_set in register_matches:
# Remove BPF_PROG_TYPE_ prefix
prog_type_short = prog_type.replace("BPF_PROG_TYPE_", "")
# Skip excluded prog_types
if prog_type_short in excluded_prog_types:
continue
print(f"File: {file_path}")
print(f" prog_type: {prog_type_short}")
print(f" kfunc_set: {kfunc_set}")
# Find struct variables with the same name
struct_var_matches = struct_var_pattern.findall(content)
found = False
for struct_var_name, set_name in struct_var_matches:
if struct_var_name == kfunc_set:
print(f" Struct variable: {struct_var_name}")
print(f" .set initialized with: {set_name}")
found = True
# Find BTF_KFUNCS_START and BTF_KFUNCS_END blocks
btf_kfuncs_matches =
btf_kfuncs_pattern.findall(content)
#print(btf_kfuncs_matches)
if btf_kfuncs_matches:
for func, block_content in btf_kfuncs_matches:
if func == set_name:
#block_content = btf_kfuncs_match.group(2)
print(f" BTF_KFUNCS block found for
{set_name}")
# Extract functions declared in
BTF_ID_FLAGS(func, ...)
func_matches =
btf_id_flags_pattern.findall(block_content)
if func_matches:
print(" Functions declared in block:")
for func_name in func_matches:
print(f" {func_name}
(prog_type: {prog_type_short})")
# Record function and its
corresponding prog_type
func_prog_types[func_name].add(prog_type_short)
else:
print(" No functions found in block")
else:
print(f" No BTF_KFUNCS block found for
{set_name}")
break
if not found:
print(f" No matching struct variable found for
{kfunc_set}")
print("-" * 40)
def scan_repository(repo_path):
"""
Traverse all .c and .h files in the repository and call scan_file
for each file.
"""
for root, dirs, files in os.walk(repo_path):
# Exclude selftest directory
if "selftests" in dirs:
dirs.remove("selftests")
for file_name in files:
if file_name.endswith(('.c', '.h')):
file_path = os.path.join(root, file_name)
scan_file(file_path)
def print_func_prog_types():
print("\nSummary of functions and their corresponding prog_types:")
for func_name, prog_types in func_prog_types.items():
print(f"{func_name}: {', '.join(prog_types)}")
if __name__ == "__main__":
repo_path = "/home/dylane/sdb/bpf-next2/bpf-next" # Replace with
your repository path
print(f"Scanning repository: {repo_path}")
scan_repository(repo_path)
print_func_prog_types()
------------------------------------------------------
the c code:
static const struct {
const char *name;
int code;
} program_types[] = {
#define _T(n) { #n, BPF_PROG_TYPE_ ## n }
_T(KPROBE),
_T(XDP),
_T(SYSCALL),
_T(SCHED_CLS),
_T(SCHED_ACT),
_T(SK_SKB),
_T(SOCKET_FILTER),
_T(CGROUP_SKB),
_T(LWT_OUT),
_T(LWT_IN),
_T(LWT_XMIT),
_T(LWT_SEG6LOCAL),
_T(NETFILTER)
#undef _T
};
void test_libbpf_probe_kfuncs_many(void)
{
int i, kfunc_id, ret, id;
const struct btf_type *t;
struct btf *btf = NULL;
const char *kfunc;
const char *tag;
btf = btf__parse("/sys/kernel/btf/vmlinux", NULL);
if (!ASSERT_OK_PTR(btf, "btf_parse"))
return;
for (id = 0; id < btf__type_cnt(btf); ++id) {
t = btf__type_by_id(btf, id);
if (!t)
continue;
if (!btf_is_decl_tag(t))
continue;
tag = btf__name_by_offset(btf, t->name_off);
if (strcmp(tag, "bpf_kfunc") != 0)
continue;
kfunc_id = t->type;
t = btf__type_by_id(btf, kfunc_id);
if (!btf_is_func(t))
continue;
kfunc = btf__name_by_offset(btf, t->name_off);
printf("[%-6d] %-42s ", kfunc_id, kfunc);
for (i = 0; i < ARRAY_SIZE(program_types); ++i) {
ret = libbpf_probe_bpf_kfunc(program_types[i].code, kfunc_id, -1, NULL);
if (ret < 0)
printf("%-2d ", ret);
else if (ret == 0)
printf("%2s", "");
else
printf("%2s ", program_types[i].name);
}
printf("\n");
}
btf__free(btf);
}
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-24 16:59 ` [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe Tao Chen
@ 2025-02-25 1:15 ` Andrii Nakryiko
2025-02-25 5:44 ` Tao Chen
0 siblings, 1 reply; 16+ messages in thread
From: Andrii Nakryiko @ 2025-02-25 1:15 UTC (permalink / raw)
To: Tao Chen
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane
On Mon, Feb 24, 2025 at 9:03 AM Tao Chen <chen.dylane@linux.dev> wrote:
>
> Kprobe prog type kfuncs like bpf_session_is_return and
> bpf_session_cookie will check the expected_attach_type,
> so init the expected_attach_type here.
>
> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
> ---
> tools/lib/bpf/libbpf_probes.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
> index 8efebc18a215..bb5b457ddc80 100644
> --- a/tools/lib/bpf/libbpf_probes.c
> +++ b/tools/lib/bpf/libbpf_probes.c
> @@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
> break;
> case BPF_PROG_TYPE_KPROBE:
> opts.kern_version = get_kernel_version();
> + opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
so KPROBE_SESSION is relative recent feature, if we unconditionally
specify this, we'll regress some feature probes for old kernels where
KPROBE_SESSION isn't supported, no?
pw-bot: cr
> break;
> case BPF_PROG_TYPE_LIRC_MODE2:
> opts.expected_attach_type = BPF_LIRC_MODE2;
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-24 16:59 ` [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
@ 2025-02-25 1:15 ` Andrii Nakryiko
2025-02-25 5:47 ` Tao Chen
0 siblings, 1 reply; 16+ messages in thread
From: Andrii Nakryiko @ 2025-02-25 1:15 UTC (permalink / raw)
To: Tao Chen
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane, Tao Chen
On Mon, Feb 24, 2025 at 9:02 AM Tao Chen <chen.dylane@linux.dev> wrote:
>
> Similarly to libbpf_probe_bpf_helper, the libbpf_probe_bpf_kfunc
> used to test the availability of the different eBPF kfuncs on the
> current system.
>
> Cc: Tao Chen <dylane.chen@didiglobal.com>
> Reviewed-by: Jiri Olsa <jolsa@kernel.org>
> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
> ---
> tools/lib/bpf/libbpf.h | 19 ++++++++++++-
> tools/lib/bpf/libbpf.map | 1 +
> tools/lib/bpf/libbpf_probes.c | 51 +++++++++++++++++++++++++++++++++++
> 3 files changed, 70 insertions(+), 1 deletion(-)
>
[...]
> + buf[0] = '\0';
> + ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
> + buf, sizeof(buf));
> + if (ret < 0)
> + return libbpf_err(ret);
> +
> + if (ret > 0)
> + return 1; /* assume supported */
> +
> + /* If BPF verifier recognizes BPF kfunc but it's not supported for
> + * given BPF program type, it will emit "calling kernel function
> + * <name> is not allowed". If the kfunc id is invalid,
> + * it will emit "kernel btf_id <id> is not a function". If BTF fd
> + * invalid in module BTF, it will emit "invalid module BTF fd specified" or
> + * "negative offset disallowed for kernel module function call". If
> + * kfunc prog not dev buound, it will emit "metadata kfuncs require
> + * device-bound program".
> + */
> + if (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
> + strstr(buf, "invalid module BTF fd") ||
why is invalid module BTF FD not an error (negative return)?
> + strstr(buf, "negative offset disallowed") ||
> + strstr(buf, "device-bound program"))
> + return 0;
> +
> + return 1;
> +}
> +
> int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
> const void *opts)
> {
> --
> 2.43.0
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe
2025-02-24 17:13 ` [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
@ 2025-02-25 1:28 ` Eduard Zingerman
0 siblings, 0 replies; 16+ messages in thread
From: Eduard Zingerman @ 2025-02-25 1:28 UTC (permalink / raw)
To: Tao Chen, ast, daniel, andrii, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
On Tue, 2025-02-25 at 01:13 +0800, Tao Chen wrote:
[...]
> Hi Eduard,
> I used a simple script to find all kfunc prog types and comapre it with
> your program, most of them are consistent, the results are as follows,
> and i add pathch 4 additionally to fix kfunc probe like
> bpf_session_is_return.
Hi Tao,
Thank you for putting together the python script. I double checked
output of the script and the output of the test and find these
consistent.
(I noticed that a few kfuncs are in the vmlinux.h but are not printed
by the test:
- bpf_skb_get_xfrm_info
- bpf_skb_set_xfrm_info
- bpf_xdp_get_xfrm_state
- bpf_xdp_xfrm_state_release
- bpf_dynptr_from_skb
- bpf_dynptr_from_xdp
- bpf_sock_addr_set_sun_path
but that is another topic).
Thanks,
Eduard
[...]
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-25 1:15 ` Andrii Nakryiko
@ 2025-02-25 5:44 ` Tao Chen
2025-02-25 17:04 ` Andrii Nakryiko
0 siblings, 1 reply; 16+ messages in thread
From: Tao Chen @ 2025-02-25 5:44 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane
在 2025/2/25 09:15, Andrii Nakryiko 写道:
> On Mon, Feb 24, 2025 at 9:03 AM Tao Chen <chen.dylane@linux.dev> wrote:
>>
>> Kprobe prog type kfuncs like bpf_session_is_return and
>> bpf_session_cookie will check the expected_attach_type,
>> so init the expected_attach_type here.
>>
>> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
>> ---
>> tools/lib/bpf/libbpf_probes.c | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
>> index 8efebc18a215..bb5b457ddc80 100644
>> --- a/tools/lib/bpf/libbpf_probes.c
>> +++ b/tools/lib/bpf/libbpf_probes.c
>> @@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
>> break;
>> case BPF_PROG_TYPE_KPROBE:
>> opts.kern_version = get_kernel_version();
>> + opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
>
> so KPROBE_SESSION is relative recent feature, if we unconditionally
> specify this, we'll regress some feature probes for old kernels where
> KPROBE_SESSION isn't supported, no?
>
Yeah, maybe we can detect the kernel version first, will fix it.
+ if (opts.kern_version >= KERNEL_VERSION(6, 12, 0))
+ opts.expected_attach_type =BPF_TRACE_KPROBE_SESSION;
> pw-bot: cr
>
>> break;
>> case BPF_PROG_TYPE_LIRC_MODE2:
>> opts.expected_attach_type = BPF_LIRC_MODE2;
>> --
>> 2.43.0
>>
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-25 1:15 ` Andrii Nakryiko
@ 2025-02-25 5:47 ` Tao Chen
2025-02-25 17:01 ` Andrii Nakryiko
0 siblings, 1 reply; 16+ messages in thread
From: Tao Chen @ 2025-02-25 5:47 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane, Tao Chen
在 2025/2/25 09:15, Andrii Nakryiko 写道:
> On Mon, Feb 24, 2025 at 9:02 AM Tao Chen <chen.dylane@linux.dev> wrote:
>>
>> Similarly to libbpf_probe_bpf_helper, the libbpf_probe_bpf_kfunc
>> used to test the availability of the different eBPF kfuncs on the
>> current system.
>>
>> Cc: Tao Chen <dylane.chen@didiglobal.com>
>> Reviewed-by: Jiri Olsa <jolsa@kernel.org>
>> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
>> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
>> ---
>> tools/lib/bpf/libbpf.h | 19 ++++++++++++-
>> tools/lib/bpf/libbpf.map | 1 +
>> tools/lib/bpf/libbpf_probes.c | 51 +++++++++++++++++++++++++++++++++++
>> 3 files changed, 70 insertions(+), 1 deletion(-)
>>
>
> [...]
>
>> + buf[0] = '\0';
>> + ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
>> + buf, sizeof(buf));
>> + if (ret < 0)
>> + return libbpf_err(ret);
>> +
>> + if (ret > 0)
>> + return 1; /* assume supported */
>> +
>> + /* If BPF verifier recognizes BPF kfunc but it's not supported for
>> + * given BPF program type, it will emit "calling kernel function
>> + * <name> is not allowed". If the kfunc id is invalid,
>> + * it will emit "kernel btf_id <id> is not a function". If BTF fd
>> + * invalid in module BTF, it will emit "invalid module BTF fd specified" or
>> + * "negative offset disallowed for kernel module function call". If
>> + * kfunc prog not dev buound, it will emit "metadata kfuncs require
>> + * device-bound program".
>> + */
>> + if (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
>> + strstr(buf, "invalid module BTF fd") ||
>
> why is invalid module BTF FD not an error (negative return)?
>
>> + strstr(buf, "negative offset disallowed") ||
>> + strstr(buf, "device-bound program"))
>> + return 0;
>> +
>> + return 1;
>> +}
>> +
>> int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
>> const void *opts)
>> {
>> --
>> 2.43.0
>>
In probe_prog_load, err will be checked and converted into either 0 or 1.
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-25 5:47 ` Tao Chen
@ 2025-02-25 17:01 ` Andrii Nakryiko
0 siblings, 0 replies; 16+ messages in thread
From: Andrii Nakryiko @ 2025-02-25 17:01 UTC (permalink / raw)
To: Tao Chen
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane, Tao Chen
On Mon, Feb 24, 2025 at 9:47 PM Tao Chen <chen.dylane@linux.dev> wrote:
>
> 在 2025/2/25 09:15, Andrii Nakryiko 写道:
> > On Mon, Feb 24, 2025 at 9:02 AM Tao Chen <chen.dylane@linux.dev> wrote:
> >>
> >> Similarly to libbpf_probe_bpf_helper, the libbpf_probe_bpf_kfunc
> >> used to test the availability of the different eBPF kfuncs on the
> >> current system.
> >>
> >> Cc: Tao Chen <dylane.chen@didiglobal.com>
> >> Reviewed-by: Jiri Olsa <jolsa@kernel.org>
> >> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
> >> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
> >> ---
> >> tools/lib/bpf/libbpf.h | 19 ++++++++++++-
> >> tools/lib/bpf/libbpf.map | 1 +
> >> tools/lib/bpf/libbpf_probes.c | 51 +++++++++++++++++++++++++++++++++++
> >> 3 files changed, 70 insertions(+), 1 deletion(-)
> >>
> >
> > [...]
> >
> >> + buf[0] = '\0';
> >> + ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
> >> + buf, sizeof(buf));
> >> + if (ret < 0)
> >> + return libbpf_err(ret);
> >> +
> >> + if (ret > 0)
> >> + return 1; /* assume supported */
> >> +
> >> + /* If BPF verifier recognizes BPF kfunc but it's not supported for
> >> + * given BPF program type, it will emit "calling kernel function
> >> + * <name> is not allowed". If the kfunc id is invalid,
> >> + * it will emit "kernel btf_id <id> is not a function". If BTF fd
> >> + * invalid in module BTF, it will emit "invalid module BTF fd specified" or
> >> + * "negative offset disallowed for kernel module function call". If
> >> + * kfunc prog not dev buound, it will emit "metadata kfuncs require
> >> + * device-bound program".
> >> + */
> >> + if (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
> >> + strstr(buf, "invalid module BTF fd") ||
> >
> > why is invalid module BTF FD not an error (negative return)?
> >
> >> + strstr(buf, "negative offset disallowed") ||
> >> + strstr(buf, "device-bound program"))
> >> + return 0;
> >> +
> >> + return 1;
> >> +}
> >> +
> >> int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
> >> const void *opts)
> >> {
> >> --
> >> 2.43.0
> >>
>
> In probe_prog_load, err will be checked and converted into either 0 or 1.
I guess what I was getting at is that providing invalid module BTF FD
is not a "not supported" case, it's an error case (and so should
result in negative return)
>
> --
> Best Regards
> Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-25 5:44 ` Tao Chen
@ 2025-02-25 17:04 ` Andrii Nakryiko
2025-02-26 11:12 ` Jiri Olsa
0 siblings, 1 reply; 16+ messages in thread
From: Andrii Nakryiko @ 2025-02-25 17:04 UTC (permalink / raw)
To: Tao Chen
Cc: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo, bpf,
linux-kernel, chen.dylane
On Mon, Feb 24, 2025 at 9:44 PM Tao Chen <chen.dylane@linux.dev> wrote:
>
> 在 2025/2/25 09:15, Andrii Nakryiko 写道:
> > On Mon, Feb 24, 2025 at 9:03 AM Tao Chen <chen.dylane@linux.dev> wrote:
> >>
> >> Kprobe prog type kfuncs like bpf_session_is_return and
> >> bpf_session_cookie will check the expected_attach_type,
> >> so init the expected_attach_type here.
> >>
> >> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
> >> ---
> >> tools/lib/bpf/libbpf_probes.c | 1 +
> >> 1 file changed, 1 insertion(+)
> >>
> >> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
> >> index 8efebc18a215..bb5b457ddc80 100644
> >> --- a/tools/lib/bpf/libbpf_probes.c
> >> +++ b/tools/lib/bpf/libbpf_probes.c
> >> @@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
> >> break;
> >> case BPF_PROG_TYPE_KPROBE:
> >> opts.kern_version = get_kernel_version();
> >> + opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
> >
> > so KPROBE_SESSION is relative recent feature, if we unconditionally
> > specify this, we'll regress some feature probes for old kernels where
> > KPROBE_SESSION isn't supported, no?
> >
>
> Yeah, maybe we can detect the kernel version first, will fix it.
Hold on. I think the entire probing API is kind of unfortunately
inadequate. Just the fact that we randomly pick some specific
expected_attach_type to do helpers/kfunc compatibility detection is
telling. expected_attach_type can change a set of available helpers,
and yet it's not even an input parameter for either
libbpf_probe_bpf_helper() or kfunc variant you are trying to add.
Basically, I'm questioning the validity of even adding this API to
libbpf. It feels like this kind of detection is simple enough for
application to do on its own.
>
> + if (opts.kern_version >= KERNEL_VERSION(6, 12, 0))
> + opts.expected_attach_type =BPF_TRACE_KPROBE_SESSION;
no, we shouldn't hard-code kernel version for feature detection (but
also see above, I'm not sure this API should be added in the first
place)
>
> > pw-bot: cr
> >
> >> break;
> >> case BPF_PROG_TYPE_LIRC_MODE2:
> >> opts.expected_attach_type = BPF_LIRC_MODE2;
> >> --
> >> 2.43.0
> >>
>
>
> --
> Best Regards
> Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-25 17:04 ` Andrii Nakryiko
@ 2025-02-26 11:12 ` Jiri Olsa
2025-02-26 16:10 ` Tao Chen
0 siblings, 1 reply; 16+ messages in thread
From: Jiri Olsa @ 2025-02-26 11:12 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Tao Chen, ast, daniel, andrii, eddyz87, haoluo, qmo, bpf,
linux-kernel, chen.dylane
On Tue, Feb 25, 2025 at 09:04:58AM -0800, Andrii Nakryiko wrote:
> On Mon, Feb 24, 2025 at 9:44 PM Tao Chen <chen.dylane@linux.dev> wrote:
> >
> > 在 2025/2/25 09:15, Andrii Nakryiko 写道:
> > > On Mon, Feb 24, 2025 at 9:03 AM Tao Chen <chen.dylane@linux.dev> wrote:
> > >>
> > >> Kprobe prog type kfuncs like bpf_session_is_return and
> > >> bpf_session_cookie will check the expected_attach_type,
> > >> so init the expected_attach_type here.
> > >>
> > >> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
> > >> ---
> > >> tools/lib/bpf/libbpf_probes.c | 1 +
> > >> 1 file changed, 1 insertion(+)
> > >>
> > >> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
> > >> index 8efebc18a215..bb5b457ddc80 100644
> > >> --- a/tools/lib/bpf/libbpf_probes.c
> > >> +++ b/tools/lib/bpf/libbpf_probes.c
> > >> @@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
> > >> break;
> > >> case BPF_PROG_TYPE_KPROBE:
> > >> opts.kern_version = get_kernel_version();
> > >> + opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
> > >
> > > so KPROBE_SESSION is relative recent feature, if we unconditionally
> > > specify this, we'll regress some feature probes for old kernels where
> > > KPROBE_SESSION isn't supported, no?
> > >
> >
> > Yeah, maybe we can detect the kernel version first, will fix it.
>
> Hold on. I think the entire probing API is kind of unfortunately
> inadequate. Just the fact that we randomly pick some specific
> expected_attach_type to do helpers/kfunc compatibility detection is
> telling. expected_attach_type can change a set of available helpers,
> and yet it's not even an input parameter for either
> libbpf_probe_bpf_helper() or kfunc variant you are trying to add.
could we use the libbpf_probe_bpf_kfunc opts argument and
allow to specify and override expected_attach_type?
jirka
>
> Basically, I'm questioning the validity of even adding this API to
> libbpf. It feels like this kind of detection is simple enough for
> application to do on its own.
>
> >
> > + if (opts.kern_version >= KERNEL_VERSION(6, 12, 0))
> > + opts.expected_attach_type =BPF_TRACE_KPROBE_SESSION;
>
> no, we shouldn't hard-code kernel version for feature detection (but
> also see above, I'm not sure this API should be added in the first
> place)
>
> >
> > > pw-bot: cr
> > >
> > >> break;
> > >> case BPF_PROG_TYPE_LIRC_MODE2:
> > >> opts.expected_attach_type = BPF_LIRC_MODE2;
> > >> --
> > >> 2.43.0
> > >>
> >
> >
> > --
> > Best Regards
> > Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe
2025-02-26 11:12 ` Jiri Olsa
@ 2025-02-26 16:10 ` Tao Chen
0 siblings, 0 replies; 16+ messages in thread
From: Tao Chen @ 2025-02-26 16:10 UTC (permalink / raw)
To: Jiri Olsa, Andrii Nakryiko
Cc: ast, daniel, andrii, eddyz87, haoluo, qmo, bpf, linux-kernel,
chen.dylane
在 2025/2/26 19:12, Jiri Olsa 写道:
> On Tue, Feb 25, 2025 at 09:04:58AM -0800, Andrii Nakryiko wrote:
>> On Mon, Feb 24, 2025 at 9:44 PM Tao Chen <chen.dylane@linux.dev> wrote:
>>>
>>> 在 2025/2/25 09:15, Andrii Nakryiko 写道:
>>>> On Mon, Feb 24, 2025 at 9:03 AM Tao Chen <chen.dylane@linux.dev> wrote:
>>>>>
>>>>> Kprobe prog type kfuncs like bpf_session_is_return and
>>>>> bpf_session_cookie will check the expected_attach_type,
>>>>> so init the expected_attach_type here.
>>>>>
>>>>> Signed-off-by: Tao Chen <chen.dylane@linux.dev>
>>>>> ---
>>>>> tools/lib/bpf/libbpf_probes.c | 1 +
>>>>> 1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
>>>>> index 8efebc18a215..bb5b457ddc80 100644
>>>>> --- a/tools/lib/bpf/libbpf_probes.c
>>>>> +++ b/tools/lib/bpf/libbpf_probes.c
>>>>> @@ -126,6 +126,7 @@ static int probe_prog_load(enum bpf_prog_type prog_type,
>>>>> break;
>>>>> case BPF_PROG_TYPE_KPROBE:
>>>>> opts.kern_version = get_kernel_version();
>>>>> + opts.expected_attach_type = BPF_TRACE_KPROBE_SESSION;
>>>>
>>>> so KPROBE_SESSION is relative recent feature, if we unconditionally
>>>> specify this, we'll regress some feature probes for old kernels where
>>>> KPROBE_SESSION isn't supported, no?
>>>>
>>>
>>> Yeah, maybe we can detect the kernel version first, will fix it.
>>
>> Hold on. I think the entire probing API is kind of unfortunately
>> inadequate. Just the fact that we randomly pick some specific
>> expected_attach_type to do helpers/kfunc compatibility detection is
>> telling. expected_attach_type can change a set of available helpers,
>> and yet it's not even an input parameter for either
>> libbpf_probe_bpf_helper() or kfunc variant you are trying to add.
>
> could we use the libbpf_probe_bpf_kfunc opts argument and
> allow to specify and override expected_attach_type?
>
> jirka
>
It looks great, btw, these probe apis already used in bpftool feature
function, so maybe we can continue to improve it including the
libbpf_probe_bpf_helper as andrii said.
>>
>> Basically, I'm questioning the validity of even adding this API to
>> libbpf. It feels like this kind of detection is simple enough for
>> application to do on its own.
>>
>>>
>>> + if (opts.kern_version >= KERNEL_VERSION(6, 12, 0))
>>> + opts.expected_attach_type =BPF_TRACE_KPROBE_SESSION;
>>
>> no, we shouldn't hard-code kernel version for feature detection (but
>> also see above, I'm not sure this API should be added in the first
>> place)
>>
>>>
>>>> pw-bot: cr
>>>>
>>>>> break;
>>>>> case BPF_PROG_TYPE_LIRC_MODE2:
>>>>> opts.expected_attach_type = BPF_LIRC_MODE2;
>>>>> --
>>>>> 2.43.0
>>>>>
>>>
>>>
>>> --
>>> Best Regards
>>> Tao Chen
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-02-26 16:11 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-24 16:59 [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 1/5] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 2/5] libbpf: Init fd_array when prog probe load Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 3/5] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
2025-02-25 1:15 ` Andrii Nakryiko
2025-02-25 5:47 ` Tao Chen
2025-02-25 17:01 ` Andrii Nakryiko
2025-02-24 16:59 ` [PATCH bpf-next v8 4/5] libbpf: Init kprobe prog expected_attach_type for kfunc probe Tao Chen
2025-02-25 1:15 ` Andrii Nakryiko
2025-02-25 5:44 ` Tao Chen
2025-02-25 17:04 ` Andrii Nakryiko
2025-02-26 11:12 ` Jiri Olsa
2025-02-26 16:10 ` Tao Chen
2025-02-24 16:59 ` [PATCH bpf-next v8 5/5] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
2025-02-24 17:13 ` [PATCH bpf-next v8 0/5] Add prog_kfunc feature probe Tao Chen
2025-02-25 1:28 ` Eduard Zingerman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox