Re: [PATCH bpf-next v1 09/11] libbpf: Add bpf_stream_printk() macro

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

 



On Fri, 9 May 2025 at 01:48, Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx> wrote:
>
> On Fri, 9 May 2025 at 01:42, Alexei Starovoitov
> <alexei.starovoitov@xxxxxxxxx> wrote:
> >
> > On Wed, May 7, 2025 at 10:17 AM Kumar Kartikeya Dwivedi
> > <memxor@xxxxxxxxx> wrote:
> > >
> > > Introduce a new macro that allows printing data similar to bpf_printk(),
> > > but to BPF streams. The first argument is the stream ID, the rest of the
> > > arguments are same as what one would pass to bpf_printk().
> > >
> > > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx>
> > > ---
> > >  kernel/bpf/stream.c         | 10 +++++++--
> > >  tools/lib/bpf/bpf_helpers.h | 44 +++++++++++++++++++++++++++++++------
> > >  2 files changed, 45 insertions(+), 9 deletions(-)
> > >
> > > diff --git a/kernel/bpf/stream.c b/kernel/bpf/stream.c
> > > index eaf0574866b1..d64975486ad1 100644
> > > --- a/kernel/bpf/stream.c
> > > +++ b/kernel/bpf/stream.c
> > > @@ -257,7 +257,12 @@ __bpf_kfunc int bpf_stream_vprintk(struct bpf_stream *stream, const char *fmt__s
> > >         return ret;
> > >  }
> > >
> > > -__bpf_kfunc struct bpf_stream *bpf_stream_get(enum bpf_stream_id stream_id, void *aux__ign)
> > > +/* Use int vs enum stream_id here, we use this kfunc in bpf_helpers.h, and
> > > + * keeping enum stream_id necessitates a complete definition of enum, but we
> > > + * can't copy it in the header as it may conflict with the definition in
> > > + * vmlinux.h.
> > > + */
> > > +__bpf_kfunc struct bpf_stream *bpf_stream_get(int stream_id, void *aux__ign)
> > >  {
> > >         struct bpf_prog_aux *aux = aux__ign;
> > >
> > > @@ -351,7 +356,8 @@ __bpf_kfunc struct bpf_stream_elem *bpf_stream_next_elem(struct bpf_stream *stre
> > >         return elem;
> > >  }
> > >
> > > -__bpf_kfunc struct bpf_stream *bpf_prog_stream_get(enum bpf_stream_id stream_id, u32 prog_id)
> > > +/* Use int vs enum bpf_stream_id for consistency with bpf_stream_get. */
> > > +__bpf_kfunc struct bpf_stream *bpf_prog_stream_get(int stream_id, u32 prog_id)
> > >  {
> > >         struct bpf_stream *stream;
> > >         struct bpf_prog *prog;
> > > diff --git a/tools/lib/bpf/bpf_helpers.h b/tools/lib/bpf/bpf_helpers.h
> > > index a50773d4616e..1a748c21e358 100644
> > > --- a/tools/lib/bpf/bpf_helpers.h
> > > +++ b/tools/lib/bpf/bpf_helpers.h
> > > @@ -314,17 +314,47 @@ enum libbpf_tristate {
> > >                           ___param, sizeof(___param));          \
> > >  })
> > >
> > > +struct bpf_stream;
> > > +
> > > +extern struct bpf_stream *bpf_stream_get(int stream_id, void *aux__ign) __weak __ksym;
> > > +extern int bpf_stream_vprintk(struct bpf_stream *stream, const char *fmt__str, const void *args,
> > > +                             __u32 len__sz) __weak __ksym;
> > > +
> > > +#define __bpf_stream_vprintk(stream, fmt, args...)                             \
> > > +({                                                                             \
> > > +       static const char ___fmt[] = fmt;                                       \
> > > +       unsigned long long ___param[___bpf_narg(args)];                         \
> > > +                                                                               \
> > > +       _Pragma("GCC diagnostic push")                                          \
> > > +       _Pragma("GCC diagnostic ignored \"-Wint-conversion\"")                  \
> > > +       ___bpf_fill(___param, args);                                            \
> > > +       _Pragma("GCC diagnostic pop")                                           \
> > > +                                                                               \
> > > +       int ___id = stream;                                                     \
> > > +       struct bpf_stream *___sptr = bpf_stream_get(___id, NULL);               \
> > > +       if (___sptr)                                                            \
> > > +               bpf_stream_vprintk(___sptr, ___fmt, ___param, sizeof(___param));\
> > > +})
> >
> > Typically _get() is an acquire kfunc,
> > but here:
> >
> > +BTF_ID_FLAGS(func, bpf_stream_get, KF_RET_NULL)
> > ...
> > +BTF_ID_FLAGS(func, bpf_prog_stream_get, KF_ACQUIRE | KF_RET_NULL)
> >
> > This is odd and it makes above sequence look weird too.
> >
> > This is inconsistent as well:
> > bpf_stream_printk(int stream,
> > bpf_stream_vprintk(struct bpf_stream *stream,
> >
> > Existing helpers bpf_trace_printk() and bpf_trace_vprintk()
> > are consistent.
> >
> > Not sure why bpf_stream_get() is needed at all.
> >
> > Maybe
> > #define BPF_STDOUT ((struct bpf_stream *)1)
> > #define BPF_STDERR ((struct bpf_stream *)2)
> >
> > not pretty, but at least api will be consistent.
> >
> > Other ideas ?
>
> We can take the stream id directly in bpf_stream_vprintk, we have room
> for one more argument, that can be hidden prog->aux.
> Then we can drop bpf_stream_get.

Taking it directly does negate the ability to write into any stream *
one has access to, so there's that.

>
> Alternatively there's a way to call it bpf_stream_self.
> I wasn't concerned about inconsistency since bpf_stream_vprintk is not
> something people will use directly, you have to stuff arguments as array
> of u64 etc. so it's unusable in practice. The main API exposed is
> bpf_stream_printk. But I get the concern.





[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