All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: bot+bpf-ci@kernel.org, bpf@vger.kernel.org, ast@kernel.org
Cc: andrii@kernel.org, daniel@iogearbox.net, kernel-team@fb.com,
	 yonghong.song@linux.dev, martin.lau@kernel.org,
	mason@kernel.org,  ihor.solodrai@linux.dev
Subject: Re: [PATCH bpf-next v3 19/51] bpf: representation for intervals with steps
Date: Fri, 09 Oct 2026 11:55:21 -0700	[thread overview]
Message-ID: <faf14259573df35d2fc49a8445be5cd79a0a8565.camel@gmail.com> (raw)
In-Reply-To: <debf620cc082978bcb926bf13fa5af72f46e25607f0ca9289f4bb41ca15530d3@mail.kernel.org>

On Fri, 2026-10-09 at 12:07 +0000, bot+bpf-ci@kernel.org wrote:
> > bpf: representation for intervals with steps
> 
> TL;DR:
> - Commit message says eq/neq branches ignore base/step, but they appear to
>   change branch pruning
> - Comment in reg_bounds_sync() names reg_umin() where reg_smin() seems
>   intended (nit)
> 
> >     bpf: representation for intervals with steps
> > 
> >     Extend scalar register tracking with a linear "base + step * k" description:
> >     each scalar carries two u16 fields, base and step (invariant: base < step),
> >     recording that its value is some point on the line base + step * k.
> >     A fresh scalar starts as base=0, step=1, i.e. any integer.
> > 
> >     This lets the verifier reason about strided values, e.g. an index multiplied
> >     by an element size, which neither the min/max bounds nor the tnum can capture
> >     for a non-power-of-2 stride. Such reasoning is necessary to allow
> >     array access with a variable offset through PTR_TO_BTF_ID, e.g.
> >     for expressions like p->arr[i].field.
> > 
> >     reg_bounds_sync() uses the description in two ways:
> >     - __reg_bound_offset() clears the low bits of var_off implied by the number
> >       of trailing zeros shared by base and step.
> >     - __update_bounds_from_step() intersects the 64-bit range with the line via
> >       cnum64_intersect_linear(), snapping smin/smax to actual points on it.
> >       This is the last step of the sync, as refining the range from var_off
> >       can move the bounds off the line.
> > 
> >     range_within() is extended to check whether the cur register's equation
> >     describes a subset of the points described by the old register's equation.
> > 
> >     Scalar ALU operations update base/step as follows:
> >     - ADD of a constant (including pointer + scalar): keep step, shift base;
> >     - MUL by a constant: scale step and base by the constant;
> >     - LSH by a constant: scale step and base by the corresponding power of two;
> >     - sign extension: keep the register unchanged if all values fit the target
> >       type, reset to base=0, step=1 otherwise;
> >     - All other operations reset to base=0, step=1.
> > 
> >     Branch (eq/neq) checks do not take into account base/step yet.
> > 
> >     Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
> 
> The changelog says "Branch (eq/neq) checks do not take into account base/step
> yet."  Is that accurate for this patch?
> 
> is_scalar_branch_taken() ends by calling simulate_both_branches_taken().  That
> function runs regs_refine_cond_op() and reg_bounds_sync() on copies of the
> registers, and treats range_bounds_violation() as proof that a branch is dead.
> 
> reg_bounds_sync() now ends with __update_bounds_from_step(), and
> cnum64_intersect_linear() returns CNUM64_EMPTY when the refined range holds no
> point of base + step * k.
> 
> For example, take r1 in [0, 30] with step=3, base=0 (say from r0 *= 3 with r0
> in [0, 10]), followed by:
> 
>     if r1 == 4 goto L
> 
> The tnum and min/max checks cannot decide this.  In
> simulate_both_branches_taken() the true branch refines r64 to [4, 4], and then
> in cnum64_intersect_linear():
> 
>     d = imod(base - imod(smin, step), step);   /* imod(0 - 1, 3) == 2 */
>     if ((u64)smax - (u64)smin < d)              /* 0 < 2 */
>             return CNUM64_EMPTY;
> 
> So the JEQ branch is treated as dead (pred = 0) purely because of
> base/step.  JNE behaves the same way, and JNE against a range edge now snaps
> the bound onto the line ([0, 29] becomes [0, 27]).
> 
> This looks sound as long as base/step are sound, but it is a real change to
> branch pruning, and mark_chain_precision() is called on the compared registers
> whenever pred >= 0.  Should the changelog describe this instead of saying
> eq/neq branches ignore base/step?

Kind of. Sort of.
There is no explicit handling in is_scalar_branch_taken(),
as well as it is not wired for pointers.
I didn't think through if simulate_both_branches_taken()
is sufficient or some explicit rules is_scalar_branch_taken()
might be of use as well.

