* [PATCH bpf-next v5 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper
2025-02-10 5:59 [PATCH bpf-next v5 0/4] Add prog_kfunc feature probe Tao Chen
@ 2025-02-10 5:59 ` Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 2/4] libbpf: Init fd_array when prog probe load Tao Chen
` (2 subsequent siblings)
3 siblings, 0 replies; 9+ messages in thread
From: Tao Chen @ 2025-02-10 5:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
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}.
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
tools/lib/bpf/libbpf_probes.c | 29 ++++++++++++++++++-----------
1 file changed, 18 insertions(+), 11 deletions(-)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index 9dfbe7750f56..aeb4fd97d801 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:
+ if (!can_probe_prog_type(prog_type))
return -EOPNOTSUPP;
- default:
- break;
- }
buf[0] = '\0';
ret = probe_prog_load(prog_type, insns, insn_cnt, buf, sizeof(buf));
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bpf-next v5 2/4] libbpf: Init fd_array when prog probe load
2025-02-10 5:59 [PATCH bpf-next v5 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
@ 2025-02-10 5:59 ` Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
3 siblings, 0 replies; 9+ messages in thread
From: Tao Chen @ 2025-02-10 5:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
fd_array used to store module btf fd, which will
be used for kfunc probe in module btf.
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
tools/lib/bpf/libbpf_probes.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
index aeb4fd97d801..e142130cb83c 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -102,12 +102,15 @@ __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,
+ int *fd_array, size_t fd_array_cnt,
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,
+ .fd_array_cnt = fd_array_cnt,
);
int fd, err, exp_err = 0;
const char *exp_msg = NULL;
@@ -214,7 +217,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, 0, NULL, 0);
return libbpf_err(ret);
}
@@ -448,7 +451,7 @@ int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helpe
return -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, 0, buf, sizeof(buf));
if (ret < 0)
return libbpf_err(ret);
--
2.43.0
^ permalink raw reply related [flat|nested] 9+ messages in thread* [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-10 5:59 [PATCH bpf-next v5 0/4] Add prog_kfunc feature probe Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 1/4] libbpf: Extract prog load type check from libbpf_probe_bpf_helper Tao Chen
2025-02-10 5:59 ` [PATCH bpf-next v5 2/4] libbpf: Init fd_array when prog probe load Tao Chen
@ 2025-02-10 5:59 ` Tao Chen
2025-02-10 13:47 ` Jiri Olsa
2025-02-10 5:59 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
3 siblings, 1 reply; 9+ messages in thread
From: Tao Chen @ 2025-02-10 5:59 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>
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..e796e38cf255 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 -1 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 e142130cb83c..53f1196394bf 100644
--- a/tools/lib/bpf/libbpf_probes.c
+++ b/tools/lib/bpf/libbpf_probes.c
@@ -433,6 +433,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 -EOPNOTSUPP;
+
+ if (btf_fd >= 0) {
+ fd_array[1] = btf_fd;
+ } else if (btf_fd == -1) {
+ /* insn.off = 0, means vmlinux btf */
+ insns[0].off = 0;
+ } else {
+ return libbpf_err(-EINVAL);
+ }
+
+ buf[0] = '\0';
+ ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
+ 0, buf, sizeof(buf));
+ if (ret < 0)
+ return libbpf_err(ret);
+
+ /* If BPF verifier recognizes BPF kfunc but it's not supported for
+ * given BPF program type, it will emit "calling kernel function
+ * bpf_cpumask_create is not allowed", if the kfunc id is invalid,
+ * it will emit "kernel btf_id 4294967295 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 (ret == 0 && (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
+ (strstr(buf, "invalid module BTF fd")) ||
+ (strstr(buf, "negative offset disallowed"))))
+ return 0;
+
+ return 1; /* assume supported */
+}
+
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] 9+ messages in thread* Re: [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-10 5:59 ` [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
@ 2025-02-10 13:47 ` Jiri Olsa
2025-02-10 15:19 ` Tao Chen
0 siblings, 1 reply; 9+ messages in thread
From: Jiri Olsa @ 2025-02-10 13:47 UTC (permalink / raw)
To: Tao Chen
Cc: ast, daniel, andrii, eddyz87, haoluo, qmo, bpf, linux-kernel,
Tao Chen
On Mon, Feb 10, 2025 at 01:59:44PM +0800, Tao Chen wrote:
SNIP
> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
> index e142130cb83c..53f1196394bf 100644
> --- a/tools/lib/bpf/libbpf_probes.c
> +++ b/tools/lib/bpf/libbpf_probes.c
> @@ -433,6 +433,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 -EOPNOTSUPP;
> +
> + if (btf_fd >= 0) {
> + fd_array[1] = btf_fd;
> + } else if (btf_fd == -1) {
> + /* insn.off = 0, means vmlinux btf */
> + insns[0].off = 0;
> + } else {
> + return libbpf_err(-EINVAL);
> + }
> +
> + buf[0] = '\0';
> + ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
> + 0, buf, sizeof(buf));
hum, you pass fd_array_cnt as 0, which IIUC will work properly
but I guess then we don't need to have fd_array_cnt argument in
probe_prog_load if all callers pass 0 ?
jirka
> + if (ret < 0)
> + return libbpf_err(ret);
> +
> + /* If BPF verifier recognizes BPF kfunc but it's not supported for
> + * given BPF program type, it will emit "calling kernel function
> + * bpf_cpumask_create is not allowed", if the kfunc id is invalid,
> + * it will emit "kernel btf_id 4294967295 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 (ret == 0 && (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
> + (strstr(buf, "invalid module BTF fd")) ||
> + (strstr(buf, "negative offset disallowed"))))
> + return 0;
> +
> + return 1; /* assume supported */
> +}
> +
> 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] 9+ messages in thread* Re: [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API
2025-02-10 13:47 ` Jiri Olsa
@ 2025-02-10 15:19 ` Tao Chen
0 siblings, 0 replies; 9+ messages in thread
From: Tao Chen @ 2025-02-10 15:19 UTC (permalink / raw)
To: Jiri Olsa
Cc: ast, daniel, andrii, eddyz87, haoluo, qmo, bpf, linux-kernel,
Tao Chen
在 2025/2/10 21:47, Jiri Olsa 写道:
> On Mon, Feb 10, 2025 at 01:59:44PM +0800, Tao Chen wrote:
>
> SNIP
>
>> diff --git a/tools/lib/bpf/libbpf_probes.c b/tools/lib/bpf/libbpf_probes.c
>> index e142130cb83c..53f1196394bf 100644
>> --- a/tools/lib/bpf/libbpf_probes.c
>> +++ b/tools/lib/bpf/libbpf_probes.c
>> @@ -433,6 +433,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 -EOPNOTSUPP;
>> +
>> + if (btf_fd >= 0) {
>> + fd_array[1] = btf_fd;
>> + } else if (btf_fd == -1) {
>> + /* insn.off = 0, means vmlinux btf */
>> + insns[0].off = 0;
>> + } else {
>> + return libbpf_err(-EINVAL);
>> + }
>> +
>> + buf[0] = '\0';
>> + ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
>> + 0, buf, sizeof(buf));
>
> hum, you pass fd_array_cnt as 0, which IIUC will work properly
>
> but I guess then we don't need to have fd_array_cnt argument in
> probe_prog_load if all callers pass 0 ?
>
> jirka
>
Hi, jiri
In fact, 0 is indeed used everywhere here. I was just thinking about
whether we might need it in the future. Anyway, it seems better to
remove it. I'll make the modifications in the next version.
>> + if (ret < 0)
>> + return libbpf_err(ret);
>> +
>> + /* If BPF verifier recognizes BPF kfunc but it's not supported for
>> + * given BPF program type, it will emit "calling kernel function
>> + * bpf_cpumask_create is not allowed", if the kfunc id is invalid,
>> + * it will emit "kernel btf_id 4294967295 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 (ret == 0 && (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
>> + (strstr(buf, "invalid module BTF fd")) ||
>> + (strstr(buf, "negative offset disallowed"))))
>> + return 0;
>> +
>> + return 1; /* assume supported */
>> +}
>> +
>> int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
>> const void *opts)
>> {
>> --
>> 2.43.0
>>
--
Best Regards
Dylane Chen
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
2025-02-10 5:59 [PATCH bpf-next v5 0/4] Add prog_kfunc feature probe Tao Chen
` (2 preceding siblings ...)
2025-02-10 5:59 ` [PATCH bpf-next v5 3/4] libbpf: Add libbpf_probe_bpf_kfunc API Tao Chen
@ 2025-02-10 5:59 ` Tao Chen
2025-02-10 13:47 ` Jiri Olsa
3 siblings, 1 reply; 9+ messages in thread
From: Tao Chen @ 2025-02-10 5:59 UTC (permalink / raw)
To: ast, daniel, andrii, eddyz87, haoluo, jolsa, qmo
Cc: bpf, linux-kernel, chen.dylane
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
Signed-off-by: Tao Chen <chen.dylane@gmail.com>
---
.../selftests/bpf/prog_tests/libbpf_probes.c | 118 ++++++++++++++++++
1 file changed, 118 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..fc4c9dc2cbed 100644
--- a/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
+++ b/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
@@ -126,3 +126,121 @@ 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 && (errno == ENOENT || errno == EPERM))
+ return 0;
+ if (err) {
+ err = -errno;
+ return err;
+ }
+ fd = bpf_btf_get_fd_by_id(id);
+ if (fd < 0) {
+ if (errno == ENOENT)
+ continue;
+ err = -errno;
+ return err;
+ }
+ 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) {
+ err = -errno;
+ goto err_out;
+ }
+ /* find target module btf */
+ if (!strcmp(name, module))
+ break;
+
+ close(fd);
+ }
+
+ return fd;
+err_out:
+ close(fd);
+ return err;
+}
+
+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_GT(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] 9+ messages in thread* Re: [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
2025-02-10 5:59 ` [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests Tao Chen
@ 2025-02-10 13:47 ` Jiri Olsa
2025-02-10 15:11 ` Tao Chen
0 siblings, 1 reply; 9+ messages in thread
From: Jiri Olsa @ 2025-02-10 13:47 UTC (permalink / raw)
To: Tao Chen; +Cc: ast, daniel, andrii, eddyz87, haoluo, qmo, bpf, linux-kernel
On Mon, Feb 10, 2025 at 01:59:45PM +0800, Tao Chen wrote:
> 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
>
> Signed-off-by: Tao Chen <chen.dylane@gmail.com>
> ---
> .../selftests/bpf/prog_tests/libbpf_probes.c | 118 ++++++++++++++++++
> 1 file changed, 118 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..fc4c9dc2cbed 100644
> --- a/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
> +++ b/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
> @@ -126,3 +126,121 @@ 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 && (errno == ENOENT || errno == EPERM))
> + return 0;
> + if (err) {
> + err = -errno;
> + return err;
> + }
> + fd = bpf_btf_get_fd_by_id(id);
> + if (fd < 0) {
> + if (errno == ENOENT)
> + continue;
> + err = -errno;
> + return err;
nit, return -errno ?
jirka
> + }
> + 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) {
> + err = -errno;
> + goto err_out;
> + }
> + /* find target module btf */
> + if (!strcmp(name, module))
> + break;
> +
> + close(fd);
> + }
> +
> + return fd;
> +err_out:
> + close(fd);
> + return err;
> +}
SNIP
^ permalink raw reply [flat|nested] 9+ messages in thread* Re: [PATCH bpf-next v5 4/4] selftests/bpf: Add libbpf_probe_bpf_kfunc API selftests
2025-02-10 13:47 ` Jiri Olsa
@ 2025-02-10 15:11 ` Tao Chen
0 siblings, 0 replies; 9+ messages in thread
From: Tao Chen @ 2025-02-10 15:11 UTC (permalink / raw)
To: Jiri Olsa; +Cc: ast, daniel, andrii, eddyz87, haoluo, qmo, bpf, linux-kernel
在 2025/2/10 21:47, Jiri Olsa 写道:
> On Mon, Feb 10, 2025 at 01:59:45PM +0800, Tao Chen wrote:
>> 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
>>
>> Signed-off-by: Tao Chen <chen.dylane@gmail.com>
>> ---
>> .../selftests/bpf/prog_tests/libbpf_probes.c | 118 ++++++++++++++++++
>> 1 file changed, 118 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..fc4c9dc2cbed 100644
>> --- a/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
>> +++ b/tools/testing/selftests/bpf/prog_tests/libbpf_probes.c
>> @@ -126,3 +126,121 @@ 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 && (errno == ENOENT || errno == EPERM))
>> + return 0;
>> + if (err) {
>> + err = -errno;
>> + return err;
>> + }
>> + fd = bpf_btf_get_fd_by_id(id);
>> + if (fd < 0) {
>> + if (errno == ENOENT)
>> + continue;
>> + err = -errno;
>> + return err;
>
> nit, return -errno ?
>
> jirka
>
Ack.
>> + }
>> + 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) {
>> + err = -errno;
>> + goto err_out;
>> + }
>> + /* find target module btf */
>> + if (!strcmp(name, module))
>> + break;
>> +
>> + close(fd);
>> + }
>> +
>> + return fd;
>> +err_out:
>> + close(fd);
>> + return err;
>> +}
>
> SNIP
--
Best Regards
Dylane Chen
^ permalink raw reply [flat|nested] 9+ messages in thread