Re: [PATCH v2 bpf-next 2/3] Right align verifier states in verifier logs

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

 



On Thu, Dec 16, 2021 at 7:59 AM Christy Lee <christyc.y.lee@xxxxxxxxx> wrote:>

Apologies, resending this because the previous email was not plain text.

>
> On Wed, Dec 15, 2021 at 11:02 PM Andrii Nakryiko <andrii.nakryiko@xxxxxxxxx> wrote:
>>
>> On Wed, Dec 15, 2021 at 11:22 AM Christy Lee <christylee@xxxxxx> wrote:
>> >
>
> [...]
>>
>>
>> There seems to be quite a lot of jumpin back and forth in terms of
>> 33th (see off by one error below) vs 40th offsets (this is for
>> pyperf50 test):
>>
>> 16: (07) r2 += -8               ; R2_w=fp-8
>> ; Event* event = bpf_map_lookup_elem(&eventmap, &zero);
>> 17: (18) r1 = 0xffff88810d81dc00       ;
>> R1_w=map_ptr(id=0,off=0,ks=4,vs=252,imm=0)
>> 19: (85) call bpf_map_lookup_elem#1    ;
>> R0=map_value_or_null(id=3,off=0,ks=4,vs=252,imm=0)
>> 20: (bf) r7 = r0                ;
>> R0=map_value_or_null(id=3,off=0,ks=4,vs=252,imm=0)
>> R7_w=map_value_or_null(id=3,off=0,ks=4,vs=252,imm=0)
>> ; if (!event)
>> 21: (15) if r7 == 0x0 goto pc+5193     ;
>> R7_w=map_value(id=0,off=0,ks=4,vs=252,imm=0)
>> ; event->pid = pid;
>> 22: (61) r1 = *(u32 *)(r10 -4)  ;
>> R1_w=inv(id=0,umax_value=4294967295,var_off=(0x0; 0xffffffff)) R10=fp0
>>
>> Maybe let's bump the minimum to 40?
>
> Will do! I'll experiment with the nicest looking offset.
>>
>>
>> >
>> > Signed-off-by: Christy Lee <christylee@xxxxxx>
>
> [...]
>>
>> >
>> > +static u32 vlog_alignment(u32 prev_insn_print_len)
>> > +{
>> > +       if (prev_insn_print_len < BPF_LOG_ALIGNMENT_POS)
>> > +               return BPF_LOG_ALIGNMENT_POS - prev_insn_print_len + 1;
>>
>> why +1 here?
>
> I wanted the insn_state to be prepended by BPF_LOG_ALIGNMENT_POS
> number of characters, in this case, that would be prepended by 32 and starting
> at 33. This ensures that whether prev_insn_print_len is smaller than
> BPF_LOG_ALIGNMENT_POS or not, the insn_states would be aligned properly,
> there would be an off-by-one error otherwise.
>>
>>
>> > +       return round_up(prev_insn_print_len, BPF_LOG_MIN_ALIGNMENT) -
>> > +              prev_insn_print_len;
>> > +}
>> > +
>> > +static void print_prev_insn_state(struct bpf_verifier_env *env,
>> > +                                 const struct bpf_func_state *state)
>> > +{
>> > +       if (env->prev_log_len == env->log.len_used) {
>> > +               if (env->prev_log_len)
>> > +                       bpf_vlog_reset(&env->log, env->prev_log_len - 1);
>>
>> I don't get this... why do we need this reset? Why just appending
>> alignment spaces below doesn't work?
>
> The insn are printed via print_bpf_insn() which ends the line with a '\n', we need to
> reset one character in order to remove the new line and print insn_state on the same
> line. print_bpf_insn() is defined in kernel/bpf/disasm.h and used by bpf_tool as well, so I
> didn't want to modify it.
>>
>>
>> > +               verbose(env, "%*c;", vlog_alignment(env->prev_insn_print_len),
>> > +                       ' ');
>>
>> nit: keep it on single line
>>
>> > +       } else
>> > +               verbose(env, "%d:", env->insn_idx);
>>
>> if one branch of if/else has {}, the other one has to have them as
>> well, even if it's a single line statement
>>
>> > +       print_verifier_state(env, state);
>> > +}
>> > +
>> >  /* copy array src of length n * size bytes to dst. dst is reallocated if it's too
>> >   * small to hold src. This is different from krealloc since we don't want to preserve
>> >   * the contents of dst.
>>
>> [...]
>>
>> > @@ -9441,8 +9465,10 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
>> >                         insn->dst_reg);
>> >                 return -EACCES;
>> >         }
>> > -       if (env->log.level & BPF_LOG_LEVEL)
>> > -               print_verifier_state(env, this_branch->frame[this_branch->curframe]);
>> > +       if (env->log.level & BPF_LOG_LEVEL) {
>> > +               print_prev_insn_state(
>> > +                       env, this_branch->frame[this_branch->curframe]);
>>
>> nit: keep on a single line. But also is it really a "previous
>> instruction" or still a current instruction? Maybe just
>> "print_insn_state"? Do we have "next_insn" helper anywhere? If not,
>> dropping this "prev_" prefix from helpers and variables would be
>> cleaner, IMO
>>
>> > +       }
>> >         return 0;
>> >  }
>> >
>> > @@ -11310,17 +11336,12 @@ static int do_check(struct bpf_verifier_env *env)
>> >                 if (need_resched())
>> >                         cond_resched();
>> >
>> > -               if ((env->log.level & BPF_LOG_LEVEL2) ||
>> > -                   (env->log.level & BPF_LOG_LEVEL && do_print_state)) {
>> > -                       if (verifier_state_scratched(env) &&
>> > -                           (env->log.level & BPF_LOG_LEVEL2))
>> > -                               verbose(env, "%d:", env->insn_idx);
>> > -                       else
>> > -                               verbose(env, "\nfrom %d to %d%s:",
>> > -                                       env->prev_insn_idx, env->insn_idx,
>> > -                                       env->cur_state->speculative ?
>> > -                                       " (speculative execution)" : "");
>> > -                       print_verifier_state(env, state->frame[state->curframe]);
>> > +               if (env->log.level & BPF_LOG_LEVEL1 && do_print_state) {
>>
>> () around bit operations
>>
>> > +                       verbose(env, "\nfrom %d to %d%s:\n", env->prev_insn_idx,
>> > +                               env->insn_idx,
>> > +                               env->cur_state->speculative ?
>> > +                                       " (speculative execution)" :
>> > +                                             "");
>>
>> it's ok to go up to 100 characters, please keep the code more readable
>>
>> >                         do_print_state = false;
>> >                 }
>> >
>> > @@ -11331,9 +11352,17 @@ static int do_check(struct bpf_verifier_env *env)
>> >                                 .private_data   = env,
>> >                         };
>> >
>> > +                       if (verifier_state_scratched(env))
>> > +                               print_prev_insn_state(
>> > +                                       env, state->frame[state->curframe]);
>> > +
>> >                         verbose_linfo(env, env->insn_idx, "; ");
>> > +                       env->prev_log_len = env->log.len_used;
>> >                         verbose(env, "%d: ", env->insn_idx);
>> >                         print_bpf_insn(&cbs, insn, env->allow_ptr_leaks);
>> > +                       env->prev_insn_print_len =
>> > +                               env->log.len_used - env->prev_log_len;
>> > +                       env->prev_log_len = env->log.len_used;
>> >                 }
>> >
>> >                 if (bpf_prog_is_dev_bound(env->prog->aux)) {
>>
>> [...]



[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