]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
bpf: do not update state->loop_entry in get_loop_entry()
authorEduard Zingerman <eddyz87@gmail.com>
Sat, 15 Feb 2025 11:03:58 +0000 (03:03 -0800)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 19 Feb 2025 03:22:59 +0000 (19:22 -0800)
The patch 9 is simpler if less places modify loop_entry field.
The loop deleted by this patch does not affect correctness, but is a
performance optimization. However, measurements on selftests and
sched_ext programs show that this optimization is unnecessary:
- at most 2 steps are done in get_loop_entry();
- most of the time 0 or 1 steps are done in get_loop_entry().

Measured using "do-not-submit" patches from here:
https://github.com/eddyz87/bpf/tree/get-loop-entry-hungup

Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20250215110411.3236773-8-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/verifier.c

index cb5ae7dc6488f738f18dbd421076bbfde2cd9940..e6ed71e053b7f13afc0962b6b314f726d5c2287a 100644 (file)
@@ -1829,13 +1829,12 @@ static bool same_callsites(struct bpf_verifier_state *a, struct bpf_verifier_sta
  *   and cur's loop entry has to be updated (case A), handle this in
  *   update_branch_counts();
  * - use st->branch > 0 as a signal that st is in the current DFS path;
- * - handle cases B and C in is_state_visited();
- * - update topmost loop entry for intermediate states in get_loop_entry().
+ * - handle cases B and C in is_state_visited().
  */
 static struct bpf_verifier_state *get_loop_entry(struct bpf_verifier_env *env,
                                                 struct bpf_verifier_state *st)
 {
-       struct bpf_verifier_state *topmost = st->loop_entry, *old;
+       struct bpf_verifier_state *topmost = st->loop_entry;
        u32 steps = 0;
 
        while (topmost && topmost->loop_entry) {
@@ -1846,14 +1845,6 @@ static struct bpf_verifier_state *get_loop_entry(struct bpf_verifier_env *env,
                }
                topmost = topmost->loop_entry;
        }
-       /* Update loop entries for intermediate states to avoid this
-        * traversal in future get_loop_entry() calls.
-        */
-       while (st && st->loop_entry != topmost) {
-               old = st->loop_entry;
-               st->loop_entry = topmost;
-               st = old;
-       }
        return topmost;
 }