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
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.