Re: [patch 10/10] selftests/rseq: Expand for optimized RSEQ ABI v2
Dmitry Vyukov <[email protected]>
| Newsgroups | org.kernel.vger.linux-man,dev.linux.lists.regressions,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CACT4Y+ZVmKfHiMCSM6gbRXcc=n-cgCJWUGsxLmg-oV-HGXGMgg@mail.gmail.com> |
On Wed, 29 Apr 2026 at 01:34, Thomas Gleixner <[email protected]> wrote: > > Update the selftests so they are executed for legacy (32 bytes RSEQ region) > and optimized RSEQ ABI v2 mode. > > Fixes: d6200245c75e ("rseq: Allow registering RSEQ with slice extension") > Signed-off-by: Thomas Gleixner <[email protected]> > Cc: [email protected] Reviewed-by: Dmitry Vyukov <[email protected]> > --- > tools/testing/selftests/rseq/Makefile | 7 ++- > tools/testing/selftests/rseq/check_optimized.c | 17 +++++++++ > tools/testing/selftests/rseq/param_test.c | 22 +++++++---- > tools/testing/selftests/rseq/run_param_test.sh | 39 +++++++++++++++++++++ > tools/testing/selftests/rseq/run_timeslice_test.sh | 14 +++++++ > tools/testing/selftests/rseq/slice_test.c | 2 - > 6 files changed, 89 insertions(+), 12 deletions(-) > > --- a/tools/testing/selftests/rseq/Makefile > +++ b/tools/testing/selftests/rseq/Makefile > @@ -17,11 +17,11 @@ OVERRIDE_TARGETS = 1 > TEST_GEN_PROGS = basic_test basic_percpu_ops_test basic_percpu_ops_mm_cid_test param_test \ > param_test_benchmark param_test_compare_twice param_test_mm_cid \ > param_test_mm_cid_benchmark param_test_mm_cid_compare_twice \ > - syscall_errors_test slice_test legacy_check > + syscall_errors_test slice_test legacy_check check_optimized > > TEST_GEN_PROGS_EXTENDED = librseq.so > > -TEST_PROGS = run_param_test.sh run_syscall_errors_test.sh run_legacy_check.sh > +TEST_PROGS = run_param_test.sh run_syscall_errors_test.sh run_legacy_check.sh run_timeslice_test.sh > > TEST_FILES := settings > > @@ -62,3 +62,6 @@ include ../lib.mk > > $(OUTPUT)/slice_test: slice_test.c $(TEST_GEN_PROGS_EXTENDED) rseq.h rseq-*.h > $(CC) $(CFLAGS) $< $(LDLIBS) -lrseq -o $@ > + > +$(OUTPUT)/check_optimized: check_optimized.c $(TEST_GEN_PROGS_EXTENDED) rseq.h rseq-*.h > + $(CC) $(CFLAGS) $< $(LDLIBS) -lrseq -o $@ > --- /dev/null > +++ b/tools/testing/selftests/rseq/check_optimized.c > @@ -0,0 +1,17 @@ > +// SPDX-License-Identifier: LGPL-2.1 > +#define _GNU_SOURCE > +#include <assert.h> > +#include <sched.h> > +#include <signal.h> > +#include <stdio.h> > +#include <string.h> > +#include <sys/time.h> > + > +#include "rseq.h" > + > +int main(int argc, char **argv) > +{ > + if (__rseq_register_current_thread(true, false)) > + return -1; > + return 0; > +} > --- a/tools/testing/selftests/rseq/param_test.c > +++ b/tools/testing/selftests/rseq/param_test.c > @@ -38,7 +38,7 @@ static int opt_modulo, verbose; > static int opt_yield, opt_signal, opt_sleep, > opt_disable_rseq, opt_threads = 200, > opt_disable_mod = 0, opt_test = 's'; > - > +static bool opt_rseq_legacy; > static long long opt_reps = 5000; > > static __thread __attribute__((tls_model("initial-exec"))) > @@ -481,7 +481,7 @@ void *test_percpu_spinlock_thread(void * > long long i, reps; > > if (!opt_disable_rseq && thread_data->reg && > - rseq_register_current_thread()) > + __rseq_register_current_thread(true, opt_rseq_legacy)) > abort(); > reps = thread_data->reps; > for (i = 0; i < reps; i++) { > @@ -558,7 +558,7 @@ void *test_percpu_inc_thread(void *arg) > long long i, reps; > > if (!opt_disable_rseq && thread_data->reg && > - rseq_register_current_thread()) > + __rseq_register_current_thread(true, opt_rseq_legacy)) > abort(); > reps = thread_data->reps; > for (i = 0; i < reps; i++) { > @@ -712,7 +712,7 @@ void *test_percpu_list_thread(void *arg) > long long i, reps; > struct percpu_list *list = (struct percpu_list *)arg; > > - if (!opt_disable_rseq && rseq_register_current_thread()) > + if (!opt_disable_rseq && __rseq_register_current_thread(true, opt_rseq_legacy)) > abort(); > > reps = opt_reps; > @@ -895,7 +895,7 @@ void *test_percpu_buffer_thread(void *ar > long long i, reps; > struct percpu_buffer *buffer = (struct percpu_buffer *)arg; > > - if (!opt_disable_rseq && rseq_register_current_thread()) > + if (!opt_disable_rseq && __rseq_register_current_thread(true, opt_rseq_legacy)) > abort(); > > reps = opt_reps; > @@ -1105,7 +1105,7 @@ void *test_percpu_memcpy_buffer_thread(v > long long i, reps; > struct percpu_memcpy_buffer *buffer = (struct percpu_memcpy_buffer *)arg; > > - if (!opt_disable_rseq && rseq_register_current_thread()) > + if (!opt_disable_rseq && __rseq_register_current_thread(true, opt_rseq_legacy)) > abort(); > > reps = opt_reps; > @@ -1258,7 +1258,7 @@ void *test_membarrier_worker_thread(void > const int iters = opt_reps; > int i; > > - if (rseq_register_current_thread()) { > + if (__rseq_register_current_thread(true, opt_rseq_legacy)) { > fprintf(stderr, "Error: rseq_register_current_thread(...) failed(%d): %s\n", > errno, strerror(errno)); > abort(); > @@ -1323,7 +1323,7 @@ void *test_membarrier_manager_thread(voi > intptr_t expect_a = 0, expect_b = 0; > int cpu_a = 0, cpu_b = 0; > > - if (rseq_register_current_thread()) { > + if (__rseq_register_current_thread(true, opt_rseq_legacy)) { > fprintf(stderr, "Error: rseq_register_current_thread(...) failed(%d): %s\n", > errno, strerror(errno)); > abort(); > @@ -1475,6 +1475,7 @@ static void show_usage(int argc, char ** > printf(" [-D M] Disable rseq for each M threads\n"); > printf(" [-T test] Choose test: (s)pinlock, (l)ist, (b)uffer, (m)emcpy, (i)ncrement, membarrie(r)\n"); > printf(" [-M] Push into buffer and memcpy buffer with memory barriers.\n"); > + printf(" [-O] Test with optimized RSEQ\n"); > printf(" [-v] Verbose output.\n"); > printf(" [-h] Show this help.\n"); > printf("\n"); > @@ -1602,6 +1603,9 @@ int main(int argc, char **argv) > case 'M': > opt_mo = RSEQ_MO_RELEASE; > break; > + case 'L': > + opt_rseq_legacy = true; > + break; > default: > show_usage(argc, argv); > goto error; > @@ -1618,7 +1622,7 @@ int main(int argc, char **argv) > if (set_signal_handler()) > goto error; > > - if (!opt_disable_rseq && rseq_register_current_thread()) > + if (!opt_disable_rseq && __rseq_register_current_thread(true, opt_rseq_legacy)) > goto error; > if (!opt_disable_rseq && !rseq_validate_cpu_id()) { > fprintf(stderr, "Error: cpu id getter unavailable\n"); > --- a/tools/testing/selftests/rseq/run_param_test.sh > +++ b/tools/testing/selftests/rseq/run_param_test.sh > @@ -34,6 +34,11 @@ REPS=1000 > SLOW_REPS=100 > NR_THREADS=$((6*${NR_CPUS})) > > +# Prevent GLIBC from registering RSEQ so the selftest can run in legacy and > +# performance optimized mode. > +GLIBC_TUNABLES="${GLIBC_TUNABLES:-}:glibc.pthread.rseq=0" > +export GLIBC_TUNABLES > + > function do_tests() > { > local i=0 > @@ -103,6 +108,40 @@ function inject_blocking() > NR_LOOPS= > } > > +echo "Testing in legacy RSEQ mode" > +echo "Yield injection (25%)" > +inject_blocking -m 4 -y -L > + > +echo "Yield injection (50%)" > +inject_blocking -m 2 -y -L > + > +echo "Yield injection (100%)" > +inject_blocking -m 1 -y -L > + > +echo "Kill injection (25%)" > +inject_blocking -m 4 -k -L > + > +echo "Kill injection (50%)" > +inject_blocking -m 2 -k -L > + > +echo "Kill injection (100%)" > +inject_blocking -m 1 -k -L > + > +echo "Sleep injection (1ms, 25%)" > +inject_blocking -m 4 -s 1 -L > + > +echo "Sleep injection (1ms, 50%)" > +inject_blocking -m 2 -s 1 -L > + > +echo "Sleep injection (1ms, 100%)" > +inject_blocking -m 1 -s 1 -L > + > +./check_optimized || { > + echo "Skipping optimized RSEQ mode test. Not supported"; > + exit 0 > +} > + > +echo "Testing in optimized RSEQ mode" > echo "Yield injection (25%)" > inject_blocking -m 4 -y > > --- /dev/null > +++ b/tools/testing/selftests/rseq/run_timeslice_test.sh > @@ -0,0 +1,14 @@ > +#!/bin/bash > +# SPDX-License-Identifier: GPL-2.0+ > + > +# Prevent GLIBC from registering RSEQ so the selftest can run in legacy > +# and performance optimized mode. > +GLIBC_TUNABLES="${GLIBC_TUNABLES:-}:glibc.pthread.rseq=0" > +export GLIBC_TUNABLES > + > +./check_optimized || { > + echo "Skipping optimized RSEQ mode test. Not supported"; > + exit 0 > +} > + > +./slice_test > --- a/tools/testing/selftests/rseq/slice_test.c > +++ b/tools/testing/selftests/rseq/slice_test.c > @@ -124,7 +124,7 @@ FIXTURE_SETUP(slice_ext) > { > cpu_set_t affinity; > > - if (rseq_register_current_thread()) > + if (__rseq_register_current_thread(true, false)) > SKIP(return, "RSEQ not supported\n"); > > if (prctl(PR_RSEQ_SLICE_EXTENSION, PR_RSEQ_SLICE_EXTENSION_SET, >