[Devel] [PATCH hci-8.1 v3 1/1] selftests: bpf: size the map in test_lru_sanity3 to whole refills

Konstantin Khorenko khorenko at virtuozzo.com
Fri Sep 25 20:16:27 MSK 2026


On 9/25/26 17:27, Eva Kurchatova wrote:
> test_lru_sanity3 fills a map of tgt_free * 2 elements, and then reads
> back all but the last few. Whether that passes depends on the cpu
> count alone; on a machine with six it does not:
> 
>   test_lru_sanity3 (map_type:9 map_flags:0x0): test_lru_map.c:463:
>   test_lru_sanity3: Assertion `!bpf_map_lookup_elem_with_ref_bit(
>   lru_map_fd, key, value)' failed.
> 
> The kernel hands elements out in refills of lru->target_free, which is
> clamp((size / nr_cpus) / 2, 1, LOCAL_FREE_TARGET), that is 128 / nr_cpus
> rounded down. A refill the global free list cannot satisfy in full
> calls __bpf_lru_list_shrink() for the remainder, and that evicts live
> elements. Filling the map therefore evicts nothing only when computed
> 128 / nr_cpus is a power of two. Any other nr_cpus variation fails.
> 
> batch_size is already __tgt_size(tgt_free), the refill size of a map
> is __map_size(batch_size) elements, so size the map that way and the
> fill consumes whole refills. Start the keys of the last insert at
> map_size + 1, just past the new size.
> 
> Above 128 cpus __tgt_size(tgt_free) is 0 and there is no size to build
> on. Skip the test there.

  One inaccuracy in the commit message.

  The message says the skip kicks in above 128 cpus. It actually kicks in above 64. The skip fires when __tgt_size(128) =
  (128 / nr_cpus) / 2 reaches zero, and that happens already at 65 cpus: 128 / 65 = 1, then 1 / 2 = 0.

  I think 128 comes from the old map. For the 256-element map the kernel computes target_free as roughly 128 / nr_cpus, and
  that reaches zero only past 128 cpus. But the skip is driven by the test's batch_size, which is roughly 64 / nr_cpus,
  twice smaller.

  The code is fine as is, it tests batch_size == 0 directly. Only the number in the sentence needs fixing, and the same
  "above 128 cpus" appears in the v3 changelog of the cover letter. While at it, the cover letter says "Patchset for tast",
  should be "task".

> 
> Fixes: 5e9388f7984a ("selftests/bpf: adapt one more case in test_lru_map to the new target_free")
> 
> https://virtuozzo.atlassian.net/browse/VSTOR-139677
> Feature: fix selftests
> 
> Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>
> ---
>  tools/testing/selftests/bpf/test_lru_map.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/tools/testing/selftests/bpf/test_lru_map.c b/tools/testing/selftests/bpf/test_lru_map.c
> index 0921939532c6..84e9a930471a 100644
> --- a/tools/testing/selftests/bpf/test_lru_map.c
> +++ b/tools/testing/selftests/bpf/test_lru_map.c
> @@ -441,8 +441,15 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
>  	assert(sched_next_online(0, &next_cpu) != -1);
>  
>  	batch_size = __tgt_size(tgt_free);
> +	if (!batch_size) {
> +		/* More cpus than this tgt_free gives a refill for */
> +		printf("Skip\n");
> +		return;
> +	}
> +
> +	/* A partial refill shrinks the LRU and evicts live elements */
> +	map_size = __map_size(batch_size);
>  
> -	map_size = tgt_free * 2;
>  	lru_map_fd = create_map(map_type, map_flags, map_size);
>  	assert(lru_map_fd != -1);
>  
> @@ -466,7 +473,7 @@ static void test_lru_sanity3(int map_type, int map_flags, unsigned int tgt_free)
>  	}
>  
>  	/* Insert new batch_size: replaces the non-referenced elements */
> -	key = 2 * tgt_free + 1;
> +	key = 1 + map_size;
>  	end_key = key + batch_size;
>  	for (; key < end_key; key++) {
>  		assert(!bpf_map_update_elem(lru_map_fd, &key, value,



More information about the Devel mailing list