summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2026-03-13 19:09:35 -0700
committerAlexei Starovoitov <ast@kernel.org>2026-03-13 19:09:35 -0700
commitbb41fcef5c7932e61ce87f573497ab0472cfe496 (patch)
tree631e074d556a9837683969324576bd03987428c3 /kernel
parent2af3aa702c05ecd05850db9d9e110be9ffa3cf47 (diff)
parent0a753d8cd61e31cc438a4fc414cc01655d3f3b72 (diff)
downloadlinux-bb41fcef5c7932e61ce87f573497ab0472cfe496.tar.gz
linux-bb41fcef5c7932e61ce87f573497ab0472cfe496.zip
Merge branch 'optimize-bounds-refinement-by-reordering-deductions'
Paul Chaignon says: ==================== Optimize bounds refinement by reordering deductions This patchset optimizes the bounds refinement (reg_bounds_sync) by reordering deductions in __reg_deduce_bounds. This reordering allows us to improve precision slightly while losing one call to __reg_deduce_bounds. The first patch from Eduard refactors the __reg_deduce_bounds subfunctions, the second patch implements the reordering, and the last one adds a selftest. Changes in v3: - Added first commit from Eduard that significantly helps with readability of second commit. - Reshuffled a bit more the functions in the second commit to improve precision (Eduard). - Rebased. Changes in v2: - Updated description to mention potential precision improvement and to clarify the sequence of refinements (Shung-Hsi). - Added the second patch. - Rebased. ==================== Link: https://patch.msgid.link/cover.1773401138.git.paul.chaignon@gmail.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/bpf/verifier.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 4fbacd2149cd..e29f15419fcb 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -2448,7 +2448,7 @@ static void __update_reg_bounds(struct bpf_reg_state *reg)
}
/* Uses signed min/max values to inform unsigned, and vice-versa */
-static void __reg32_deduce_bounds(struct bpf_reg_state *reg)
+static void deduce_bounds_32_from_64(struct bpf_reg_state *reg)
{
/* If upper 32 bits of u64/s64 range don't change, we can use lower 32
* bits to improve our u32/s32 boundaries.
@@ -2518,6 +2518,10 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg)
reg->s32_min_value = max_t(s32, reg->s32_min_value, (s32)reg->smin_value);
reg->s32_max_value = min_t(s32, reg->s32_max_value, (s32)reg->smax_value);
}
+}
+
+static void deduce_bounds_32_from_32(struct bpf_reg_state *reg)
+{
/* if u32 range forms a valid s32 range (due to matching sign bit),
* try to learn from that
*/
@@ -2559,7 +2563,7 @@ static void __reg32_deduce_bounds(struct bpf_reg_state *reg)
}
}
-static void __reg64_deduce_bounds(struct bpf_reg_state *reg)
+static void deduce_bounds_64_from_64(struct bpf_reg_state *reg)
{
/* If u64 range forms a valid s64 range (due to matching sign bit),
* try to learn from that. Let's do a bit of ASCII art to see when
@@ -2694,7 +2698,7 @@ static void __reg64_deduce_bounds(struct bpf_reg_state *reg)
}
}
-static void __reg_deduce_mixed_bounds(struct bpf_reg_state *reg)
+static void deduce_bounds_64_from_32(struct bpf_reg_state *reg)
{
/* Try to tighten 64-bit bounds from 32-bit knowledge, using 32-bit
* values on both sides of 64-bit range in hope to have tighter range.
@@ -2763,9 +2767,10 @@ static void __reg_deduce_mixed_bounds(struct bpf_reg_state *reg)
static void __reg_deduce_bounds(struct bpf_reg_state *reg)
{
- __reg32_deduce_bounds(reg);
- __reg64_deduce_bounds(reg);
- __reg_deduce_mixed_bounds(reg);
+ deduce_bounds_64_from_64(reg);
+ deduce_bounds_32_from_64(reg);
+ deduce_bounds_32_from_32(reg);
+ deduce_bounds_64_from_32(reg);
}
/* Attempts to improve var_off based on unsigned min/max information */
@@ -2788,7 +2793,6 @@ static void reg_bounds_sync(struct bpf_reg_state *reg)
/* We might have learned something about the sign bit. */
__reg_deduce_bounds(reg);
__reg_deduce_bounds(reg);
- __reg_deduce_bounds(reg);
/* We might have learned some bits from the bounds. */
__reg_bound_offset(reg);
/* Intersecting with the old var_off might have improved our bounds