Re: [PATCH bpf-next v4 06/12] bpf: Add dump_stack() analogue to print to BPF stderr

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jul 1, 2025 at 11:17 PM Kumar Kartikeya Dwivedi
<memxor@xxxxxxxxx> wrote:
>
> Introduce a kernel function which is the analogue of dump_stack()
> printing some useful information and the stack trace. This is not
> exposed to BPF programs yet, but can be made available in the future.
>
> When we have a program counter for a BPF program in the stack trace,
> also additionally output the filename and line number to make the trace
> helpful. The rest of the trace can be passed into ./decode_stacktrace.sh
> to obtain the line numbers for kernel symbols.
>
> Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx>
> ---
>  include/linux/bpf.h |  2 ++
>  kernel/bpf/stream.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 46 insertions(+)
>

Reviewed-by: Emil Tsalapatis <emil@xxxxxxxxxxxxxxx>

> diff --git a/include/linux/bpf.h b/include/linux/bpf.h
> index 4d577352f3e6..18f8e4066e20 100644
> --- a/include/linux/bpf.h
> +++ b/include/linux/bpf.h
> @@ -3615,8 +3615,10 @@ __printf(2, 3)
>  int bpf_stream_stage_printk(struct bpf_stream_stage *ss, const char *fmt, ...);
>  int bpf_stream_stage_commit(struct bpf_stream_stage *ss, struct bpf_prog *prog,
>                             enum bpf_stream_id stream_id);
> +int bpf_stream_stage_dump_stack(struct bpf_stream_stage *ss);
>
>  #define bpf_stream_printk(ss, ...) bpf_stream_stage_printk(&ss, __VA_ARGS__)
> +#define bpf_stream_dump_stack(ss) bpf_stream_stage_dump_stack(&ss)
>
>  #define bpf_stream_stage(ss, prog, stream_id, expr)            \
>         ({                                                     \
> diff --git a/kernel/bpf/stream.c b/kernel/bpf/stream.c
> index c4925f8d275f..370eae669300 100644
> --- a/kernel/bpf/stream.c
> +++ b/kernel/bpf/stream.c
> @@ -2,6 +2,7 @@
>  /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */
>
>  #include <linux/bpf.h>
> +#include <linux/filter.h>
>  #include <linux/bpf_mem_alloc.h>
>  #include <linux/percpu.h>
>  #include <linux/refcount.h>
> @@ -476,3 +477,46 @@ int bpf_stream_stage_commit(struct bpf_stream_stage *ss, struct bpf_prog *prog,
>         llist_add_batch(head, tail, &stream->log);
>         return 0;
>  }
> +
> +struct dump_stack_ctx {
> +       struct bpf_stream_stage *ss;
> +       int err;
> +};
> +
> +static bool dump_stack_cb(void *cookie, u64 ip, u64 sp, u64 bp)
> +{
> +       struct dump_stack_ctx *ctxp = cookie;
> +       const char *file = "", *line = "";
> +       struct bpf_prog *prog;
> +       int num, ret;
> +
> +       rcu_read_lock();
> +       prog = bpf_prog_ksym_find(ip);
> +       rcu_read_unlock();
> +       if (prog) {
> +               ret = bpf_prog_get_file_line(prog, ip, &file, &line, &num);
> +               if (ret < 0)
> +                       goto end;

I assume that this is by design that if we cannot resolve the IP to a
source line
we just dump the IP and continue the stack walk.

> +               ctxp->err = bpf_stream_stage_printk(ctxp->ss, "%pS\n  %s @ %s:%d\n",
> +                                                   (void *)ip, line, file, num);
> +               return !ctxp->err;
> +       }
> +end:
> +       ctxp->err = bpf_stream_stage_printk(ctxp->ss, "%pS\n", (void *)ip);
> +       return !ctxp->err;
> +}
> +
> +int bpf_stream_stage_dump_stack(struct bpf_stream_stage *ss)
> +{
> +       struct dump_stack_ctx ctx = { .ss = ss };
> +       int ret;
> +
> +       ret = bpf_stream_stage_printk(ss, "CPU: %d UID: %d PID: %d Comm: %s\n",
> +                                     raw_smp_processor_id(), __kuid_val(current_real_cred()->euid),
> +                                     current->pid, current->comm);
> +       ret = ret ?: bpf_stream_stage_printk(ss, "Call trace:\n");
> +       if (!ret)

Nit: Can we flip this and just do
    if (ret)
        return ret;
? I get using ?: for brevity but it makes the code less obvious, and
this specific check
isn't even shorter than the more straightforward alternative.

> +               arch_bpf_stack_walk(dump_stack_cb, &ctx);
> +       ret = ret ?: ctx.err;
> +       return ret ?: bpf_stream_stage_printk(ss, "\n");
> +}
> --
> 2.47.1
>





[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux