From d9ccaa8ddbb76b17e7674d58a88feb9fcfa3bac5 Mon Sep 17 00:00:00 2001 From: Neil Horman Date: Mon, 25 Mar 2024 13:35:05 -0400 Subject: [PATCH] Add code to check wrapping --- test/threadstest.c | 42 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/test/threadstest.c b/test/threadstest.c index c27f51f85dcf0c..1f1972b129f49a 100644 --- a/test/threadstest.c +++ b/test/threadstest.c @@ -351,6 +351,9 @@ static void writer2_fn(void) CRYPTO_atomic_add(&writer2_done, 1, &local, NULL); } +#define NO_WRAP 0 +#define WRAPPED_LAST_ITER 1 +#define BETTER_NOT_WRAP 2 static void reader_fn(int *iterations) { unsigned int count = 0; @@ -360,6 +363,7 @@ static void reader_fn(int *iterations) int lw1 = 0; int lw2 = 0; size_t i; + int wrap = NO_WRAP; while (lw1 != 1 || lw2 != 1) { CRYPTO_atomic_add(&writer1_done, 0, &lw1, NULL); @@ -368,13 +372,39 @@ static void reader_fn(int *iterations) ossl_rcu_read_lock(rcu_lock); valp = ossl_rcu_deref(&writer_ptr); val = (valp == NULL) ? 0 : *valp; - if (oldval > val) { - TEST_info("rcu torture value went backwards! %llu : %llu", (unsigned long long)oldval, (unsigned long long)val); - TEST_info("val ptr is %p\n", (void*)valp); - for (i=0; i<256; i++) { - TEST_info("Old Addrs for write %zu\n is %p\n", i, old_addrs[i]); + + /* + * If we didn't wrap before, and we see a wrap + * condition, mark it as such + */ + if (oldval > val && wrap == NO_WRAP) { + wrap = WRAPPED_LAST_ITER; + } + + /* + * If this iteration wrapped, indicate that + * its ok, but we better not wrap again + */ + if (wrap == WRAPPED_LAST_ITER) { + wrap = BETTER_NOT_WRAP; + } else { + /* + * We get here if we've wrapped once, but we better not go + * backwards again + */ + if (oldval > val) { + TEST_info("rcu torture value went backwards! %llu : %llu", (unsigned long long)oldval, (unsigned long long)val); + TEST_info("val ptr is %p\n", (void*)valp); + for (i=0; i<256; i++) { + TEST_info("Old Addrs for write %zu\n is %p\n", i, old_addrs[i]); + } + rcu_torture_result = 0; + } else { + /* + * If we get here, we've successfully wrapped, and can continue + */ + wrap = NO_WRAP; } - rcu_torture_result = 0; } oldval = val; /* just try to deref the pointer */ ossl_rcu_read_unlock(rcu_lock);