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-robust7.c | 1 -
sysdeps/pthread/tst-robust8.c | 6 ++++++
sysdeps/pthread/tst-robust9.c | 1 -
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 ------
16 files changed, 31 insertions(+), 56 deletions(-)
@@ -386,9 +386,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. */
@@ -536,7 +534,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;
@@ -567,7 +564,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. */
@@ -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;
}
@@ -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),
@@ -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_process_shared_robust_mutex ();
+ 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\n");
+ continue;
+ }
one_test (parent_bits, child_bits, nonshared_bits,
lock_nonshared, lock_child);
}
@@ -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)
@@ -95,11 +93,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;
}
{
@@ -192,12 +192,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;
@@ -21,7 +21,6 @@
#include <stdio.h>
#include <stdlib.h>
-
static pthread_barrier_t b;
static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t m;
@@ -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_process_shared_robust_mutex ())
+ FAIL_UNSUPPORTED ("process-shared robust mutexes not supported");
+
if (ftruncate (fd, N * sizeof (pthread_mutex_t)) != 0)
{
puts ("cannot size new file");
@@ -5,7 +5,6 @@
#include <unistd.h>
#include <sys/time.h>
-
static pthread_mutex_t m;
static void *
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.