[PATCH 2/3] nptl: Do not always assume set_robust_list availability (BZ 33225)
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Sep 8 16:08:49 GMT 2025
Ping. I still think that the incostency between some arches (ARM/x86 and
RISC-V) wrt robust support in qemu it still work to fix.
On 29/07/25 15:21, Adhemerval Zanella wrote:
> The __ASSUME_SET_ROBUST_LIST is used to define and set
> __nptl_set_robust_list_avail to advertise process shared robust mutex
> support, done at __tls_init_tp (during pthread initialization).
>
> Some specific kernel configurations and the qemu-user (for all ABIs) do
> not implement the set_robust_list syscal. Therefore, for the default case
> (__ASSUME_SET_ROBUST_LIST being true), the missing support is not
> detected, and pthread_mutex_init succeeds where it should fail. For
> instance, the sequence succeeds on qemu-user even when set_robust_list
> fails with ENOSYS.
>
> pthread_mutexattr_init(&attr);
> pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
> pthread_mutexattr_setrobust(&attr, PTHREAD_MUTEX_ROBUST);
>
> pthread_mutex_init(&mutex, &attr);
>
> This patch removes __ASSUME_SET_ROBUST_LIST and always enables
> __nptl_set_robust_list_avail detection.
>
> Checked on x86_64-linux-gnu.
>
> Reported-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
> ---
> nptl/pthread_create.c | 4 ----
> nptl/pthread_mutex_init.c | 3 ---
> nptl/tst-mutexpi10.c | 4 +++-
> nptl/tst-robust-fork.c | 21 +++++++++++++++++++
> sysdeps/nptl/dl-tls_init_tp.c | 8 +------
> sysdeps/nptl/pthreadP.h | 2 --
> sysdeps/pthread/tst-mutex7.c | 3 +++
> sysdeps/pthread/tst-robust1.c | 3 +++
> sysdeps/pthread/tst-robust10.c | 3 +++
> sysdeps/pthread/tst-robust7.c | 2 ++
> sysdeps/pthread/tst-robust8.c | 6 ++++++
> sysdeps/pthread/tst-robust9.c | 2 ++
> sysdeps/unix/sysv/linux/arm/kernel-features.h | 7 -------
> .../unix/sysv/linux/hppa/kernel-features.h | 3 ---
> sysdeps/unix/sysv/linux/kernel-features.h | 5 -----
> .../unix/sysv/linux/m68k/kernel-features.h | 5 -----
> .../unix/sysv/linux/mips/kernel-features.h | 6 ------
> .../unix/sysv/linux/riscv/kernel-features.h | 5 -----
> .../unix/sysv/linux/sparc/kernel-features.h | 6 ------
> 19 files changed, 44 insertions(+), 54 deletions(-)
>
> diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
> index e1033d4ee6..04b8f27b99 100644
> --- a/nptl/pthread_create.c
> +++ b/nptl/pthread_create.c
> @@ -380,9 +380,7 @@ start_thread (void *arg)
> __libc_fatal ("Fatal glibc error: rseq registration failed\n");
> }
>
> -#ifndef __ASSUME_SET_ROBUST_LIST
> if (__nptl_set_robust_list_avail)
> -#endif
> {
> /* This call should never fail because the initial call in init.c
> succeeded. */
> @@ -517,7 +515,6 @@ start_thread (void *arg)
> pd->exiting = true;
> __libc_lock_unlock (pd->exit_lock);
>
> -#ifndef __ASSUME_SET_ROBUST_LIST
> /* If this thread has any robust mutexes locked, handle them now. */
> # if __PTHREAD_MUTEX_HAVE_PREV
> void *robust = pd->robust_head.list;
> @@ -548,7 +545,6 @@ start_thread (void *arg)
> }
> while (robust != (void *) &pd->robust_head);
> }
> -#endif
>
> /* Release the vDSO getrandom per-thread buffer with all signal blocked,
> to avoid creating a new free-state block during thread release. */
> diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
> index 1639935202..35b55576c4 100644
> --- a/nptl/pthread_mutex_init.c
> +++ b/nptl/pthread_mutex_init.c
> @@ -93,12 +93,9 @@ ___pthread_mutex_init (pthread_mutex_t *mutex,
>
> if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0)
> {
> -#ifndef __ASSUME_SET_ROBUST_LIST
> if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_PSHARED) != 0
> && !__nptl_set_robust_list_avail)
> return ENOTSUP;
> -#endif
> -
> mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
> }
>
> diff --git a/nptl/tst-mutexpi10.c b/nptl/tst-mutexpi10.c
> index 6d2bbbb308..92bd82ebb7 100644
> --- a/nptl/tst-mutexpi10.c
> +++ b/nptl/tst-mutexpi10.c
> @@ -58,7 +58,9 @@ do_test (void)
> xpthread_mutexattr_setrobust (&attr, robust[r]);
>
> pthread_mutex_t mtx;
> - xpthread_mutex_init (&mtx, &attr);
> + if (pthread_mutex_init (&mtx, &attr) == ENOTSUP
> + && robust[r] == PTHREAD_MUTEX_ROBUST)
> + continue;
>
> /* Uncontended case does not trigger any futex call. */
> struct timespec tmo = timespec_add (xclock_now (clocks[c].clk),
> diff --git a/nptl/tst-robust-fork.c b/nptl/tst-robust-fork.c
> index 8144b3de3d..375dad768a 100644
> --- a/nptl/tst-robust-fork.c
> +++ b/nptl/tst-robust-fork.c
> @@ -159,9 +159,20 @@ one_test (int parent_bits, int child_bits, int nonshared_bits,
> xmunmap (shared, sizeof (*shared));
> }
>
> +static inline bool
> +is_robust_pshared (int bits)
> +{
> + return (bits & (mutex_robust | mutex_pshared))
> + == (mutex_robust | mutex_pshared);
> +}
> +
> static int
> do_test (void)
> {
> + bool robust_support = support_mutex_robust ();
> + if (test_verbose)
> + printf ("info: robust_support=%d\n", robust_support);
> +
> for (int parent_bits = 0; parent_bits <= mutex_all_bits; ++parent_bits)
> for (int child_bits = 0; child_bits <= mutex_all_bits; ++child_bits)
> for (int nonshared_bits = 0; nonshared_bits <= mutex_all_bits;
> @@ -175,6 +186,16 @@ do_test (void)
> parent_bits, child_bits, nonshared_bits,
> lock_nonshared ? " lock_nonshared" : "",
> lock_child ? " lock_child" : "");
> + if ((is_robust_pshared (parent_bits)
> + || is_robust_pshared (child_bits)
> + || is_robust_pshared (nonshared_bits))
> + && !robust_support)
> + {
> + if (test_verbose)
> + printf ("info: skipping tests due missing robust mutex"
> + "support");
> + continue;
> + }
> one_test (parent_bits, child_bits, nonshared_bits,
> lock_nonshared, lock_child);
> }
> diff --git a/sysdeps/nptl/dl-tls_init_tp.c b/sysdeps/nptl/dl-tls_init_tp.c
> index 47566dce4f..8bf3c7f14b 100644
> --- a/sysdeps/nptl/dl-tls_init_tp.c
> +++ b/sysdeps/nptl/dl-tls_init_tp.c
> @@ -28,10 +28,8 @@
> #define TUNABLE_NAMESPACE pthread
> #include <dl-tunables.h>
>
> -#ifndef __ASSUME_SET_ROBUST_LIST
> bool __nptl_set_robust_list_avail;
> rtld_hidden_data_def (__nptl_set_robust_list_avail)
> -#endif
>
> bool __nptl_initial_report_events;
> rtld_hidden_def (__nptl_initial_report_events)
> @@ -94,11 +92,7 @@ __tls_init_tp (void)
> int res = INTERNAL_SYSCALL_CALL (set_robust_list, &pd->robust_head,
> sizeof (struct robust_list_head));
> if (!INTERNAL_SYSCALL_ERROR_P (res))
> - {
> -#ifndef __ASSUME_SET_ROBUST_LIST
> - __nptl_set_robust_list_avail = true;
> -#endif
> - }
> + __nptl_set_robust_list_avail = true;
> }
>
> {
> diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
> index 8f256967e2..0822a437da 100644
> --- a/sysdeps/nptl/pthreadP.h
> +++ b/sysdeps/nptl/pthreadP.h
> @@ -210,12 +210,10 @@ libc_hidden_proto (__pthread_keys)
> extern unsigned int __nptl_nthreads;
> libc_hidden_proto (__nptl_nthreads)
>
> -#ifndef __ASSUME_SET_ROBUST_LIST
> /* True if the set_robust_list system call works. Initialized in
> __tls_init_tp. */
> extern bool __nptl_set_robust_list_avail;
> rtld_hidden_proto (__nptl_set_robust_list_avail)
> -#endif
>
> /* Thread Priority Protection. */
> extern int __sched_fifo_min_prio;
> diff --git a/sysdeps/pthread/tst-mutex7.c b/sysdeps/pthread/tst-mutex7.c
> index fc8220eec7..d56a7f4dbb 100644
> --- a/sysdeps/pthread/tst-mutex7.c
> +++ b/sysdeps/pthread/tst-mutex7.c
> @@ -21,6 +21,9 @@
> #include <stdlib.h>
> #include <time.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
> +
> /* This test is a template for other tests to use. Other tests define
> the following macros to change the behaviour of the template test.
> The test is very simple, it configures N threads given the parameters
> diff --git a/sysdeps/pthread/tst-robust1.c b/sysdeps/pthread/tst-robust1.c
> index bd659cc494..638cb705c8 100644
> --- a/sysdeps/pthread/tst-robust1.c
> +++ b/sysdeps/pthread/tst-robust1.c
> @@ -20,6 +20,9 @@
> #include <stdio.h>
> #include <stdlib.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
> +
>
> static pthread_mutex_t m1;
> static pthread_mutex_t m2;
> diff --git a/sysdeps/pthread/tst-robust10.c b/sysdeps/pthread/tst-robust10.c
> index ef1e3113f0..813d785ed7 100644
> --- a/sysdeps/pthread/tst-robust10.c
> +++ b/sysdeps/pthread/tst-robust10.c
> @@ -22,6 +22,9 @@
> #include <string.h>
> #include <errno.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
> +
> pthread_mutex_t mutex;
>
> static void *
> diff --git a/sysdeps/pthread/tst-robust7.c b/sysdeps/pthread/tst-robust7.c
> index bf660e8cb0..f73363de96 100644
> --- a/sysdeps/pthread/tst-robust7.c
> +++ b/sysdeps/pthread/tst-robust7.c
> @@ -21,6 +21,8 @@
> #include <stdio.h>
> #include <stdlib.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
>
> static pthread_barrier_t b;
> static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
> diff --git a/sysdeps/pthread/tst-robust8.c b/sysdeps/pthread/tst-robust8.c
> index 4c8a20e916..dd6230168d 100644
> --- a/sysdeps/pthread/tst-robust8.c
> +++ b/sysdeps/pthread/tst-robust8.c
> @@ -10,6 +10,8 @@
>
> #include <pthreadP.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
>
>
> static void prepare (void);
> @@ -143,6 +145,10 @@ child (int round)
> static int
> do_test (void)
> {
> + /* Process shared robust mutexes requires kernel support. */
> + if (!support_mutex_robust ())
> + FAIL_UNSUPPORTED ("robust mutexes not supported");
> +
> if (ftruncate (fd, N * sizeof (pthread_mutex_t)) != 0)
> {
> puts ("cannot size new file");
> diff --git a/sysdeps/pthread/tst-robust9.c b/sysdeps/pthread/tst-robust9.c
> index ca24f24282..de675259da 100644
> --- a/sysdeps/pthread/tst-robust9.c
> +++ b/sysdeps/pthread/tst-robust9.c
> @@ -5,6 +5,8 @@
> #include <unistd.h>
> #include <sys/time.h>
>
> +#include <support/check.h>
> +#include <support/xthread.h>
>
> static pthread_mutex_t m;
>
> diff --git a/sysdeps/unix/sysv/linux/arm/kernel-features.h b/sysdeps/unix/sysv/linux/arm/kernel-features.h
> index 10caae8b91..a1f8611160 100644
> --- a/sysdeps/unix/sysv/linux/arm/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/arm/kernel-features.h
> @@ -20,13 +20,6 @@
> #include <endian.h>
> #include_next <kernel-features.h>
>
> -/* The ARM kernel before 3.14.3 may or may not support
> - futex_atomic_cmpxchg_inatomic, depending on kernel
> - configuration. */
> -#if __LINUX_KERNEL_VERSION < 0x030E03
> -# undef __ASSUME_SET_ROBUST_LIST
> -#endif
> -
> /* ARM fadvise64_64 reorganize the syscall arguments. */
> #define __ASSUME_FADVISE64_64_6ARG 1
>
> diff --git a/sysdeps/unix/sysv/linux/hppa/kernel-features.h b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> index 102714166e..e9b3bcaa1a 100644
> --- a/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/hppa/kernel-features.h
> @@ -30,6 +30,3 @@
>
> #undef __ASSUME_CLONE_DEFAULT
> #define __ASSUME_CLONE_BACKWARDS 1
> -
> -/* QEMU does not support set_robust_list. */
> -#undef __ASSUME_SET_ROBUST_LIST
> diff --git a/sysdeps/unix/sysv/linux/kernel-features.h b/sysdeps/unix/sysv/linux/kernel-features.h
> index a49a9159cf..f203d038da 100644
> --- a/sysdeps/unix/sysv/linux/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/kernel-features.h
> @@ -49,11 +49,6 @@
> SH this appeared first in 2.6.19-rc1. */
> #define __ASSUME_PSELECT 1
>
> -/* Support for inter-process robust mutexes was added in 2.6.17 (but
> - some architectures lack futex_atomic_cmpxchg_inatomic in some
> - configurations). */
> -#define __ASSUME_SET_ROBUST_LIST 1
> -
> /* The termios2 interface was introduced across all architectures except
> Alpha in kernel 2.6.22. */
> #define __ASSUME_TERMIOS2 1
> diff --git a/sysdeps/unix/sysv/linux/m68k/kernel-features.h b/sysdeps/unix/sysv/linux/m68k/kernel-features.h
> index 3515b20433..ba0cc0844f 100644
> --- a/sysdeps/unix/sysv/linux/m68k/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/m68k/kernel-features.h
> @@ -42,11 +42,6 @@
> # undef __ASSUME_GETPEERNAME_SYSCALL
> #endif
>
> -/* No support for PI futexes or robust mutexes before 3.10 for m68k. */
> -#if __LINUX_KERNEL_VERSION < 0x030a00
> -# undef __ASSUME_SET_ROBUST_LIST
> -#endif
> -
> /* m68k only supports ipc syscall before 5.1. */
> #if __LINUX_KERNEL_VERSION < 0x050100
> # undef __ASSUME_DIRECT_SYSVIPC_SYSCALLS
> diff --git a/sysdeps/unix/sysv/linux/mips/kernel-features.h b/sysdeps/unix/sysv/linux/mips/kernel-features.h
> index d86ac92352..c9bba743ac 100644
> --- a/sysdeps/unix/sysv/linux/mips/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/mips/kernel-features.h
> @@ -21,12 +21,6 @@
>
> #include_next <kernel-features.h>
>
> -/* The MIPS kernel does not support futex_atomic_cmpxchg_inatomic if
> - emulating LL/SC. */
> -#if __mips == 1 || defined _MIPS_ARCH_R5900
> -# undef __ASSUME_SET_ROBUST_LIST
> -#endif
> -
> /* Define this if your 32-bit syscall API requires 64-bit register
> pairs to start with an even-number register. */
> #if _MIPS_SIM == _ABIO32
> diff --git a/sysdeps/unix/sysv/linux/riscv/kernel-features.h b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
> index dce50835d1..83e0c69ee3 100644
> --- a/sysdeps/unix/sysv/linux/riscv/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/riscv/kernel-features.h
> @@ -21,8 +21,3 @@
>
> #undef __ASSUME_CLONE_DEFAULT
> #define __ASSUME_CLONE_BACKWARDS 1
> -
> -/* No support for PI mutexes or robust futexes before 4.20. */
> -#if __LINUX_KERNEL_VERSION < 0x041400
> -# undef __ASSUME_SET_ROBUST_LIST
> -#endif
> diff --git a/sysdeps/unix/sysv/linux/sparc/kernel-features.h b/sysdeps/unix/sysv/linux/sparc/kernel-features.h
> index 24423db127..8e7ee91eeb 100644
> --- a/sysdeps/unix/sysv/linux/sparc/kernel-features.h
> +++ b/sysdeps/unix/sysv/linux/sparc/kernel-features.h
> @@ -19,12 +19,6 @@
>
> #include_next <kernel-features.h>
>
> -/* 32-bit SPARC kernels do not support
> - futex_atomic_cmpxchg_inatomic. */
> -#if !defined __arch64__ && !defined __sparc_v9__
> -# undef __ASSUME_SET_ROBUST_LIST
> -#endif
> -
> /* These syscalls were added for 32-bit in 4.4 (but present for 64-bit
> in all supported kernel versions); the architecture-independent
> kernel-features.h assumes some of them to be present by default.
More information about the Libc-alpha
mailing list