Skip to content

Commit f11f7cf

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpf-add-bpf_stream_print_stack-kfunc'
Emil Tsalapatis says: ==================== bpf: Add bpf_stream_print_stack kfunc Add a new bpf_stream_print_stack kfunc for printing a BPF program stack into a BPF stream. Update the verifier to allow the new kfunc to be called with BPF spinlocks held, along with bpf_stream_vprintk. Patchset spun out of the larger libarena + ASAN patchset. (https://lore.kernel.org/bpf/20260127181610.86376-1-emil@etsalapatis.com/) Changeset: - Update bpf_stream_print_stack to take stream_id arg (Kumar) - Added selftest for the bpf_stream_print_stack - Add selftest for calling the streams kfuncs under lock v2->v1: (https://lore.kernel.org/bpf/20260202193311.446717-1-emil@etsalapatis.com/) - Updated Signed-off-by to be consistent with past submissions - Updated From email to be consistent with Signed-off-by Acked-by: Kumar Kartikeya Dwivedi <memxor@gmail.com> Signed-off-by: Emil Tsalapatis <emil@etsalapatis.com> ==================== Link: https://patch.msgid.link/20260203180424.14057-1-emil@etsalapatis.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents f941479 + 4d99137 commit f11f7cf

4 files changed

Lines changed: 85 additions & 1 deletion

File tree

kernel/bpf/helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4562,6 +4562,7 @@ BTF_ID_FLAGS(func, bpf_strncasestr);
45624562
BTF_ID_FLAGS(func, bpf_cgroup_read_xattr, KF_RCU)
45634563
#endif
45644564
BTF_ID_FLAGS(func, bpf_stream_vprintk, KF_IMPLICIT_ARGS)
4565+
BTF_ID_FLAGS(func, bpf_stream_print_stack, KF_IMPLICIT_ARGS)
45654566
BTF_ID_FLAGS(func, bpf_task_work_schedule_signal, KF_IMPLICIT_ARGS)
45664567
BTF_ID_FLAGS(func, bpf_task_work_schedule_resume, KF_IMPLICIT_ARGS)
45674568
BTF_ID_FLAGS(func, bpf_dynptr_from_file)

kernel/bpf/stream.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,25 @@ __bpf_kfunc int bpf_stream_vprintk(int stream_id, const char *fmt__str, const vo
245245
return ret;
246246
}
247247

248+
/* Directly trigger a stack dump from the program. */
249+
__bpf_kfunc int bpf_stream_print_stack(int stream_id, struct bpf_prog_aux *aux)
250+
{
251+
struct bpf_stream_stage ss;
252+
struct bpf_prog *prog;
253+
254+
/* Make sure the stream ID is valid. */
255+
if (!bpf_stream_get(stream_id, aux))
256+
return -ENOENT;
257+
258+
prog = aux->main_prog_aux->prog;
259+
260+
bpf_stream_stage(ss, prog, stream_id, ({
261+
bpf_stream_dump_stack(ss);
262+
}));
263+
264+
return 0;
265+
}
266+
248267
__bpf_kfunc_end_defs();
249268

250269
/* Added kfunc to common_btf_ids */

kernel/bpf/verifier.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12455,6 +12455,8 @@ enum special_kfunc_type {
1245512455
KF_bpf_arena_free_pages,
1245612456
KF_bpf_arena_reserve_pages,
1245712457
KF_bpf_session_is_return,
12458+
KF_bpf_stream_vprintk,
12459+
KF_bpf_stream_print_stack,
1245812460
};
1245912461

1246012462
BTF_ID_LIST(special_kfunc_list)
@@ -12533,6 +12535,8 @@ BTF_ID(func, bpf_arena_alloc_pages)
1253312535
BTF_ID(func, bpf_arena_free_pages)
1253412536
BTF_ID(func, bpf_arena_reserve_pages)
1253512537
BTF_ID(func, bpf_session_is_return)
12538+
BTF_ID(func, bpf_stream_vprintk)
12539+
BTF_ID(func, bpf_stream_print_stack)
1253612540

1253712541
static bool is_task_work_add_kfunc(u32 func_id)
1253812542
{
@@ -12977,10 +12981,17 @@ static bool is_bpf_arena_kfunc(u32 btf_id)
1297712981
btf_id == special_kfunc_list[KF_bpf_arena_reserve_pages];
1297812982
}
1297912983

12984+
static bool is_bpf_stream_kfunc(u32 btf_id)
12985+
{
12986+
return btf_id == special_kfunc_list[KF_bpf_stream_vprintk] ||
12987+
btf_id == special_kfunc_list[KF_bpf_stream_print_stack];
12988+
}
12989+
1298012990
static bool kfunc_spin_allowed(u32 btf_id)
1298112991
{
1298212992
return is_bpf_graph_api_kfunc(btf_id) || is_bpf_iter_num_api_kfunc(btf_id) ||
12983-
is_bpf_res_spin_lock_kfunc(btf_id) || is_bpf_arena_kfunc(btf_id);
12993+
is_bpf_res_spin_lock_kfunc(btf_id) || is_bpf_arena_kfunc(btf_id) ||
12994+
is_bpf_stream_kfunc(btf_id);
1298412995
}
1298512996

1298612997
static bool is_sync_callback_calling_kfunc(u32 btf_id)

tools/testing/selftests/bpf/progs/stream.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ int size;
4242
u64 fault_addr;
4343
void *arena_ptr;
4444

45+
#define private(name) SEC(".bss." #name) __hidden __attribute__((aligned(8)))
46+
47+
private(STREAM) struct bpf_spin_lock block;
48+
4549
SEC("syscall")
4650
__success __retval(0)
4751
int stream_exhaust(void *ctx)
@@ -234,4 +238,53 @@ int stream_arena_callback_fault(void *ctx)
234238
return 0;
235239
}
236240

241+
SEC("syscall")
242+
__arch_x86_64
243+
__arch_arm64
244+
__success __retval(0)
245+
__stderr("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}")
246+
__stderr("Call trace:\n"
247+
"{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
248+
"|[ \t]+[^\n]+\n)*}}")
249+
int stream_print_stack_kfunc(void *ctx)
250+
{
251+
return bpf_stream_print_stack(BPF_STDERR);
252+
}
253+
254+
SEC("syscall")
255+
__success __retval(-2)
256+
int stream_print_stack_invalid_id(void *ctx)
257+
{
258+
/* Try to pass an invalid stream ID. */
259+
return bpf_stream_print_stack((enum bpf_stream_id)0xbadcafe);
260+
}
261+
262+
SEC("syscall")
263+
__arch_x86_64
264+
__arch_arm64
265+
__success __retval(0)
266+
__stdout(_STR)
267+
__stderr("CPU: {{[0-9]+}} UID: 0 PID: {{[0-9]+}} Comm: {{.*}}")
268+
__stderr("Call trace:\n"
269+
"{{([a-zA-Z_][a-zA-Z0-9_]*\\+0x[0-9a-fA-F]+/0x[0-9a-fA-F]+\n"
270+
"|[ \t]+[^\n]+\n)*}}")
271+
int stream_print_kfuncs_locked(void *ctx)
272+
{
273+
int ret;
274+
275+
bpf_spin_lock(&block);
276+
277+
ret = bpf_stream_printk(BPF_STDOUT, _STR);
278+
if (ret)
279+
goto out;
280+
281+
ret = bpf_stream_print_stack(BPF_STDERR);
282+
283+
out:
284+
bpf_spin_unlock(&block);
285+
286+
return ret;
287+
}
288+
289+
237290
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)