> 
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index 47a632a6749a..f5b2500335a7 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> 
> [ ... ]
> 
> > @@ -2208,6 +2337,15 @@ static void reg_bounds_sync(struct bpf_reg_state *reg)
> >  	 * then new var_off is (0; 0x7f...fc) which improves our umax.
> >  	 */
> >  	__update_reg_bounds(reg);
> > +	/*
> > +	 * Both tnum and base+step define a sequence of points,
> > +	 * potentially w/o intersection, or intersecting after N
> > +	 * tnum_step()'s, where N can be large. On the other hand,
> > +	 * step+base *must* be in sync with r64 in order for
> > +	 * array traversal logic starting at reg_umin() to be sound.
>                                           ^^^^^^^^^^
> 
> This isn't a bug, but is reg_umin() the right function to name here?  The
> array traversal logic isn't part of this patch.

Yes, this should be reg_smin().

  reply	other threads:[~2026-10-09 18:55 UTC|newest]

Thread overview: 76+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-09 10:47 [PATCH bpf-next v3 00/51] bpf: use scalar evolution to widen bounded loops Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 01/51] bpf: represent stack access effects with arg_access_info Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 02/51] bpf: describe helper stack accesses " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 03/51] bpf: describe kfunc " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 04/51] bpf: track may_write flags in liveness Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 05/51] bpf: summarize may write stack slots in insn_aux_data Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 06/51] bpf: summarize live " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 07/51] bpf: summarize regs that may hold a frame pointer " Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 08/51] bpf: record write effects for atomic operations in liveness.c Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 09/51] bpf: fix arg_track_xfer() for atomic stack spills and fills Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 10/51] bpf: derive global subprog stack liveness from BTF signatures Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 18:49     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 11/51] bpf: compute parameters liveness in bpf_compute_live_registers() Eduard Zingerman
2026-10-09 11:26   ` sashiko-bot
2026-10-09 18:46     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 12/51] bpf: add tnum_alignment() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 13/51] bpf: add cnum{32,64}_union() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 14/51] bpf: add cnum64_intersect_linear() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 15/51] bpf: expose bpf_rev_opcode() and bpf_flip_opcode() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 16/51] bpf: expose bpf_grow_stack_state() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 17/51] bpf: expose bpf_verbose_snum() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 18/51] bpf: allow subrange relations for PTR_TO_STACK in regsafe() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 19/51] bpf: representation for intervals with steps Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 18:55     ` Eduard Zingerman [this message]
2026-10-09 10:47 ` [PATCH bpf-next v3 20/51] bpf: varying offset access support for PTR_TO_BTF_ID pointers Eduard Zingerman
2026-10-09 11:41   ` sashiko-bot
2026-10-09 19:43     ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 21/51] bpf: save DFS postorder numbers for program instructions Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 22/51] bpf: move the live-register and SCC printout to a standalone function Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 23/51] bpf: compute immediate dominators Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 24/51] bpf: compute loop hierarchy Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 25/51] bpf: add bpf_set_reg_range() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 26/51] bpf: add bpf_mark_reg_known_scalar() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 27/51] bpf: add bpf_reg_union() and bpf_reg_union_compatible() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 28/51] bpf: add bpf_split_cur_state() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 29/51] bpf: add bpf_same_memory_origin() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 30/51] bpf: add bpf_spill_size() Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 31/51] bpf: record basic-block ends in insn_aux_data Eduard Zingerman
2026-10-09 11:45   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 32/51] bpf: allow precision backtracking between overlapping checkpoints Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 33/51] bpf: compute scalar evolution expressions for loops Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 34/51] bpf: use SCEV to widen bounded loops Eduard Zingerman
2026-10-09 12:08   ` bot+bpf-ci
2026-10-10  1:25   ` kernel test robot
2026-10-10 14:55     ` Alexei Starovoitov
2026-10-10 20:02       ` Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 35/51] bpf: avoid widening registers that hinder exact stack-slot tracking Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 12:08   ` sashiko-bot
2026-10-09 10:47 ` [PATCH bpf-next v3 36/51] bpf: bpf_func_state size optimization Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:47 ` [PATCH bpf-next v3 37/51] selftests/bpf: __msg_next tag for matching messages on consecutive lines Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 38/51] selftests/bpf: bound UNIX socket path loops by sun_path size Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 39/51] selftests/bpf: test for stack-pointer subrange pruning Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 40/51] selftests/bpf: tests for may_write stack-liveness tracking Eduard Zingerman
2026-10-09 10:47 ` [PATCH bpf-next v3 41/51] selftests/bpf: tests for may_def marks of atomic RMW operations Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 42/51] selftests/bpf: tests for stack pointer spills/fills through atomics Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 43/51] selftests/bpf: tests for map special cases in bpf_helper_stack_access_bytes() Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 44/51] selftests/bpf: tests for BTF-based global subprog stack liveness Eduard Zingerman
2026-10-09 11:45   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 45/51] selftests/bpf: test for register liveness of subprogram arguments Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 46/51] selftests/bpf: tests for register base/step arithmetic Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 47/51] selftests/bpf: tests for register base/step state pruning Eduard Zingerman
2026-10-09 12:22   ` sashiko-bot
2026-10-09 10:48 ` [PATCH bpf-next v3 48/51] selftests/bpf: tests for varying offset access to PTR_TO_BTF_ID Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 10:48 ` [PATCH bpf-next v3 49/51] selftests/bpf: tests for loop hierarchy computation Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 50/51] selftests/bpf: tests for immediate dominator computation Eduard Zingerman
2026-10-09 10:48 ` [PATCH bpf-next v3 51/51] selftests/bpf: tests for SCEV analysis and loop widening Eduard Zingerman
2026-10-09 12:07   ` bot+bpf-ci
2026-10-09 20:40 ` [PATCH bpf-next v3 00/51] bpf: use scalar evolution to widen bounded loops patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=faf14259573df35d2fc49a8445be5cd79a0a8565.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bot+bpf-ci@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=ihor.solodrai@linux.dev \
    --cc=kernel-team@fb.com \
    --cc=martin.lau@kernel.org \
    --cc=mason@kernel.org \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.