From 9a26fa6fb1e07ae9f57985a98665d82802b2e163 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Thu, 25 Oct 2018 23:22:20 -0400 Subject: [PATCH] radix tree test suite: Convert regression3 to XArray Move the test to the in-kernel test suite Signed-off-by: Matthew Wilcox --- lib/test_xarray.c | 66 +++++++++++++++++- tools/testing/radix-tree/Makefile | 3 +- tools/testing/radix-tree/main.c | 1 - tools/testing/radix-tree/regression.h | 1 - tools/testing/radix-tree/regression3.c | 95 -------------------------- 5 files changed, 66 insertions(+), 100 deletions(-) delete mode 100644 tools/testing/radix-tree/regression3.c diff --git a/lib/test_xarray.c b/lib/test_xarray.c index 9d631a7b6a70..75797cfcf7ca 100644 --- a/lib/test_xarray.c +++ b/lib/test_xarray.c @@ -95,7 +95,7 @@ static noinline void check_xa_err(struct xarray *xa) // XA_BUG_ON(xa, xa_err(xa_store(xa, 0, xa_mk_internal(0), 0)) != -EINVAL); } -static noinline void check_xas_retry(struct xarray *xa) +static noinline void check_xas_retry_1(struct xarray *xa) { XA_STATE(xas, xa, 0); void *entry; @@ -140,6 +140,70 @@ static noinline void check_xas_retry(struct xarray *xa) xa_erase_index(xa, 1); } +static noinline void check_xas_retry_2(struct xarray *xa) +{ + XA_STATE(xas, xa, 0); + void *entry; + bool first; + + xa_store_index(xa, 0, GFP_KERNEL); + xa_set_mark(xa, 0, XA_MARK_0); + + first = true; + rcu_read_lock(); + xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) { + if (first) { + xa_store_index(xa, 1, GFP_KERNEL); + xa_set_mark(xa, 1, XA_MARK_0); + first = false; + } + if (xas_retry(&xas, entry)) + continue; + } + rcu_read_unlock(); + xa_erase_index(xa, 1); + + first = true; + xas_set(&xas, 0); + rcu_read_lock(); + xas_for_each(&xas, entry, ULONG_MAX) { + if (xas_retry(&xas, entry)) + continue; + if (first) { + xa_store_index(xa, 1, GFP_KERNEL); + first = false; + } + } + rcu_read_unlock(); + + xas_set(&xas, 0); + rcu_read_lock(); + xas_for_each(&xas, entry, ULONG_MAX) { + if (xas.xa_index == 0) + xas_pause(&xas); + } + rcu_read_unlock(); + + xa_set_mark(xa, 0, XA_MARK_0); + xa_set_mark(xa, 1, XA_MARK_0); + xas_set(&xas, 0); + rcu_read_lock(); + xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_0) { + if (xas.xa_index == 0) + xas_pause(&xas); + } + rcu_read_unlock(); + + xa_erase_index(xa, 0); + xa_erase_index(xa, 1); +} + +static noinline void check_xas_retry(struct xarray *xa) +{ + check_xas_retry_1(xa); + check_xas_retry_2(xa); +} + static noinline void check_xa_load(struct xarray *xa) { unsigned long i, j; diff --git a/tools/testing/radix-tree/Makefile b/tools/testing/radix-tree/Makefile index 397d6b612502..b26f0494dc82 100644 --- a/tools/testing/radix-tree/Makefile +++ b/tools/testing/radix-tree/Makefile @@ -6,8 +6,7 @@ LDFLAGS += -fsanitize=address -fsanitize=undefined LDLIBS+= -lpthread -lurcu TARGETS = main idr-test multiorder xarray CORE_OFILES := xarray.o radix-tree.o idr.o linux.o test.o find_bit.o bitmap.o -OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression3.o \ - regression4.o \ +OFILES = main.o $(CORE_OFILES) regression1.o regression2.o regression4.o \ tag_check.o multiorder.o idr-test.o iteration_check.o benchmark.o ifndef SHIFT diff --git a/tools/testing/radix-tree/main.c b/tools/testing/radix-tree/main.c index 7a22d6e3732e..83773c5e89f8 100644 --- a/tools/testing/radix-tree/main.c +++ b/tools/testing/radix-tree/main.c @@ -307,7 +307,6 @@ int main(int argc, char **argv) xarray_tests(); regression1_test(); regression2_test(); - regression3_test(); regression4_test(); iteration_test(0, 10 + 90 * long_run); iteration_test(7, 10 + 90 * long_run); diff --git a/tools/testing/radix-tree/regression.h b/tools/testing/radix-tree/regression.h index 135145af18b7..387d7349d15d 100644 --- a/tools/testing/radix-tree/regression.h +++ b/tools/testing/radix-tree/regression.h @@ -4,7 +4,6 @@ void regression1_test(void); void regression2_test(void); -void regression3_test(void); void regression4_test(void); #endif diff --git a/tools/testing/radix-tree/regression3.c b/tools/testing/radix-tree/regression3.c deleted file mode 100644 index 9f9a3b280f56..000000000000 --- a/tools/testing/radix-tree/regression3.c +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Regression3 - * Description: - * Helper radix_tree_iter_retry resets next_index to the current index. - * In following radix_tree_next_slot current chunk size becomes zero. - * This isn't checked and it tries to dereference null pointer in slot. - * - * Helper radix_tree_iter_resume reset slot to NULL and next_index to index + 1, - * for tagger iteraction it also must reset cached tags in iterator to abort - * next radix_tree_next_slot and go to slow-path into radix_tree_next_chunk. - * - * Running: - * This test should run to completion immediately. The above bug would - * cause it to segfault. - * - * Upstream commit: - * Not yet - */ -#include -#include -#include -#include -#include -#include - -#include "regression.h" - -void regression3_test(void) -{ - RADIX_TREE(root, GFP_KERNEL); - void *ptr0 = (void *)4ul; - void *ptr = (void *)8ul; - struct radix_tree_iter iter; - void **slot; - bool first; - - printv(1, "running regression test 3 (should take milliseconds)\n"); - - radix_tree_insert(&root, 0, ptr0); - radix_tree_tag_set(&root, 0, 0); - - first = true; - radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { - printv(2, "tagged %ld %p\n", iter.index, *slot); - if (first) { - radix_tree_insert(&root, 1, ptr); - radix_tree_tag_set(&root, 1, 0); - first = false; - } - if (radix_tree_deref_retry(*slot)) { - printv(2, "retry at %ld\n", iter.index); - slot = radix_tree_iter_retry(&iter); - continue; - } - } - radix_tree_delete(&root, 1); - - first = true; - radix_tree_for_each_slot(slot, &root, &iter, 0) { - printv(2, "slot %ld %p\n", iter.index, *slot); - if (first) { - radix_tree_insert(&root, 1, ptr); - first = false; - } - if (radix_tree_deref_retry(*slot)) { - printv(2, "retry at %ld\n", iter.index); - slot = radix_tree_iter_retry(&iter); - continue; - } - } - - radix_tree_for_each_slot(slot, &root, &iter, 0) { - printv(2, "slot %ld %p\n", iter.index, *slot); - if (!iter.index) { - printv(2, "next at %ld\n", iter.index); - slot = radix_tree_iter_resume(slot, &iter); - } - } - - radix_tree_tag_set(&root, 0, 0); - radix_tree_tag_set(&root, 1, 0); - radix_tree_for_each_tagged(slot, &root, &iter, 0, 0) { - printv(2, "tagged %ld %p\n", iter.index, *slot); - if (!iter.index) { - printv(2, "next at %ld\n", iter.index); - slot = radix_tree_iter_resume(slot, &iter); - } - } - - radix_tree_delete(&root, 0); - radix_tree_delete(&root, 1); - - printv(1, "regression test 3 passed\n"); -} -- 2.51.0