From: Eduard Zingerman <eddyz87@gmail.com>
To: bpf@vger.kernel.org, ast@kernel.org, andrii@kernel.org
Cc: daniel@iogearbox.net, martin.lau@linux.dev, kernel-team@fb.com,
yonghong.song@linux.dev, eddyz87@gmail.com
Subject: [PATCH bpf-next v2 06/13] bpf: prepare bpf_liveness api for use by static analysis pass
Date: Thu, 9 Apr 2026 18:11:25 -0700 [thread overview]
Message-ID: <20260409-patch-set-v2-6-651804512349@gmail.com> (raw)
In-Reply-To: <20260409-patch-set-v2-0-651804512349@gmail.com>
bpf: prepare liveness internal API for static analysis pass
Move the `updated` check and reset from bpf_update_live_stack() into
update_instance() itself, so callers outside the main loop can reuse
it. Similarly, move write_insn_idx assignment out of
reset_stack_write_marks() into its public caller, and thread insn_idx
as a parameter to commit_stack_write_marks() instead of reading it
from liveness->write_insn_idx. Drop the unused `env` parameter from
alloc_frame_masks() and mark_stack_read().
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
---
kernel/bpf/liveness.c | 48 +++++++++++++++++++++++-------------------------
1 file changed, 23 insertions(+), 25 deletions(-)
diff --git a/kernel/bpf/liveness.c b/kernel/bpf/liveness.c
index e2697cd9ae27..a3af5972520f 100644
--- a/kernel/bpf/liveness.c
+++ b/kernel/bpf/liveness.c
@@ -259,8 +259,7 @@ static struct per_frame_masks *get_frame_masks(struct func_instance *instance,
return &instance->frames[frame][relative_idx(instance, insn_idx)];
}
-static struct per_frame_masks *alloc_frame_masks(struct bpf_verifier_env *env,
- struct func_instance *instance,
+static struct per_frame_masks *alloc_frame_masks(struct func_instance *instance,
u32 frame, u32 insn_idx)
{
struct per_frame_masks *arr;
@@ -298,13 +297,12 @@ static int ensure_cur_instance(struct bpf_verifier_env *env)
}
/* Accumulate may_read masks for @frame at @insn_idx */
-static int mark_stack_read(struct bpf_verifier_env *env,
- struct func_instance *instance, u32 frame, u32 insn_idx, spis_t mask)
+static int mark_stack_read(struct func_instance *instance, u32 frame, u32 insn_idx, spis_t mask)
{
struct per_frame_masks *masks;
spis_t new_may_read;
- masks = alloc_frame_masks(env, instance, frame, insn_idx);
+ masks = alloc_frame_masks(instance, frame, insn_idx);
if (IS_ERR(masks))
return PTR_ERR(masks);
new_may_read = spis_or(masks->may_read, mask);
@@ -321,17 +319,15 @@ int bpf_mark_stack_read(struct bpf_verifier_env *env, u32 frame, u32 insn_idx, s
int err;
err = ensure_cur_instance(env);
- err = err ?: mark_stack_read(env, env->liveness->cur_instance, frame, insn_idx, mask);
+ err = err ?: mark_stack_read(env->liveness->cur_instance, frame, insn_idx, mask);
return err;
}
-static void reset_stack_write_marks(struct bpf_verifier_env *env,
- struct func_instance *instance, u32 insn_idx)
+static void reset_stack_write_marks(struct bpf_verifier_env *env, struct func_instance *instance)
{
struct bpf_liveness *liveness = env->liveness;
int i;
- liveness->write_insn_idx = insn_idx;
for (i = 0; i <= instance->callchain.curframe; i++)
liveness->write_masks_acc[i] = SPIS_ZERO;
}
@@ -345,7 +341,8 @@ int bpf_reset_stack_write_marks(struct bpf_verifier_env *env, u32 insn_idx)
if (err)
return err;
- reset_stack_write_marks(env, liveness->cur_instance, insn_idx);
+ liveness->write_insn_idx = insn_idx;
+ reset_stack_write_marks(env, liveness->cur_instance);
return 0;
}
@@ -355,7 +352,8 @@ void bpf_mark_stack_write(struct bpf_verifier_env *env, u32 frame, spis_t mask)
}
static int commit_stack_write_marks(struct bpf_verifier_env *env,
- struct func_instance *instance)
+ struct func_instance *instance,
+ u32 insn_idx)
{
struct bpf_liveness *liveness = env->liveness;
u32 idx, frame, curframe;
@@ -366,13 +364,13 @@ static int commit_stack_write_marks(struct bpf_verifier_env *env,
return 0;
curframe = instance->callchain.curframe;
- idx = relative_idx(instance, liveness->write_insn_idx);
+ idx = relative_idx(instance, insn_idx);
for (frame = 0; frame <= curframe; frame++) {
mask = liveness->write_masks_acc[frame];
/* avoid allocating frames for zero masks */
if (spis_is_zero(mask) && !instance->must_write_set[idx])
continue;
- masks = alloc_frame_masks(env, instance, frame, liveness->write_insn_idx);
+ masks = alloc_frame_masks(instance, frame, insn_idx);
if (IS_ERR(masks))
return PTR_ERR(masks);
old_must_write = masks->must_write;
@@ -402,7 +400,7 @@ static int commit_stack_write_marks(struct bpf_verifier_env *env,
*/
int bpf_commit_stack_write_marks(struct bpf_verifier_env *env)
{
- return commit_stack_write_marks(env, env->liveness->cur_instance);
+ return commit_stack_write_marks(env, env->liveness->cur_instance, env->liveness->write_insn_idx);
}
static char *fmt_callchain(struct bpf_verifier_env *env, struct callchain *callchain)
@@ -576,18 +574,17 @@ static int propagate_to_outer_instance(struct bpf_verifier_env *env,
if (IS_ERR(outer_instance))
return PTR_ERR(outer_instance);
callsite = callchain->callsites[callchain->curframe - 1];
-
- reset_stack_write_marks(env, outer_instance, callsite);
+ reset_stack_write_marks(env, outer_instance);
for (frame = 0; frame < callchain->curframe; frame++) {
insn = get_frame_masks(instance, frame, this_subprog_start);
if (!insn)
continue;
bpf_mark_stack_write(env, frame, insn->must_write_acc);
- err = mark_stack_read(env, outer_instance, frame, callsite, insn->live_before);
+ err = mark_stack_read(outer_instance, frame, callsite, insn->live_before);
if (err)
return err;
}
- commit_stack_write_marks(env, outer_instance);
+ commit_stack_write_marks(env, outer_instance, callsite);
return 0;
}
@@ -654,6 +651,9 @@ static int update_instance(struct bpf_verifier_env *env, struct func_instance *i
bool changed;
int err;
+ if (!instance->updated)
+ return 0;
+
this_subprog_start = callchain_subprog_start(callchain);
/*
* If must_write marks were updated must_write_acc needs to be reset
@@ -699,6 +699,8 @@ static int update_instance(struct bpf_verifier_env *env, struct func_instance *i
return err;
}
+ instance->updated = false;
+ instance->must_write_dropped = false;
return 0;
}
@@ -721,13 +723,9 @@ int bpf_update_live_stack(struct bpf_verifier_env *env)
if (IS_ERR(instance))
return PTR_ERR(instance);
- if (instance->updated) {
- err = update_instance(env, instance);
- if (err)
- return err;
- instance->updated = false;
- instance->must_write_dropped = false;
- }
+ err = update_instance(env, instance);
+ if (err)
+ return err;
}
return 0;
}
--
2.53.0
next prev parent reply other threads:[~2026-04-10 1:11 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-10 1:11 [PATCH bpf-next v2 00/13] bpf: static stack liveness data flow analysis Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 01/13] bpf: share several utility functions as internal API Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 02/13] bpf: save subprogram name in bpf_subprog_info Eduard Zingerman
2026-04-10 1:50 ` bot+bpf-ci
2026-04-10 4:04 ` Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 03/13] bpf: Add spis_*() helpers for 4-byte stack slot bitmasks Eduard Zingerman
2026-04-10 1:50 ` bot+bpf-ci
2026-04-10 4:05 ` Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 04/13] bpf: make liveness.c track stack with 4-byte granularity Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 05/13] bpf: 4-byte precise clean_verifier_state Eduard Zingerman
2026-04-10 1:11 ` Eduard Zingerman [this message]
2026-04-10 1:11 ` [PATCH bpf-next v2 07/13] bpf: introduce forward arg-tracking dataflow analysis Eduard Zingerman
2026-04-10 2:02 ` bot+bpf-ci
2026-04-10 1:11 ` [PATCH bpf-next v2 08/13] bpf: simplify liveness to use (callsite, depth) keyed func_instances Eduard Zingerman
2026-04-10 2:02 ` bot+bpf-ci
2026-04-10 1:11 ` [PATCH bpf-next v2 09/13] bpf: change logging scheme for live stack analysis Eduard Zingerman
2026-04-10 2:02 ` bot+bpf-ci
2026-04-10 4:06 ` Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 10/13] selftests/bpf: update existing tests due to liveness changes Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 11/13] selftests/bpf: adjust verifier_log buffers Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 12/13] selftests/bpf: add new tests for static stack liveness analysis Eduard Zingerman
2026-04-10 1:11 ` [PATCH bpf-next v2 13/13] bpf: poison dead stack slots Eduard Zingerman
2026-04-10 2:02 ` bot+bpf-ci
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=20260409-patch-set-v2-6-651804512349@gmail.com \
--to=eddyz87@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=kernel-team@fb.com \
--cc=martin.lau@linux.dev \
--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.