Re: [PATCH bpf-next v4 4/6] bpf: Inline bpf_iter_num_destroy() as a no-op
Andrii Nakryiko <[email protected]>
| Newsgroups | org.kernel.vger.bpf |
|---|---|
| Message-ID | <CAEf4BzYuQxx2Oa8hhqhmaP1FAFcamNW_QHRwxGv_GXKHpdvXgg@mail.gmail.com> |
On Wed, Jul 29, 2026 at 1:37 PM Puranjay Mohan <[email protected]> wrote: > > bpf_iter_num_destroy() ends every bpf_for() loop. The kfunc only zeroed > the 8-byte on-stack iterator state, but once destroy() returns that slot > is no longer tracked as iterator state, so nothing reads it and the > zeroing is dead work. > > Drop it on both sides: make the bpf_iter_num_destroy() kfunc a no-op, and > inline the call in bpf_fixup_kfunc_call() to a single BPF_JA 0 (nop) so > the per-loop call is removed without emitting any store. The nop is > elided by the JITs. > > The emitted instruction is plain BPF and is handled by the interpreter, > so interpreter fallback stays correct and no jit_required marking is > needed. > > Suggested-by: Andrii Nakryiko <[email protected]> > Signed-off-by: Puranjay Mohan <[email protected]> > --- > kernel/bpf/bpf_iter.c | 8 +++++--- > kernel/bpf/verifier.c | 14 ++++++++++++++ > 2 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c > index f190f2b250048..ff2055399f3c0 100644 > --- a/kernel/bpf/bpf_iter.c > +++ b/kernel/bpf/bpf_iter.c > @@ -821,9 +821,11 @@ __bpf_kfunc int *bpf_iter_num_next(struct bpf_iter_num* it) > > __bpf_kfunc void bpf_iter_num_destroy(struct bpf_iter_num *it) > { > - struct bpf_iter_num_kern *s = (void *)it; > - > - s->cur = s->end = 0; > + /* > + * Nothing to do: the stack slot backing the iterator is no longer > + * tracked as iterator state once destroy() returns, so its contents do > + * not matter. The verifier inlines this call away entirely. > + */ verbose, drop the comment or have /* no-op */ > } > > __bpf_kfunc_end_defs(); > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 3a3d096f3966e..36f3e80d2f0b9 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -19838,6 +19838,18 @@ static int inline_bpf_iter_num_next(struct bpf_insn *insn_buf) > return i; > } > > +/* > + * Inline bpf_iter_num_destroy(). The stack slot is no longer tracked as iterator state after > + * destroy(), so nothing has to be done to it; emit a nop just to drop the call. Keep in sync > + * with the kfunc in kernel/bpf/bpf_iter.c. > + */ > +static int inline_bpf_iter_num_destroy(struct bpf_insn *insn_buf) > +{ > + insn_buf[0] = BPF_JMP_A(0); > + > + return 1; > +} again, inline the inlining logic also, bpf_patch_insn_single doesn't support deleting an instruction, we have to have BPF_JMP_A? > + > int bpf_fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, > struct bpf_insn *insn_buf, int insn_idx, int *cnt) > { > @@ -19971,6 +19983,8 @@ int bpf_fixup_kfunc_call(struct bpf_verifier_env *env, struct bpf_insn *insn, > *cnt = inline_bpf_iter_num_new(insn_buf); > } else if (desc->func_id == special_kfunc_list[KF_bpf_iter_num_next]) { > *cnt = inline_bpf_iter_num_next(insn_buf); > + } else if (desc->func_id == special_kfunc_list[KF_bpf_iter_num_destroy]) { > + *cnt = inline_bpf_iter_num_destroy(insn_buf); > } > > if (env->insn_aux_data[insn_idx].arg_prog) { > -- > 2.53.0-Meta >