* [PATCH bpf-next v4 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
@ 2026-01-20 7:30 Menglong Dong
2026-01-20 7:30 ` [PATCH bpf-next v4 1/2] " Menglong Dong
2026-01-20 7:30 ` [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
0 siblings, 2 replies; 7+ messages in thread
From: Menglong Dong @ 2026-01-20 7:30 UTC (permalink / raw)
To: ast, andrii, yonghong.song
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
Support bpf_get_func_arg() for BPF_TRACE_RAW_TP by getting the function
argument count from "prog->aux->attach_func_proto" during verifier inline.
Changes v4 -> v3:
* fix the error of using bpf_get_func_arg() for BPF_TRACE_ITER
* https://lore.kernel.org/bpf/20260119023732.130642-1-dongml2@chinatelecom.cn/
Changes v3 -> v2:
* remove unnecessary NULL checking for prog->aux->attach_func_proto
* v2: https://lore.kernel.org/bpf/20260116071739.121182-1-dongml2@chinatelecom.cn/
Changes v2 -> v1:
* for nr_args, skip first 'void *__data' argument in btf_trace_##name
typedef
* check the result4 and result5 in the selftests
* v1: https://lore.kernel.org/bpf/20260116035024.98214-1-dongml2@chinatelecom.cn/
Menglong Dong (2):
bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
selftests/bpf: test bpf_get_func_arg() for tp_btf
kernel/bpf/verifier.c | 32 ++++++++++++--
kernel/trace/bpf_trace.c | 4 ++
.../bpf/prog_tests/get_func_args_test.c | 3 ++
.../selftests/bpf/progs/get_func_args_test.c | 44 +++++++++++++++++++
.../bpf/test_kmods/bpf_testmod-events.h | 10 +++++
.../selftests/bpf/test_kmods/bpf_testmod.c | 4 ++
6 files changed, 93 insertions(+), 4 deletions(-)
--
2.52.0
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf-next v4 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-20 7:30 [PATCH bpf-next v4 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
@ 2026-01-20 7:30 ` Menglong Dong
2026-01-20 22:49 ` Yonghong Song
2026-01-21 0:38 ` Andrii Nakryiko
2026-01-20 7:30 ` [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
1 sibling, 2 replies; 7+ messages in thread
From: Menglong Dong @ 2026-01-20 7:30 UTC (permalink / raw)
To: ast, andrii, yonghong.song
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
tracepoint, especially for the case that the position of the arguments in
a tracepoint can change.
The target tracepoint BTF type id is specified during loading time,
therefore we can get the function argument count from the function
prototype instead of the stack.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
v4:
- fix the error of using bpf_get_func_arg() for BPF_TRACE_ITER
v3:
- remove unnecessary NULL checking for prog->aux->attach_func_proto
v2:
- for nr_args, skip first 'void *__data' argument in btf_trace_##name
typedef
---
kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
kernel/trace/bpf_trace.c | 4 ++++
2 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9de0ec0c3ed9..0b281b7c41eb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -23323,8 +23323,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
/* Implement bpf_get_func_arg inline. */
if (prog_type == BPF_PROG_TYPE_TRACING &&
insn->imm == BPF_FUNC_get_func_arg) {
- /* Load nr_args from ctx - 8 */
- insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+ if (eatype == BPF_TRACE_RAW_TP) {
+ int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+ /*
+ * skip first 'void *__data' argument in btf_trace_##name
+ * typedef
+ */
+ nr_args--;
+ /* Save nr_args to reg0 */
+ insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+ } else {
+ /* Load nr_args from ctx - 8 */
+ insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+ }
insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
@@ -23376,8 +23388,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
/* Implement get_func_arg_cnt inline. */
if (prog_type == BPF_PROG_TYPE_TRACING &&
insn->imm == BPF_FUNC_get_func_arg_cnt) {
- /* Load nr_args from ctx - 8 */
- insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+ if (eatype == BPF_TRACE_RAW_TP) {
+ int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
+
+ /*
+ * skip first 'void *__data' argument in btf_trace_##name
+ * typedef
+ */
+ nr_args--;
+ /* Save nr_args to reg0 */
+ insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
+ } else {
+ /* Load nr_args from ctx - 8 */
+ insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
+ }
new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
if (!new_prog)
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index f73e08c223b5..0efdad3adcce 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -1734,10 +1734,14 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
case BPF_FUNC_d_path:
return &bpf_d_path_proto;
case BPF_FUNC_get_func_arg:
+ if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
+ return &bpf_get_func_arg_proto;
return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
case BPF_FUNC_get_func_ret:
return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
case BPF_FUNC_get_func_arg_cnt:
+ if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
+ return &bpf_get_func_arg_cnt_proto;
return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
case BPF_FUNC_get_attach_cookie:
if (prog->type == BPF_PROG_TYPE_TRACING &&
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf
2026-01-20 7:30 [PATCH bpf-next v4 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
2026-01-20 7:30 ` [PATCH bpf-next v4 1/2] " Menglong Dong
@ 2026-01-20 7:30 ` Menglong Dong
2026-01-20 22:52 ` Yonghong Song
1 sibling, 1 reply; 7+ messages in thread
From: Menglong Dong @ 2026-01-20 7:30 UTC (permalink / raw)
To: ast, andrii, yonghong.song
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
Test bpf_get_func_arg() and bpf_get_func_arg_cnt() for tp_btf. The code
is most copied from test1 and test2.
Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
---
.../bpf/prog_tests/get_func_args_test.c | 3 ++
.../selftests/bpf/progs/get_func_args_test.c | 44 +++++++++++++++++++
.../bpf/test_kmods/bpf_testmod-events.h | 10 +++++
.../selftests/bpf/test_kmods/bpf_testmod.c | 4 ++
4 files changed, 61 insertions(+)
diff --git a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
index 64a9c95d4acf..fadee95d3ae8 100644
--- a/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/prog_tests/get_func_args_test.c
@@ -33,11 +33,14 @@ void test_get_func_args_test(void)
ASSERT_EQ(topts.retval >> 16, 1, "test_run");
ASSERT_EQ(topts.retval & 0xffff, 1234 + 29, "test_run");
+ ASSERT_OK(trigger_module_test_read(1), "trigger_read");
ASSERT_EQ(skel->bss->test1_result, 1, "test1_result");
ASSERT_EQ(skel->bss->test2_result, 1, "test2_result");
ASSERT_EQ(skel->bss->test3_result, 1, "test3_result");
ASSERT_EQ(skel->bss->test4_result, 1, "test4_result");
+ ASSERT_EQ(skel->bss->test5_result, 1, "test5_result");
+ ASSERT_EQ(skel->bss->test6_result, 1, "test6_result");
cleanup:
get_func_args_test__destroy(skel);
diff --git a/tools/testing/selftests/bpf/progs/get_func_args_test.c b/tools/testing/selftests/bpf/progs/get_func_args_test.c
index e0f34a55e697..5b7233afef05 100644
--- a/tools/testing/selftests/bpf/progs/get_func_args_test.c
+++ b/tools/testing/selftests/bpf/progs/get_func_args_test.c
@@ -121,3 +121,47 @@ int BPF_PROG(fexit_test, int _a, int *_b, int _ret)
test4_result &= err == 0 && ret == 1234;
return 0;
}
+
+__u64 test5_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test1_tp")
+int BPF_PROG(tp_test1)
+{
+ __u64 cnt = bpf_get_func_arg_cnt(ctx);
+ __u64 a = 0, z = 0;
+ __s64 err;
+
+ test5_result = cnt == 1;
+
+ err = bpf_get_func_arg(ctx, 0, &a);
+ test5_result &= err == 0 && ((int) a == 1);
+
+ /* not valid argument */
+ err = bpf_get_func_arg(ctx, 1, &z);
+ test5_result &= err == -EINVAL;
+
+ return 0;
+}
+
+__u64 test6_result = 0;
+SEC("tp_btf/bpf_testmod_fentry_test2_tp")
+int BPF_PROG(tp_test2)
+{
+ __u64 cnt = bpf_get_func_arg_cnt(ctx);
+ __u64 a = 0, b = 0, z = 0;
+ __s64 err;
+
+ test6_result = cnt == 2;
+
+ /* valid arguments */
+ err = bpf_get_func_arg(ctx, 0, &a);
+ test6_result &= err == 0 && (int) a == 2;
+
+ err = bpf_get_func_arg(ctx, 1, &b);
+ test6_result &= err == 0 && b == 3;
+
+ /* not valid argument */
+ err = bpf_get_func_arg(ctx, 2, &z);
+ test6_result &= err == -EINVAL;
+
+ return 0;
+}
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
index aeef86b3da74..45a5e41f3a92 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod-events.h
@@ -63,6 +63,16 @@ BPF_TESTMOD_DECLARE_TRACE(bpf_testmod_test_writable_bare,
sizeof(struct bpf_testmod_test_writable_ctx)
);
+DECLARE_TRACE(bpf_testmod_fentry_test1,
+ TP_PROTO(int a),
+ TP_ARGS(a)
+);
+
+DECLARE_TRACE(bpf_testmod_fentry_test2,
+ TP_PROTO(int a, u64 b),
+ TP_ARGS(a, b)
+);
+
#endif /* _BPF_TESTMOD_EVENTS_H */
#undef TRACE_INCLUDE_PATH
diff --git a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
index bc07ce9d5477..f3698746f033 100644
--- a/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
+++ b/tools/testing/selftests/bpf/test_kmods/bpf_testmod.c
@@ -396,11 +396,15 @@ __weak noinline struct file *bpf_testmod_return_ptr(int arg)
noinline int bpf_testmod_fentry_test1(int a)
{
+ trace_bpf_testmod_fentry_test1_tp(a);
+
return a + 1;
}
noinline int bpf_testmod_fentry_test2(int a, u64 b)
{
+ trace_bpf_testmod_fentry_test2_tp(a, b);
+
return a + b;
}
--
2.52.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v4 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-20 7:30 ` [PATCH bpf-next v4 1/2] " Menglong Dong
@ 2026-01-20 22:49 ` Yonghong Song
2026-01-21 0:38 ` Andrii Nakryiko
1 sibling, 0 replies; 7+ messages in thread
From: Yonghong Song @ 2026-01-20 22:49 UTC (permalink / raw)
To: Menglong Dong, ast, andrii
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
On 1/19/26 11:30 PM, Menglong Dong wrote:
> For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
> the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
> tracepoint, especially for the case that the position of the arguments in
> a tracepoint can change.
>
> The target tracepoint BTF type id is specified during loading time,
> therefore we can get the function argument count from the function
> prototype instead of the stack.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf
2026-01-20 7:30 ` [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
@ 2026-01-20 22:52 ` Yonghong Song
0 siblings, 0 replies; 7+ messages in thread
From: Yonghong Song @ 2026-01-20 22:52 UTC (permalink / raw)
To: Menglong Dong, ast, andrii
Cc: daniel, john.fastabend, martin.lau, eddyz87, song, kpsingh, sdf,
haoluo, jolsa, mattbobrowski, rostedt, mhiramat,
mathieu.desnoyers, bpf, linux-kernel, linux-trace-kernel
On 1/19/26 11:30 PM, Menglong Dong wrote:
> Test bpf_get_func_arg() and bpf_get_func_arg_cnt() for tp_btf. The code
> is most copied from test1 and test2.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
Acked-by: Yonghong Song <yonghong.song@linux.dev>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v4 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-20 7:30 ` [PATCH bpf-next v4 1/2] " Menglong Dong
2026-01-20 22:49 ` Yonghong Song
@ 2026-01-21 0:38 ` Andrii Nakryiko
2026-01-21 2:01 ` Menglong Dong
1 sibling, 1 reply; 7+ messages in thread
From: Andrii Nakryiko @ 2026-01-21 0:38 UTC (permalink / raw)
To: Menglong Dong
Cc: ast, andrii, yonghong.song, daniel, john.fastabend, martin.lau,
eddyz87, song, kpsingh, sdf, haoluo, jolsa, mattbobrowski,
rostedt, mhiramat, mathieu.desnoyers, bpf, linux-kernel,
linux-trace-kernel
On Mon, Jan 19, 2026 at 11:31 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
>
> For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
> the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
> tracepoint, especially for the case that the position of the arguments in
> a tracepoint can change.
>
> The target tracepoint BTF type id is specified during loading time,
> therefore we can get the function argument count from the function
> prototype instead of the stack.
>
> Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> ---
> v4:
> - fix the error of using bpf_get_func_arg() for BPF_TRACE_ITER
>
> v3:
> - remove unnecessary NULL checking for prog->aux->attach_func_proto
>
> v2:
> - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> typedef
> ---
> kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> kernel/trace/bpf_trace.c | 4 ++++
> 2 files changed, 32 insertions(+), 4 deletions(-)
>
other than stylistical choices, looks good to me
Acked-by: Andrii Nakryiko <andrii@kernel.org>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index 9de0ec0c3ed9..0b281b7c41eb 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -23323,8 +23323,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* Implement bpf_get_func_arg inline. */
> if (prog_type == BPF_PROG_TYPE_TRACING &&
> insn->imm == BPF_FUNC_get_func_arg) {
> - /* Load nr_args from ctx - 8 */
> - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> + if (eatype == BPF_TRACE_RAW_TP) {
> + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> +
> + /*
> + * skip first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> + } else {
> + /* Load nr_args from ctx - 8 */
> + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> + }
> insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
> insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
> insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
> @@ -23376,8 +23388,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> /* Implement get_func_arg_cnt inline. */
> if (prog_type == BPF_PROG_TYPE_TRACING &&
> insn->imm == BPF_FUNC_get_func_arg_cnt) {
> - /* Load nr_args from ctx - 8 */
> - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> + if (eatype == BPF_TRACE_RAW_TP) {
> + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> +
> + /*
> + * skip first 'void *__data' argument in btf_trace_##name
> + * typedef
> + */
> + nr_args--;
> + /* Save nr_args to reg0 */
> + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
nit: isn't this just a very verbose way of writing:
int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
/* skip 'void *__data' in btf_trace_##name() and save to reg0 */
insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1);
even if you want to preserve nr_args-- for clarity, at least make that
4-line comment into a single-line one, please
> + } else {
> + /* Load nr_args from ctx - 8 */
> + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> + }
>
> new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
> if (!new_prog)
> diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> index f73e08c223b5..0efdad3adcce 100644
> --- a/kernel/trace/bpf_trace.c
> +++ b/kernel/trace/bpf_trace.c
> @@ -1734,10 +1734,14 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> case BPF_FUNC_d_path:
> return &bpf_d_path_proto;
> case BPF_FUNC_get_func_arg:
> + if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
> + return &bpf_get_func_arg_proto;
> return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
> case BPF_FUNC_get_func_ret:
> return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
> case BPF_FUNC_get_func_arg_cnt:
> + if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
> + return &bpf_get_func_arg_cnt_proto;
> return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
hm, wouldn't "has trampoline or is raw_tp" a more logical grouping?
if (bpf_prog_has_trampoline(prog) || prog->expected_attach_type ==
BPF_TRACE_RAW_TP)
return &bpf_get_func_arg_cnt_proto;
return NULL;
maybe you'll need to wrap that condition, but still, at least no one
has to double check that we return exactly the same prototype in both
cases, no?
> case BPF_FUNC_get_attach_cookie:
> if (prog->type == BPF_PROG_TYPE_TRACING &&
> --
> 2.52.0
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf-next v4 1/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP
2026-01-21 0:38 ` Andrii Nakryiko
@ 2026-01-21 2:01 ` Menglong Dong
0 siblings, 0 replies; 7+ messages in thread
From: Menglong Dong @ 2026-01-21 2:01 UTC (permalink / raw)
To: Menglong Dong, Andrii Nakryiko
Cc: ast, andrii, yonghong.song, daniel, john.fastabend, martin.lau,
eddyz87, song, kpsingh, sdf, haoluo, jolsa, mattbobrowski,
rostedt, mhiramat, mathieu.desnoyers, bpf, linux-kernel,
linux-trace-kernel
On 2026/1/21 08:38 Andrii Nakryiko <andrii.nakryiko@gmail.com> write:
> On Mon, Jan 19, 2026 at 11:31 PM Menglong Dong <menglong8.dong@gmail.com> wrote:
> >
> > For now, bpf_get_func_arg() and bpf_get_func_arg_cnt() is not supported by
> > the BPF_TRACE_RAW_TP, which is not convenient to get the argument of the
> > tracepoint, especially for the case that the position of the arguments in
> > a tracepoint can change.
> >
> > The target tracepoint BTF type id is specified during loading time,
> > therefore we can get the function argument count from the function
> > prototype instead of the stack.
> >
> > Signed-off-by: Menglong Dong <dongml2@chinatelecom.cn>
> > ---
> > v4:
> > - fix the error of using bpf_get_func_arg() for BPF_TRACE_ITER
> >
> > v3:
> > - remove unnecessary NULL checking for prog->aux->attach_func_proto
> >
> > v2:
> > - for nr_args, skip first 'void *__data' argument in btf_trace_##name
> > typedef
> > ---
> > kernel/bpf/verifier.c | 32 ++++++++++++++++++++++++++++----
> > kernel/trace/bpf_trace.c | 4 ++++
> > 2 files changed, 32 insertions(+), 4 deletions(-)
> >
>
> other than stylistical choices, looks good to me
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>
>
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index 9de0ec0c3ed9..0b281b7c41eb 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -23323,8 +23323,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* Implement bpf_get_func_arg inline. */
> > if (prog_type == BPF_PROG_TYPE_TRACING &&
> > insn->imm == BPF_FUNC_get_func_arg) {
> > - /* Load nr_args from ctx - 8 */
> > - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > + if (eatype == BPF_TRACE_RAW_TP) {
> > + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> > +
> > + /*
> > + * skip first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
> > + } else {
> > + /* Load nr_args from ctx - 8 */
> > + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > + }
> > insn_buf[1] = BPF_JMP32_REG(BPF_JGE, BPF_REG_2, BPF_REG_0, 6);
> > insn_buf[2] = BPF_ALU64_IMM(BPF_LSH, BPF_REG_2, 3);
> > insn_buf[3] = BPF_ALU64_REG(BPF_ADD, BPF_REG_2, BPF_REG_1);
> > @@ -23376,8 +23388,20 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
> > /* Implement get_func_arg_cnt inline. */
> > if (prog_type == BPF_PROG_TYPE_TRACING &&
> > insn->imm == BPF_FUNC_get_func_arg_cnt) {
> > - /* Load nr_args from ctx - 8 */
> > - insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > + if (eatype == BPF_TRACE_RAW_TP) {
> > + int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> > +
> > + /*
> > + * skip first 'void *__data' argument in btf_trace_##name
> > + * typedef
> > + */
> > + nr_args--;
> > + /* Save nr_args to reg0 */
> > + insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args);
>
> nit: isn't this just a very verbose way of writing:
>
> int nr_args = btf_type_vlen(prog->aux->attach_func_proto);
> /* skip 'void *__data' in btf_trace_##name() and save to reg0 */
> insn_buf[0] = BPF_MOV64_IMM(BPF_REG_0, nr_args - 1);
>
> even if you want to preserve nr_args-- for clarity, at least make that
> 4-line comment into a single-line one, please
>
> > + } else {
> > + /* Load nr_args from ctx - 8 */
> > + insn_buf[0] = BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, -8);
> > + }
> >
> > new_prog = bpf_patch_insn_data(env, i + delta, insn_buf, 1);
> > if (!new_prog)
> > diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
> > index f73e08c223b5..0efdad3adcce 100644
> > --- a/kernel/trace/bpf_trace.c
> > +++ b/kernel/trace/bpf_trace.c
> > @@ -1734,10 +1734,14 @@ tracing_prog_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
> > case BPF_FUNC_d_path:
> > return &bpf_d_path_proto;
> > case BPF_FUNC_get_func_arg:
> > + if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
> > + return &bpf_get_func_arg_proto;
> > return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_proto : NULL;
> > case BPF_FUNC_get_func_ret:
> > return bpf_prog_has_trampoline(prog) ? &bpf_get_func_ret_proto : NULL;
> > case BPF_FUNC_get_func_arg_cnt:
> > + if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
> > + return &bpf_get_func_arg_cnt_proto;
> > return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
>
> hm, wouldn't "has trampoline or is raw_tp" a more logical grouping?
>
> if (bpf_prog_has_trampoline(prog) || prog->expected_attach_type ==
> BPF_TRACE_RAW_TP)
> return &bpf_get_func_arg_cnt_proto;
> return NULL;
>
> maybe you'll need to wrap that condition, but still, at least no one
> has to double check that we return exactly the same prototype in both
> cases, no?
Yeah, it looks better. I tried to write it as:
return (bpf_prog_has_trampoline(prog) || prog->expected_attach_type == BPF_TRACE_RAW_TP) ? &bpf_get_func_arg_cnt_proto : NULL;
but found it ugly.
The way you mentioned looks nice ;)
I'll do it next version.
Thanks!
Menglong Dong
>
>
> > case BPF_FUNC_get_attach_cookie:
> > if (prog->type == BPF_PROG_TYPE_TRACING &&
> > --
> > 2.52.0
> >
>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-01-21 2:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-20 7:30 [PATCH bpf-next v4 0/2] bpf: support bpf_get_func_arg() for BPF_TRACE_RAW_TP Menglong Dong
2026-01-20 7:30 ` [PATCH bpf-next v4 1/2] " Menglong Dong
2026-01-20 22:49 ` Yonghong Song
2026-01-21 0:38 ` Andrii Nakryiko
2026-01-21 2:01 ` Menglong Dong
2026-01-20 7:30 ` [PATCH bpf-next v4 2/2] selftests/bpf: test bpf_get_func_arg() for tp_btf Menglong Dong
2026-01-20 22:52 ` Yonghong Song
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox