* [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
@ 2025-02-12 15:39 Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-12 15:39 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
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:
- 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 (4):
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
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 | 86 +++++++++++---
.../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
4 files changed, 201 insertions(+), 16 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH bpf-next v7 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
@ 2025-02-12 15:39 ` Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 2/4] libbpf: Init fd_array when prog probe load Tao Chen
` (3 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-12 15:39 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, 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>
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
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] 13+ messages in thread
* [PATCH bpf-next v7 2/4] libbpf: Init fd_array when prog probe load
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
@ 2025-02-12 15:39 ` Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-12 15:39 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, 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>
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
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] 13+ messages in thread
* [PATCH bpf-next v7 3/4] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 2/4] libbpf: Init fd_array when prog probe load Tao Chen
@ 2025-02-12 15:39 ` Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
2025-02-17 5:21 ` [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
4 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-12 15:39 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, 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>
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
tools/lib/bpf/libbpf.h | 19 +++++++++++++-
tools/lib/bpf/libbpf.map | 1 +
tools/lib/bpf/libbpf_probes.c | 48 +++++++++++++++++++++++++++++++++++
3 files changed, 67 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..74928e26b5b9 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -431,6 +431,54 @@ 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 (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
+ strstr(buf, "invalid module BTF fd") ||
+ strstr(buf, "negative offset disallowed"))
+ 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] 13+ messages in thread
* [PATCH bpf-next v7 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
` (2 preceding siblings ...)
2025-02-12 15:39 ` [PATCH bpf-next v7 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
@ 2025-02-12 15:39 ` Tao Chen
2025-02-17 5:21 ` [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
4 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-12 15:39 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane, 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>
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
.../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] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
` (3 preceding siblings ...)
2025-02-12 15:39 ` [PATCH bpf-next v7 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
@ 2025-02-17 5:21 ` Tao Chen
2025-02-18 22:51 ` Eduard Zingerman
4 siblings, 1 reply; 13+ messages in thread
From: Tao Chen @ 2025-02-17 5:21 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo; +Cc: bpf, linux-kernel
在 2025/2/12 23:39, 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:
> - 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 (4):
> 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
> 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 | 86 +++++++++++---
> .../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
> 4 files changed, 201 insertions(+), 16 deletions(-)
>
Ping...
Hi Andrii, Eduard,
I've revised the previous suggestions. Please review it again. Thanks.
--
Best Regards
Dylane Chen
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-17 5:21 ` [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
@ 2025-02-18 22:51 ` Eduard Zingerman
2025-02-20 18:09 ` Tao Chen
2025-02-21 1:07 ` Andrii Nakryiko
0 siblings, 2 replies; 13+ messages in thread
From: Eduard Zingerman @ 2025-02-18 22:51 UTC (permalink / raw)
To: Tao Chen, ast, daniel, andrii, haoluo, jolsa, qmo; +Cc: bpf, linux-kernel
On Mon, 2025-02-17 at 13:21 +0800, Tao Chen wrote:
> 在 2025/2/12 23:39, 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:
> > - 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 (4):
> > 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
> > 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 | 86 +++++++++++---
> > .../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
> > 4 files changed, 201 insertions(+), 16 deletions(-)
> >
>
> Ping...
>
> Hi Andrii, Eduard,
>
> I've revised the previous suggestions. Please review it again. Thanks.
>
I tried the test enumerating all kfuncs in BTF and doing
libbpf_probe_bpf_kfunc for BPF_PROG_TYPE_{KPROBE,XDP}.
(Source code at the end of the email).
The set of kfuncs returned for XDP looks correct.
The set of kfuncs returned for KPROBE contains a few incorrect entries:
- bpf_xdp_metadata_rx_hash
- bpf_xdp_metadata_rx_timestamp
- bpf_xdp_metadata_rx_vlan_tag
This is because of a different string reported by verifier for these
three functions.
Ideally, I'd write some script looking for
register_btf_kfunc_id_set(BPF_PROG_TYPE_***, kfunc_set)
calls in the kernel source code and extracting the prog type /
functions in the set, and comparing results of this script with
output of the test below for all program types.
But up to you if you'd like to do such rigorous verification or not.
Otherwise patch-set looks good to me, for all patch-set:
Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
--- 8< -----------------------------------------------------
static const struct {
const char *name;
int code;
} program_types[] = {
#define _T(n) { #n, BPF_PROG_TYPE_ ## n }
_T(KPROBE),
_T(XDP),
#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 (!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("%-8d ", ret);
else if (ret == 0)
printf("%8s ", "");
else
printf("%8s ", program_types[i].name);
}
printf("\n");
}
btf__free(btf);
}
----------------------------------------------------- >8 ---
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-18 22:51 ` Eduard Zingerman
@ 2025-02-20 18:09 ` Tao Chen
2025-02-20 18:43 ` Eduard Zingerman
2025-02-21 1:07 ` Andrii Nakryiko
1 sibling, 1 reply; 13+ messages in thread
From: Tao Chen @ 2025-02-20 18:09 UTC (permalink / raw)
To: Eduard Zingerman, ast, daniel, andrii, haoluo, jolsa, qmo
Cc: bpf, linux-kernel
在 2025/2/19 06:51, Eduard Zingerman 写道:
> On Mon, 2025-02-17 at 13:21 +0800, Tao Chen wrote:
>> 在 2025/2/12 23:39, 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:
>>> - 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 (4):
>>> 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
>>> 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 | 86 +++++++++++---
>>> .../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
>>> 4 files changed, 201 insertions(+), 16 deletions(-)
>>>
>>
>> Ping...
>>
>> Hi Andrii, Eduard,
>>
>> I've revised the previous suggestions. Please review it again. Thanks.
>>
>
> I tried the test enumerating all kfuncs in BTF and doing
> libbpf_probe_bpf_kfunc for BPF_PROG_TYPE_{KPROBE,XDP}.
> (Source code at the end of the email).
>
> The set of kfuncs returned for XDP looks correct.
> The set of kfuncs returned for KPROBE contains a few incorrect entries:
> - bpf_xdp_metadata_rx_hash
> - bpf_xdp_metadata_rx_timestamp
> - bpf_xdp_metadata_rx_vlan_tag
>
> This is because of a different string reported by verifier for these
> three functions.
>
> Ideally, I'd write some script looking for
> register_btf_kfunc_id_set(BPF_PROG_TYPE_***, kfunc_set)
> calls in the kernel source code and extracting the prog type /
> functions in the set, and comparing results of this script with
> output of the test below for all program types.
> But up to you if you'd like to do such rigorous verification or not.
>
> Otherwise patch-set looks good to me, for all patch-set:
>
> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
>
Hi Eduard,
I try to run your test case, but it seems btf_is_decl_tag always return
false, Are there any special restrictions for the tag feature of btf?
My compilation environment:
pahole --version
v1.29
clang --version
Ubuntu clang version 18.1.3 (1ubuntu1)
> --- 8< -----------------------------------------------------
>
> static const struct {
> const char *name;
> int code;
> } program_types[] = {
> #define _T(n) { #n, BPF_PROG_TYPE_ ## n }
> _T(KPROBE),
> _T(XDP),
> #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 (!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("%-8d ", ret);
> else if (ret == 0)
> printf("%8s ", "");
> else
> printf("%8s ", program_types[i].name);
> }
> printf("\n");
> }
> btf__free(btf);
> }
>
> ----------------------------------------------------- >8 ---
>
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-20 18:09 ` Tao Chen
@ 2025-02-20 18:43 ` Eduard Zingerman
2025-02-21 10:03 ` Tao Chen
0 siblings, 1 reply; 13+ messages in thread
From: Eduard Zingerman @ 2025-02-20 18:43 UTC (permalink / raw)
To: Tao Chen, ast, daniel, andrii, haoluo, jolsa, qmo; +Cc: bpf, linux-kernel
On Fri, 2025-02-21 at 02:09 +0800, Tao Chen wrote:
[...]
> Hi Eduard,
>
> I try to run your test case, but it seems btf_is_decl_tag always return
> false, Are there any special restrictions for the tag feature of btf?
Hi Tao,
> My compilation environment:
>
> pahole --version
> v1.29
> clang --version
> Ubuntu clang version 18.1.3 (1ubuntu1)
Hm, pahole should generate kfunc tags since 1.27.
I use pahole 'next' branch, but it is the same as 1.29 at the moment.
Do you see kfunc prototypes at the bottom of vmlinux.h?
They look like so:
...
extern u32 tcp_reno_undo_cwnd(struct sock *sk) __weak __ksym;
...
These are generated by bpftool from decl tags I look for in the test case.
Decl tags are inserted by pahole, see btf_encoder.c:btf_encoder__tag_kfuncs().
Anyways, below is the list of all kfuncs from my config,
it is possible to adapt the test case with something like this:
for (i = 0; i < ARRAY_SIZE(all_kfuncs); ++i) {
kfunc = all_kfuncs[i];
kfunc_id = btf__find_by_name_kind(vmlinux_btf, kfunc, BTF_KIND_FUNC);
printf("%-42s ", kfunc);
if (kfunc_id < 0) {
printf("<not found>\n");
continue;
}
...
}
--- 8< --------------------------------------
static const char *all_kfuncs[] = {
"bbr_cwnd_event",
"bbr_init",
"bbr_main",
"bbr_min_tso_segs",
"bbr_set_state",
"bbr_sndbuf_expand",
"bbr_ssthresh",
"bbr_undo_cwnd",
"bpf_arena_alloc_pages",
"bpf_arena_free_pages",
"bpf_cast_to_kern_ctx",
"bpf_cgroup_acquire",
"bpf_cgroup_ancestor",
"bpf_cgroup_from_id",
"bpf_cgroup_release",
"bpf_copy_from_user_str",
"bpf_cpumask_acquire",
"bpf_cpumask_and",
"bpf_cpumask_any_and_distribute",
"bpf_cpumask_any_distribute",
"bpf_cpumask_clear",
"bpf_cpumask_clear_cpu",
"bpf_cpumask_copy",
"bpf_cpumask_create",
"bpf_cpumask_empty",
"bpf_cpumask_equal",
"bpf_cpumask_first",
"bpf_cpumask_first_and",
"bpf_cpumask_first_zero",
"bpf_cpumask_full",
"bpf_cpumask_intersects",
"bpf_cpumask_or",
"bpf_cpumask_release",
"bpf_cpumask_set_cpu",
"bpf_cpumask_setall",
"bpf_cpumask_subset",
"bpf_cpumask_test_and_clear_cpu",
"bpf_cpumask_test_and_set_cpu",
"bpf_cpumask_test_cpu",
"bpf_cpumask_weight",
"bpf_cpumask_xor",
"bpf_crypto_ctx_acquire",
"bpf_crypto_ctx_create",
"bpf_crypto_ctx_release",
"bpf_crypto_decrypt",
"bpf_crypto_encrypt",
"bpf_ct_change_status",
"bpf_ct_change_timeout",
"bpf_ct_insert_entry",
"bpf_ct_release",
"bpf_ct_set_nat_info",
"bpf_ct_set_status",
"bpf_ct_set_timeout",
"bpf_dynptr_adjust",
"bpf_dynptr_clone",
"bpf_dynptr_from_skb",
"bpf_dynptr_from_xdp",
"bpf_dynptr_is_null",
"bpf_dynptr_is_rdonly",
"bpf_dynptr_size",
"bpf_dynptr_slice",
"bpf_dynptr_slice_rdwr",
"bpf_fentry_test1",
"bpf_get_dentry_xattr",
"bpf_get_file_xattr",
"bpf_get_fsverity_digest",
"bpf_get_kmem_cache",
"bpf_get_task_exe_file",
"bpf_iter_bits_destroy",
"bpf_iter_bits_new",
"bpf_iter_bits_next",
"bpf_iter_css_destroy",
"bpf_iter_css_new",
"bpf_iter_css_next",
"bpf_iter_css_task_destroy",
"bpf_iter_css_task_new",
"bpf_iter_css_task_next",
"bpf_iter_kmem_cache_destroy",
"bpf_iter_kmem_cache_new",
"bpf_iter_kmem_cache_next",
"bpf_iter_num_destroy",
"bpf_iter_num_new",
"bpf_iter_num_next",
"bpf_iter_scx_dsq_destroy",
"bpf_iter_scx_dsq_new",
"bpf_iter_scx_dsq_next",
"bpf_iter_task_destroy",
"bpf_iter_task_new",
"bpf_iter_task_next",
"bpf_iter_task_vma_destroy",
"bpf_iter_task_vma_new",
"bpf_iter_task_vma_next",
"bpf_key_put",
"bpf_kfunc_call_memb_release",
"bpf_kfunc_call_test_release",
"bpf_list_pop_back",
"bpf_list_pop_front",
"bpf_list_push_back_impl",
"bpf_list_push_front_impl",
"bpf_local_irq_restore",
"bpf_local_irq_save",
"bpf_lookup_system_key",
"bpf_lookup_user_key",
"bpf_map_sum_elem_count",
"bpf_modify_return_test",
"bpf_modify_return_test2",
"bpf_modify_return_test_tp",
"bpf_obj_drop_impl",
"bpf_obj_new_impl",
"bpf_path_d_path",
"bpf_percpu_obj_drop_impl",
"bpf_percpu_obj_new_impl",
"bpf_preempt_disable",
"bpf_preempt_enable",
"bpf_put_file",
"bpf_rbtree_add_impl",
"bpf_rbtree_first",
"bpf_rbtree_remove",
"bpf_rcu_read_lock",
"bpf_rcu_read_unlock",
"bpf_rdonly_cast",
"bpf_refcount_acquire_impl",
"bpf_remove_dentry_xattr",
"bpf_send_signal_task",
"bpf_session_cookie",
"bpf_session_is_return",
"bpf_set_dentry_xattr",
"bpf_sk_assign_tcp_reqsk",
"bpf_skb_ct_alloc",
"bpf_skb_ct_lookup",
"bpf_skb_get_fou_encap",
"bpf_skb_get_xfrm_info",
"bpf_skb_set_fou_encap",
"bpf_skb_set_xfrm_info",
"bpf_sock_addr_set_sun_path",
"bpf_sock_destroy",
"bpf_task_acquire",
"bpf_task_from_pid",
"bpf_task_from_vpid",
"bpf_task_get_cgroup1",
"bpf_task_release",
"bpf_task_under_cgroup",
"bpf_throw",
"bpf_verify_pkcs7_signature",
"bpf_wq_init",
"bpf_wq_set_callback_impl",
"bpf_wq_start",
"bpf_xdp_ct_alloc",
"bpf_xdp_ct_lookup",
"bpf_xdp_flow_lookup",
"bpf_xdp_get_xfrm_state",
"bpf_xdp_metadata_rx_hash",
"bpf_xdp_metadata_rx_timestamp",
"bpf_xdp_metadata_rx_vlan_tag",
"bpf_xdp_xfrm_state_release",
"cgroup_rstat_flush",
"cgroup_rstat_updated",
"crash_kexec",
"cubictcp_acked",
"cubictcp_cong_avoid",
"cubictcp_cwnd_event",
"cubictcp_init",
"cubictcp_recalc_ssthresh",
"cubictcp_state",
"dctcp_cwnd_event",
"dctcp_cwnd_undo",
"dctcp_init",
"dctcp_ssthresh",
"dctcp_state",
"dctcp_update_alpha",
"scx_bpf_consume",
"scx_bpf_cpu_rq",
"scx_bpf_cpuperf_cap",
"scx_bpf_cpuperf_cur",
"scx_bpf_cpuperf_set",
"scx_bpf_create_dsq",
"scx_bpf_destroy_dsq",
"scx_bpf_dispatch",
"scx_bpf_dispatch_cancel",
"scx_bpf_dispatch_from_dsq",
"scx_bpf_dispatch_from_dsq_set_slice",
"scx_bpf_dispatch_from_dsq_set_vtime",
"scx_bpf_dispatch_nr_slots",
"scx_bpf_dispatch_vtime",
"scx_bpf_dispatch_vtime_from_dsq",
"scx_bpf_dsq_insert",
"scx_bpf_dsq_insert_vtime",
"scx_bpf_dsq_move",
"scx_bpf_dsq_move_set_slice",
"scx_bpf_dsq_move_set_vtime",
"scx_bpf_dsq_move_to_local",
"scx_bpf_dsq_move_vtime",
"scx_bpf_dsq_nr_queued",
"scx_bpf_dump_bstr",
"scx_bpf_error_bstr",
"scx_bpf_exit_bstr",
"scx_bpf_get_idle_cpumask",
"scx_bpf_get_idle_smtmask",
"scx_bpf_get_online_cpumask",
"scx_bpf_get_possible_cpumask",
"scx_bpf_kick_cpu",
"scx_bpf_now",
"scx_bpf_nr_cpu_ids",
"scx_bpf_pick_any_cpu",
"scx_bpf_pick_idle_cpu",
"scx_bpf_put_cpumask",
"scx_bpf_put_idle_cpumask",
"scx_bpf_reenqueue_local",
"scx_bpf_select_cpu_dfl",
"scx_bpf_task_cgroup",
"scx_bpf_task_cpu",
"scx_bpf_task_running",
"scx_bpf_test_and_clear_cpu_idle",
"tcp_cong_avoid_ai",
"tcp_reno_cong_avoid",
"tcp_reno_ssthresh",
"tcp_reno_undo_cwnd",
"tcp_slow_start",
};
-------------------------------------- >8 ---
[...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-18 22:51 ` Eduard Zingerman
2025-02-20 18:09 ` Tao Chen
@ 2025-02-21 1:07 ` Andrii Nakryiko
2025-02-21 1:11 ` Eduard Zingerman
1 sibling, 1 reply; 13+ messages in thread
From: Andrii Nakryiko @ 2025-02-21 1:07 UTC (permalink / raw)
To: Eduard Zingerman
Cc: Tao Chen, ast, daniel, andrii, haoluo, jolsa, qmo, bpf,
linux-kernel
On Tue, Feb 18, 2025 at 2:51 PM Eduard Zingerman <eddyz87@gmail.com> wrote:
>
> On Mon, 2025-02-17 at 13:21 +0800, Tao Chen wrote:
> > 在 2025/2/12 23:39, 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:
> > > - 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 (4):
> > > 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
> > > 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 | 86 +++++++++++---
> > > .../selftests/bpf/prog_tests/libbpf_probes.c | 111 ++++++++++++++++++
> > > 4 files changed, 201 insertions(+), 16 deletions(-)
> > >
> >
> > Ping...
> >
> > Hi Andrii, Eduard,
> >
> > I've revised the previous suggestions. Please review it again. Thanks.
> >
>
> I tried the test enumerating all kfuncs in BTF and doing
> libbpf_probe_bpf_kfunc for BPF_PROG_TYPE_{KPROBE,XDP}.
> (Source code at the end of the email).
>
> The set of kfuncs returned for XDP looks correct.
> The set of kfuncs returned for KPROBE contains a few incorrect entries:
> - bpf_xdp_metadata_rx_hash
> - bpf_xdp_metadata_rx_timestamp
> - bpf_xdp_metadata_rx_vlan_tag
>
> This is because of a different string reported by verifier for these
> three functions.
>
> Ideally, I'd write some script looking for
> register_btf_kfunc_id_set(BPF_PROG_TYPE_***, kfunc_set)
> calls in the kernel source code and extracting the prog type /
> functions in the set, and comparing results of this script with
> output of the test below for all program types.
> But up to you if you'd like to do such rigorous verification or not.
>
> Otherwise patch-set looks good to me, for all patch-set:
>
> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
Shouldn't we fix the issue with those bpf_xdp_metadata_* kfuncs? Do
you have details on what different string verifier reports?
>
> --- 8< -----------------------------------------------------
>
> static const struct {
> const char *name;
> int code;
> } program_types[] = {
> #define _T(n) { #n, BPF_PROG_TYPE_ ## n }
> _T(KPROBE),
> _T(XDP),
> #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 (!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("%-8d ", ret);
> else if (ret == 0)
> printf("%8s ", "");
> else
> printf("%8s ", program_types[i].name);
> }
> printf("\n");
> }
> btf__free(btf);
> }
>
> ----------------------------------------------------- >8 ---
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-21 1:07 ` Andrii Nakryiko
@ 2025-02-21 1:11 ` Eduard Zingerman
2025-02-21 10:03 ` Tao Chen
0 siblings, 1 reply; 13+ messages in thread
From: Eduard Zingerman @ 2025-02-21 1:11 UTC (permalink / raw)
To: Andrii Nakryiko
Cc: Tao Chen, ast, daniel, andrii, haoluo, jolsa, qmo, bpf,
linux-kernel
On Thu, 2025-02-20 at 17:07 -0800, Andrii Nakryiko wrote:
> On Tue, Feb 18, 2025 at 2:51 PM Eduard Zingerman <eddyz87@gmail.com> wrote:
> >
> > On Mon, 2025-02-17 at 13:21 +0800, Tao Chen wrote:
[...]
> > I tried the test enumerating all kfuncs in BTF and doing
> > libbpf_probe_bpf_kfunc for BPF_PROG_TYPE_{KPROBE,XDP}.
> > (Source code at the end of the email).
> >
> > The set of kfuncs returned for XDP looks correct.
> > The set of kfuncs returned for KPROBE contains a few incorrect entries:
> > - bpf_xdp_metadata_rx_hash
> > - bpf_xdp_metadata_rx_timestamp
> > - bpf_xdp_metadata_rx_vlan_tag
> >
> > This is because of a different string reported by verifier for these
> > three functions.
> >
> > Ideally, I'd write some script looking for
> > register_btf_kfunc_id_set(BPF_PROG_TYPE_***, kfunc_set)
> > calls in the kernel source code and extracting the prog type /
> > functions in the set, and comparing results of this script with
> > output of the test below for all program types.
> > But up to you if you'd like to do such rigorous verification or not.
> >
> > Otherwise patch-set looks good to me, for all patch-set:
> >
> > Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
>
> Shouldn't we fix the issue with those bpf_xdp_metadata_* kfuncs? Do
I assume Tao would post a v8 with the fix.
> you have details on what different string verifier reports?
The string is "metadata kfuncs require device-bound program\n".
[...]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-20 18:43 ` Eduard Zingerman
@ 2025-02-21 10:03 ` Tao Chen
0 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-21 10:03 UTC (permalink / raw)
To: Eduard Zingerman, ast, daniel, andrii, haoluo, jolsa, qmo
Cc: bpf, linux-kernel
在 2025/2/21 02:43, Eduard Zingerman 写道:
> On Fri, 2025-02-21 at 02:09 +0800, Tao Chen wrote:
>
> [...]
>
>> Hi Eduard,
>>
>> I try to run your test case, but it seems btf_is_decl_tag always return
>> false, Are there any special restrictions for the tag feature of btf?
>
> Hi Tao,
>
>> My compilation environment:
>>
>> pahole --version
>> v1.29
>> clang --version
>> Ubuntu clang version 18.1.3 (1ubuntu1)
>
> Hm, pahole should generate kfunc tags since 1.27.
> I use pahole 'next' branch, but it is the same as 1.29 at the moment.
> Do you see kfunc prototypes at the bottom of vmlinux.h?
> They look like so:
>
> ...
> extern u32 tcp_reno_undo_cwnd(struct sock *sk) __weak __ksym;
> ...
>
> These are generated by bpftool from decl tags I look for in the test case.
> Decl tags are inserted by pahole, see btf_encoder.c:btf_encoder__tag_kfuncs().
>
It's all right now, when i use make
PAHOLE=/home/dylane/sdb/dwarves/build/pahole -j4, thanks.
> Anyways, below is the list of all kfuncs from my config,
> it is possible to adapt the test case with something like this:
>
> for (i = 0; i < ARRAY_SIZE(all_kfuncs); ++i) {
> kfunc = all_kfuncs[i];
> kfunc_id = btf__find_by_name_kind(vmlinux_btf, kfunc, BTF_KIND_FUNC);
> printf("%-42s ", kfunc);
> if (kfunc_id < 0) {
> printf("<not found>\n");
> continue;
> }
> ...
> }
>
Well, i try it.
> --- 8< --------------------------------------
>
> static const char *all_kfuncs[] = {
> "bbr_cwnd_event",
> "bbr_init",
> "bbr_main",
> "bbr_min_tso_segs",
> "bbr_set_state",
> "bbr_sndbuf_expand",
> "bbr_ssthresh",
> "bbr_undo_cwnd",
> "bpf_arena_alloc_pages",
> "bpf_arena_free_pages",
> "bpf_cast_to_kern_ctx",
> "bpf_cgroup_acquire",
> "bpf_cgroup_ancestor",
> "bpf_cgroup_from_id",
> "bpf_cgroup_release",
> "bpf_copy_from_user_str",
> "bpf_cpumask_acquire",
> "bpf_cpumask_and",
> "bpf_cpumask_any_and_distribute",
> "bpf_cpumask_any_distribute",
> "bpf_cpumask_clear",
> "bpf_cpumask_clear_cpu",
> "bpf_cpumask_copy",
> "bpf_cpumask_create",
> "bpf_cpumask_empty",
> "bpf_cpumask_equal",
> "bpf_cpumask_first",
> "bpf_cpumask_first_and",
> "bpf_cpumask_first_zero",
> "bpf_cpumask_full",
> "bpf_cpumask_intersects",
> "bpf_cpumask_or",
> "bpf_cpumask_release",
> "bpf_cpumask_set_cpu",
> "bpf_cpumask_setall",
> "bpf_cpumask_subset",
> "bpf_cpumask_test_and_clear_cpu",
> "bpf_cpumask_test_and_set_cpu",
> "bpf_cpumask_test_cpu",
> "bpf_cpumask_weight",
> "bpf_cpumask_xor",
> "bpf_crypto_ctx_acquire",
> "bpf_crypto_ctx_create",
> "bpf_crypto_ctx_release",
> "bpf_crypto_decrypt",
> "bpf_crypto_encrypt",
> "bpf_ct_change_status",
> "bpf_ct_change_timeout",
> "bpf_ct_insert_entry",
> "bpf_ct_release",
> "bpf_ct_set_nat_info",
> "bpf_ct_set_status",
> "bpf_ct_set_timeout",
> "bpf_dynptr_adjust",
> "bpf_dynptr_clone",
> "bpf_dynptr_from_skb",
> "bpf_dynptr_from_xdp",
> "bpf_dynptr_is_null",
> "bpf_dynptr_is_rdonly",
> "bpf_dynptr_size",
> "bpf_dynptr_slice",
> "bpf_dynptr_slice_rdwr",
> "bpf_fentry_test1",
> "bpf_get_dentry_xattr",
> "bpf_get_file_xattr",
> "bpf_get_fsverity_digest",
> "bpf_get_kmem_cache",
> "bpf_get_task_exe_file",
> "bpf_iter_bits_destroy",
> "bpf_iter_bits_new",
> "bpf_iter_bits_next",
> "bpf_iter_css_destroy",
> "bpf_iter_css_new",
> "bpf_iter_css_next",
> "bpf_iter_css_task_destroy",
> "bpf_iter_css_task_new",
> "bpf_iter_css_task_next",
> "bpf_iter_kmem_cache_destroy",
> "bpf_iter_kmem_cache_new",
> "bpf_iter_kmem_cache_next",
> "bpf_iter_num_destroy",
> "bpf_iter_num_new",
> "bpf_iter_num_next",
> "bpf_iter_scx_dsq_destroy",
> "bpf_iter_scx_dsq_new",
> "bpf_iter_scx_dsq_next",
> "bpf_iter_task_destroy",
> "bpf_iter_task_new",
> "bpf_iter_task_next",
> "bpf_iter_task_vma_destroy",
> "bpf_iter_task_vma_new",
> "bpf_iter_task_vma_next",
> "bpf_key_put",
> "bpf_kfunc_call_memb_release",
> "bpf_kfunc_call_test_release",
> "bpf_list_pop_back",
> "bpf_list_pop_front",
> "bpf_list_push_back_impl",
> "bpf_list_push_front_impl",
> "bpf_local_irq_restore",
> "bpf_local_irq_save",
> "bpf_lookup_system_key",
> "bpf_lookup_user_key",
> "bpf_map_sum_elem_count",
> "bpf_modify_return_test",
> "bpf_modify_return_test2",
> "bpf_modify_return_test_tp",
> "bpf_obj_drop_impl",
> "bpf_obj_new_impl",
> "bpf_path_d_path",
> "bpf_percpu_obj_drop_impl",
> "bpf_percpu_obj_new_impl",
> "bpf_preempt_disable",
> "bpf_preempt_enable",
> "bpf_put_file",
> "bpf_rbtree_add_impl",
> "bpf_rbtree_first",
> "bpf_rbtree_remove",
> "bpf_rcu_read_lock",
> "bpf_rcu_read_unlock",
> "bpf_rdonly_cast",
> "bpf_refcount_acquire_impl",
> "bpf_remove_dentry_xattr",
> "bpf_send_signal_task",
> "bpf_session_cookie",
> "bpf_session_is_return",
> "bpf_set_dentry_xattr",
> "bpf_sk_assign_tcp_reqsk",
> "bpf_skb_ct_alloc",
> "bpf_skb_ct_lookup",
> "bpf_skb_get_fou_encap",
> "bpf_skb_get_xfrm_info",
> "bpf_skb_set_fou_encap",
> "bpf_skb_set_xfrm_info",
> "bpf_sock_addr_set_sun_path",
> "bpf_sock_destroy",
> "bpf_task_acquire",
> "bpf_task_from_pid",
> "bpf_task_from_vpid",
> "bpf_task_get_cgroup1",
> "bpf_task_release",
> "bpf_task_under_cgroup",
> "bpf_throw",
> "bpf_verify_pkcs7_signature",
> "bpf_wq_init",
> "bpf_wq_set_callback_impl",
> "bpf_wq_start",
> "bpf_xdp_ct_alloc",
> "bpf_xdp_ct_lookup",
> "bpf_xdp_flow_lookup",
> "bpf_xdp_get_xfrm_state",
> "bpf_xdp_metadata_rx_hash",
> "bpf_xdp_metadata_rx_timestamp",
> "bpf_xdp_metadata_rx_vlan_tag",
> "bpf_xdp_xfrm_state_release",
> "cgroup_rstat_flush",
> "cgroup_rstat_updated",
> "crash_kexec",
> "cubictcp_acked",
> "cubictcp_cong_avoid",
> "cubictcp_cwnd_event",
> "cubictcp_init",
> "cubictcp_recalc_ssthresh",
> "cubictcp_state",
> "dctcp_cwnd_event",
> "dctcp_cwnd_undo",
> "dctcp_init",
> "dctcp_ssthresh",
> "dctcp_state",
> "dctcp_update_alpha",
> "scx_bpf_consume",
> "scx_bpf_cpu_rq",
> "scx_bpf_cpuperf_cap",
> "scx_bpf_cpuperf_cur",
> "scx_bpf_cpuperf_set",
> "scx_bpf_create_dsq",
> "scx_bpf_destroy_dsq",
> "scx_bpf_dispatch",
> "scx_bpf_dispatch_cancel",
> "scx_bpf_dispatch_from_dsq",
> "scx_bpf_dispatch_from_dsq_set_slice",
> "scx_bpf_dispatch_from_dsq_set_vtime",
> "scx_bpf_dispatch_nr_slots",
> "scx_bpf_dispatch_vtime",
> "scx_bpf_dispatch_vtime_from_dsq",
> "scx_bpf_dsq_insert",
> "scx_bpf_dsq_insert_vtime",
> "scx_bpf_dsq_move",
> "scx_bpf_dsq_move_set_slice",
> "scx_bpf_dsq_move_set_vtime",
> "scx_bpf_dsq_move_to_local",
> "scx_bpf_dsq_move_vtime",
> "scx_bpf_dsq_nr_queued",
> "scx_bpf_dump_bstr",
> "scx_bpf_error_bstr",
> "scx_bpf_exit_bstr",
> "scx_bpf_get_idle_cpumask",
> "scx_bpf_get_idle_smtmask",
> "scx_bpf_get_online_cpumask",
> "scx_bpf_get_possible_cpumask",
> "scx_bpf_kick_cpu",
> "scx_bpf_now",
> "scx_bpf_nr_cpu_ids",
> "scx_bpf_pick_any_cpu",
> "scx_bpf_pick_idle_cpu",
> "scx_bpf_put_cpumask",
> "scx_bpf_put_idle_cpumask",
> "scx_bpf_reenqueue_local",
> "scx_bpf_select_cpu_dfl",
> "scx_bpf_task_cgroup",
> "scx_bpf_task_cpu",
> "scx_bpf_task_running",
> "scx_bpf_test_and_clear_cpu_idle",
> "tcp_cong_avoid_ai",
> "tcp_reno_cong_avoid",
> "tcp_reno_ssthresh",
> "tcp_reno_undo_cwnd",
> "tcp_slow_start",
> };
>
> -------------------------------------- >8 ---
>
> [...]
>
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe
2025-02-21 1:11 ` Eduard Zingerman
@ 2025-02-21 10:03 ` Tao Chen
0 siblings, 0 replies; 13+ messages in thread
From: Tao Chen @ 2025-02-21 10:03 UTC (permalink / raw)
To: Eduard Zingerman, Andrii Nakryiko
Cc: ast, daniel, andrii, haoluo, jolsa, qmo, bpf, linux-kernel
在 2025/2/21 09:11, Eduard Zingerman 写道:
> On Thu, 2025-02-20 at 17:07 -0800, Andrii Nakryiko wrote:
>> On Tue, Feb 18, 2025 at 2:51 PM Eduard Zingerman <eddyz87@gmail.com> wrote:
>>>
>>> On Mon, 2025-02-17 at 13:21 +0800, Tao Chen wrote:
>
> [...]
>
>>> I tried the test enumerating all kfuncs in BTF and doing
>>> libbpf_probe_bpf_kfunc for BPF_PROG_TYPE_{KPROBE,XDP}.
>>> (Source code at the end of the email).
>>>
>>> The set of kfuncs returned for XDP looks correct.
>>> The set of kfuncs returned for KPROBE contains a few incorrect entries:
>>> - bpf_xdp_metadata_rx_hash
>>> - bpf_xdp_metadata_rx_timestamp
>>> - bpf_xdp_metadata_rx_vlan_tag
>>>
>>> This is because of a different string reported by verifier for these
>>> three functions.
>>>
>>> Ideally, I'd write some script looking for
>>> register_btf_kfunc_id_set(BPF_PROG_TYPE_***, kfunc_set)
>>> calls in the kernel source code and extracting the prog type /
>>> functions in the set, and comparing results of this script with
>>> output of the test below for all program types.
>>> But up to you if you'd like to do such rigorous verification or not.
>>>
>>> Otherwise patch-set looks good to me, for all patch-set:
>>>
>>> Reviewed-by: Eduard Zingerman <eddyz87@gmail.com>
>>
>> Shouldn't we fix the issue with those bpf_xdp_metadata_* kfuncs? Do
>
> I assume Tao would post a v8 with the fix.
>
Sure, will fix it.
>> you have details on what different string verifier reports?
>
> The string is "metadata kfuncs require device-bound program\n".
>
> [...]
>
--
Best Regards
Tao Chen
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2025-02-21 10:03 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-02-12 15:39 [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 2/4] libbpf: Init fd_array when prog probe load Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
2025-02-12 15:39 ` [PATCH bpf-next v7 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
2025-02-17 5:21 ` [PATCH RESEND bpf-next v7 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-18 22:51 ` Eduard Zingerman
2025-02-20 18:09 ` Tao Chen
2025-02-20 18:43 ` Eduard Zingerman
2025-02-21 10:03 ` Tao Chen
2025-02-21 1:07 ` Andrii Nakryiko
2025-02-21 1:11 ` Eduard Zingerman
2025-02-21 10:03 ` Tao Chen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox