Re: [PATCH bpf-next v3 1/7] bpf: Consolidate locks and reference state in verifier state

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

 



On Thu, 28 Nov 2024 at 03:39, Eduard Zingerman <eddyz87@xxxxxxxxx> wrote:
>
> On Wed, 2024-11-27 at 08:58 -0800, Kumar Kartikeya Dwivedi wrote:
> > Currently, state for RCU read locks and preemption is in
> > bpf_verifier_state, while locks and pointer reference state remains in
> > bpf_func_state. There is no particular reason to keep the latter in
> > bpf_func_state. Additionally, it is copied into a new frame's state and
> > copied back to the caller frame's state everytime the verifier processes
> > a pseudo call instruction. This is a bit wasteful, given this state is
> > global for a given verification state / path.
> >
> > Move all resource and reference related state in bpf_verifier_state
> > structure in this patch, in preparation for introducing new reference
> > state types in the future.
> >
> > Signed-off-by: Kumar Kartikeya Dwivedi <memxor@xxxxxxxxx>
>
> lgtm, but please fix the 'print_verifier_state' note below.
>
> Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx>
>
> > ---
> >  include/linux/bpf_verifier.h |  11 ++--
> >  kernel/bpf/log.c             |  11 ++--
> >  kernel/bpf/verifier.c        | 112 ++++++++++++++++-------------------
> >  3 files changed, 64 insertions(+), 70 deletions(-)
> >
> > diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
> > index f4290c179bee..af64b5415df8 100644
> > --- a/include/linux/bpf_verifier.h
> > +++ b/include/linux/bpf_verifier.h
> > @@ -315,9 +315,6 @@ struct bpf_func_state {
> >       u32 callback_depth;
> >
> >       /* The following fields should be last. See copy_func_state() */
> > -     int acquired_refs;
> > -     int active_locks;
> > -     struct bpf_reference_state *refs;
> >       /* The state of the stack. Each element of the array describes BPF_REG_SIZE
> >        * (i.e. 8) bytes worth of stack memory.
> >        * stack[0] represents bytes [*(r10-8)..*(r10-1)]
> > @@ -419,9 +416,13 @@ struct bpf_verifier_state {
> >       u32 insn_idx;
> >       u32 curframe;
> >
> > -     bool speculative;
> > +     struct bpf_reference_state *refs;
> > +     u32 acquired_refs;
> > +     u32 active_locks;
> > +     u32 active_preempt_locks;
> >       bool active_rcu_lock;
> > -     u32 active_preempt_lock;
> > +
> > +     bool speculative;
>
> Nit: pahole says there are two holes here:
>
>      $ pahole kernel/bpf/verifier.o
>      ...
>      struct bpf_verifier_state {
>         struct bpf_func_state *    frame[8];             /*     0    64 */
>         /* --- cacheline 1 boundary (64 bytes) --- */
>         struct bpf_verifier_state * parent;              /*    64     8 */
>         u32                        branches;             /*    72     4 */
>         u32                        insn_idx;             /*    76     4 */
>         u32                        curframe;             /*    80     4 */
>
>         /* XXX 4 bytes hole, try to pack */
>
>         struct bpf_reference_state * refs;               /*    88     8 */
>         u32                        acquired_refs;        /*    96     4 */
>         u32                        active_locks;         /*   100     4 */
>         u32                        active_preempt_locks; /*   104     4 */
>         u32                        active_irq_id;        /*   108     4 */
>         bool                       active_rcu_lock;      /*   112     1 */
>         bool                       speculative;          /*   113     1 */
>         bool                       used_as_loop_entry;   /*   114     1 */
>         bool                       in_sleepable;         /*   115     1 */
>         u32                        first_insn_idx;       /*   116     4 */
>         u32                        last_insn_idx;        /*   120     4 */
>
>         /* XXX 4 bytes hole, try to pack */
>
>         /* --- cacheline 2 boundary (128 bytes) --- */
>         struct bpf_verifier_state * loop_entry;          /*   128     8 */
>         u32                        insn_hist_start;      /*   136     4 */
>         u32                        insn_hist_end;        /*   140     4 */
>         u32                        dfs_depth;            /*   144     4 */
>         u32                        callback_unroll_depth; /*   148     4 */
>         u32                        may_goto_depth;       /*   152     4 */
>
>         /* size: 160, cachelines: 3, members: 22 */
>         /* sum members: 148, holes: 2, sum holes: 8 */
>
>     maybe move the 'refs' pointer?
>     e.g. moving it after 'parent' makes both holes disappear.

Ack, will fix.

>
> >       /* If this state was ever pointed-to by other state's loop_entry field
> >        * this flag would be set to true. Used to avoid freeing such states
> >        * while they are still in use.
> > diff --git a/kernel/bpf/log.c b/kernel/bpf/log.c
> > index 4a858fdb6476..8b52e5b7504c 100644
> > --- a/kernel/bpf/log.c
> > +++ b/kernel/bpf/log.c
> > @@ -756,6 +756,7 @@ static void print_reg_state(struct bpf_verifier_env *env,
> >  void print_verifier_state(struct bpf_verifier_env *env, const struct bpf_func_state *state,
> >                         bool print_all)
> >  {
> > +     struct bpf_verifier_state *vstate = env->cur_state;
>
> This is not always true.
> For example, __mark_chain_precision does 'print_verifier_state(env, func, true)'
> for func obtained as 'func = st->frame[fr];' where 'st' iterates over parents
> of env->cur_state.

Looking through the code, I'm thinking the only proper fix is
explicitly passing in the verifier state, I was hoping there would be
a link from func_state -> verifier_state but it is not the case.
Regardless, explicitly passing in the verifier state is probably cleaner. WDYT?

>
> >       const struct bpf_reg_state *reg;
> >       int i;
> >
>
> [...]
>




[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