Each uffd read threads unlocks the read mutex first, probably just to make sure the thread is reaching a stage where pthread_cancel() can always work before the main thread moves on. However keeping the mutex locked always and unlock in the thread is a bit hacky. Replacing it with a semaphore which should be much clearer, where the main thread will wait() and the thread will just post(). Move it to uffd-common.* to be reused later. Signed-off-by: Peter Xu <peterx@xxxxxxxxxx> --- tools/testing/selftests/mm/uffd-common.c | 1 + tools/testing/selftests/mm/uffd-common.h | 2 ++ tools/testing/selftests/mm/uffd-stress.c | 8 +++----- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/testing/selftests/mm/uffd-common.c b/tools/testing/selftests/mm/uffd-common.c index 02b89860e193..aded06cab285 100644 --- a/tools/testing/selftests/mm/uffd-common.c +++ b/tools/testing/selftests/mm/uffd-common.c @@ -17,6 +17,7 @@ bool map_shared; bool test_uffdio_wp = true; unsigned long long *count_verify; uffd_test_ops_t *uffd_test_ops; +sem_t uffd_read_sem; static int uffd_mem_fd_create(off_t mem_size, bool hugetlb) { diff --git a/tools/testing/selftests/mm/uffd-common.h b/tools/testing/selftests/mm/uffd-common.h index 7c4fa964c3b0..521523baded1 100644 --- a/tools/testing/selftests/mm/uffd-common.h +++ b/tools/testing/selftests/mm/uffd-common.h @@ -32,6 +32,7 @@ #include <inttypes.h> #include <stdint.h> #include <sys/random.h> +#include <semaphore.h> #include "../kselftest.h" #include "vm_util.h" @@ -97,6 +98,7 @@ extern bool map_shared; extern bool test_uffdio_wp; extern unsigned long long *count_verify; extern volatile bool test_uffdio_copy_eexist; +extern sem_t uffd_read_sem; extern uffd_test_ops_t anon_uffd_test_ops; extern uffd_test_ops_t shmem_uffd_test_ops; diff --git a/tools/testing/selftests/mm/uffd-stress.c b/tools/testing/selftests/mm/uffd-stress.c index 469e0476af26..7219f55ae794 100644 --- a/tools/testing/selftests/mm/uffd-stress.c +++ b/tools/testing/selftests/mm/uffd-stress.c @@ -125,14 +125,12 @@ static int copy_page_retry(int ufd, unsigned long offset) return __copy_page(ufd, offset, true, test_uffdio_wp); } -pthread_mutex_t uffd_read_mutex = PTHREAD_MUTEX_INITIALIZER; - static void *uffd_read_thread(void *arg) { struct uffd_args *args = (struct uffd_args *)arg; struct uffd_msg msg; - pthread_mutex_unlock(&uffd_read_mutex); + sem_post(&uffd_read_sem); /* from here cancellation is ok */ for (;;) { @@ -196,7 +194,7 @@ static int stress(struct uffd_args *args) uffd_read_thread, (void *)&args[cpu])) return 1; - pthread_mutex_lock(&uffd_read_mutex); + sem_wait(&uffd_read_sem); } if (pthread_create(&background_threads[cpu], &attr, background_thread, (void *)cpu)) @@ -258,7 +256,7 @@ static int userfaultfd_stress(void) zeropage = area; bzero(zeropage, page_size); - pthread_mutex_lock(&uffd_read_mutex); + sem_init(&uffd_read_sem, 0, 0); pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 16*1024*1024); -- 2.41.0