helper_fill_hashmap() is used also on parallel and stress map tests.
Those are consistently failing with ENOMEM on kernels built with
PREEMPT_RT if preallocation is disabled. The failure is transient and
only called by the memory cache refill running in a preemptible
irq_work, which can easily stall in case of contention.

Use a retriable update in those cases to handle transient ENOMEM and
make the test more stable also on PREEMPT_RT.
Also fix the sign of the value printed in case of error (strerror()
expects a positive errno while updates return it negative).

Signed-off-by: Gabriele Monaco <[email protected]>
---
 tools/testing/selftests/bpf/test_maps.c | 23 +++++++++++++----------
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/bpf/test_maps.c 
b/tools/testing/selftests/bpf/test_maps.c
index ccc5acd55f..c32da7bd8b 100644
--- a/tools/testing/selftests/bpf/test_maps.c
+++ b/tools/testing/selftests/bpf/test_maps.c
@@ -260,6 +260,16 @@ static void test_hashmap_percpu(unsigned int task, void 
*data)
        close(fd);
 }
 
+#define MAP_RETRIES 20
+
+static bool can_retry(int err)
+{
+       return (err == EAGAIN || err == EBUSY ||
+               ((err == ENOMEM || err == E2BIG) &&
+                map_opts.map_flags == BPF_F_NO_PREALLOC));
+}
+
+
 #define VALUE_SIZE 3
 static int helper_fill_hashmap(int max_entries)
 {
@@ -274,10 +284,11 @@ static int helper_fill_hashmap(int max_entries)
 
        for (i = 0; i < max_entries; i++) {
                key = i; value[0] = key;
-               ret = bpf_map_update_elem(fd, &key, value, BPF_NOEXIST);
+               ret = map_update_retriable(fd, &key, value, BPF_NOEXIST,
+                                          MAP_RETRIES, can_retry);
                CHECK(ret != 0,
                      "can't update hashmap",
-                     "err: %s\n", strerror(ret));
+                     "err: %s\n", strerror(-ret));
        }
 
        return fd;
@@ -1392,17 +1403,9 @@ static void test_map_stress(void)
 #define DO_UPDATE 1
 #define DO_DELETE 0
 
-#define MAP_RETRIES 20
 #define MAX_DELAY_US 50000
 #define MIN_DELAY_RANGE_US 5000
 
-static bool can_retry(int err)
-{
-       return (err == EAGAIN || err == EBUSY ||
-               ((err == ENOMEM || err == E2BIG) &&
-                map_opts.map_flags == BPF_F_NO_PREALLOC));
-}
-
 int map_update_retriable(int map_fd, const void *key, const void *value, int 
flags, int attempts,
                         retry_for_error_fn need_retry)
 {

base-commit: 2d3090a8aeb596a26935db0955d46c9a5db5c6ce
-- 
2.54.0


Reply via email to