aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/tools/testing/selftests/bpf/prog_tests
diff options
context:
space:
mode:
authorAlexei Starovoitov <ast@kernel.org>2025-04-25 08:36:59 -0700
committerAlexei Starovoitov <ast@kernel.org>2025-04-25 08:37:21 -0700
commit6ae003adc029c74e7f97cc65dc1e79109a1f2d67 (patch)
tree4c40aabec804482096aa1993ebb93a92ebc74d64 /tools/testing/selftests/bpf/prog_tests
parentselftests/bpf: Mitigate sockmap_ktls disconnect_after_delete failure (diff)
parentselftests/bpf: add test for softlock when modifying hashmap while iterating (diff)
downloadwireguard-linux-6ae003adc029c74e7f97cc65dc1e79109a1f2d67.tar.xz
wireguard-linux-6ae003adc029c74e7f97cc65dc1e79109a1f2d67.zip
Merge branch 'bpf-fix-softlock-condition-in-bpf-hashmap-interation'
Brandon Kammerdiener says: ==================== This patchset fixes an endless loop condition that can occur in bpf_for_each_hash_elem, causing the core to softlock. My understanding is that a combination of RCU list deletion and insertion introduces the new element after the iteration cursor and that there is a chance that an RCU reader may in fact use this new element in iteration. The patch uses a _safe variant of the macro which gets the next element to iterate before executing the loop body for the current element. I have also added a subtest in the for_each selftest that can trigger this condition without the fix. Changes since v2: - Renaming and additional checks in selftests/bpf/prog_tests/for_each.c Changes since v1: - Added missing Signed-off-by lines to both patches ==================== Acked-by: Hou Tao <houtao1@huawei.com> Link: https://patch.msgid.link/20250424153246.141677-1-brandon.kammerdiener@intel.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Diffstat (limited to 'tools/testing/selftests/bpf/prog_tests')
-rw-r--r--tools/testing/selftests/bpf/prog_tests/for_each.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/prog_tests/for_each.c b/tools/testing/selftests/bpf/prog_tests/for_each.c
index 09f6487f58b9..5fea3209566e 100644
--- a/tools/testing/selftests/bpf/prog_tests/for_each.c
+++ b/tools/testing/selftests/bpf/prog_tests/for_each.c
@@ -6,6 +6,7 @@
#include "for_each_array_map_elem.skel.h"
#include "for_each_map_elem_write_key.skel.h"
#include "for_each_multi_maps.skel.h"
+#include "for_each_hash_modify.skel.h"
static unsigned int duration;
@@ -203,6 +204,40 @@ out:
for_each_multi_maps__destroy(skel);
}
+static void test_hash_modify(void)
+{
+ struct for_each_hash_modify *skel;
+ int max_entries, i, err;
+ __u64 key, val;
+
+ LIBBPF_OPTS(bpf_test_run_opts, topts,
+ .data_in = &pkt_v4,
+ .data_size_in = sizeof(pkt_v4),
+ .repeat = 1
+ );
+
+ skel = for_each_hash_modify__open_and_load();
+ if (!ASSERT_OK_PTR(skel, "for_each_hash_modify__open_and_load"))
+ return;
+
+ max_entries = bpf_map__max_entries(skel->maps.hashmap);
+ for (i = 0; i < max_entries; i++) {
+ key = i;
+ val = i;
+ err = bpf_map__update_elem(skel->maps.hashmap, &key, sizeof(key),
+ &val, sizeof(val), BPF_ANY);
+ if (!ASSERT_OK(err, "map_update"))
+ goto out;
+ }
+
+ err = bpf_prog_test_run_opts(bpf_program__fd(skel->progs.test_pkt_access), &topts);
+ ASSERT_OK(err, "bpf_prog_test_run_opts");
+ ASSERT_OK(topts.retval, "retval");
+
+out:
+ for_each_hash_modify__destroy(skel);
+}
+
void test_for_each(void)
{
if (test__start_subtest("hash_map"))
@@ -213,4 +248,6 @@ void test_for_each(void)
test_write_map_key();
if (test__start_subtest("multi_maps"))
test_multi_maps();
+ if (test__start_subtest("hash_modify"))
+ test_hash_modify();
}