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,
>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.