Skip to content

Commit 595b28f

Browse files
committed
Merge tag 'locking-core-2021-10-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull locking updates from Thomas Gleixner: - Move futex code into kernel/futex/ and split up the kitchen sink into seperate files to make integration of sys_futex_waitv() simpler. - Add a new sys_futex_waitv() syscall which allows to wait on multiple futexes. The main use case is emulating Windows' WaitForMultipleObjects which allows Wine to improve the performance of Windows Games. Also native Linux games can benefit from this interface as this is a common wait pattern for this kind of applications. - Add context to ww_mutex_trylock() to provide a path for i915 to rework their eviction code step by step without making lockdep upset until the final steps of rework are completed. It's also useful for regulator and TTM to avoid dropping locks in the non contended path. - Lockdep and might_sleep() cleanups and improvements - A few improvements for the RT substitutions. - The usual small improvements and cleanups. * tag 'locking-core-2021-10-31' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits) locking: Remove spin_lock_flags() etc locking/rwsem: Fix comments about reader optimistic lock stealing conditions locking: Remove rcu_read_{,un}lock() for preempt_{dis,en}able() locking/rwsem: Disable preemption for spinning region docs: futex: Fix kernel-doc references futex: Fix PREEMPT_RT build futex2: Documentation: Document sys_futex_waitv() uAPI selftests: futex: Test sys_futex_waitv() wouldblock selftests: futex: Test sys_futex_waitv() timeout selftests: futex: Add sys_futex_waitv() test futex,arm: Wire up sys_futex_waitv() futex,x86: Wire up sys_futex_waitv() futex: Implement sys_futex_waitv() futex: Simplify double_lock_hb() futex: Split out wait/wake futex: Split out requeue futex: Rename mark_wake_futex() futex: Rename: match_futex() futex: Rename: hb_waiter_{inc,dec,pending}() futex: Split out PI futex ...
2 parents 91e1c99 + f98a3dc commit 595b28f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+5518
-4550
lines changed

Documentation/kernel-hacking/locking.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1352,7 +1352,19 @@ Mutex API reference
13521352
Futex API reference
13531353
===================
13541354

1355-
.. kernel-doc:: kernel/futex.c
1355+
.. kernel-doc:: kernel/futex/core.c
1356+
:internal:
1357+
1358+
.. kernel-doc:: kernel/futex/futex.h
1359+
:internal:
1360+
1361+
.. kernel-doc:: kernel/futex/pi.c
1362+
:internal:
1363+
1364+
.. kernel-doc:: kernel/futex/requeue.c
1365+
:internal:
1366+
1367+
.. kernel-doc:: kernel/futex/waitwake.c
13561368
:internal:
13571369

13581370
Further reading

Documentation/translations/it_IT/kernel-hacking/locking.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1396,7 +1396,19 @@ Riferimento per l'API dei Mutex
13961396
Riferimento per l'API dei Futex
13971397
===============================
13981398

1399-
.. kernel-doc:: kernel/futex.c
1399+
.. kernel-doc:: kernel/futex/core.c
1400+
:internal:
1401+
1402+
.. kernel-doc:: kernel/futex/futex.h
1403+
:internal:
1404+
1405+
.. kernel-doc:: kernel/futex/pi.c
1406+
:internal:
1407+
1408+
.. kernel-doc:: kernel/futex/requeue.c
1409+
:internal:
1410+
1411+
.. kernel-doc:: kernel/futex/waitwake.c
14001412
:internal:
14011413

14021414
Approfondimenti
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
.. SPDX-License-Identifier: GPL-2.0
2+
3+
======
4+
futex2
5+
======
6+
7+
:Author: André Almeida <[email protected]>
8+
9+
futex, or fast user mutex, is a set of syscalls to allow userspace to create
10+
performant synchronization mechanisms, such as mutexes, semaphores and
11+
conditional variables in userspace. C standard libraries, like glibc, uses it
12+
as a means to implement more high level interfaces like pthreads.
13+
14+
futex2 is a followup version of the initial futex syscall, designed to overcome
15+
limitations of the original interface.
16+
17+
User API
18+
========
19+
20+
``futex_waitv()``
21+
-----------------
22+
23+
Wait on an array of futexes, wake on any::
24+
25+
futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes,
26+
unsigned int flags, struct timespec *timeout, clockid_t clockid)
27+
28+
struct futex_waitv {
29+
__u64 val;
30+
__u64 uaddr;
31+
__u32 flags;
32+
__u32 __reserved;
33+
};
34+
35+
Userspace sets an array of struct futex_waitv (up to a max of 128 entries),
36+
using ``uaddr`` for the address to wait for, ``val`` for the expected value
37+
and ``flags`` to specify the type (e.g. private) and size of futex.
38+
``__reserved`` needs to be 0, but it can be used for future extension. The
39+
pointer for the first item of the array is passed as ``waiters``. An invalid
40+
address for ``waiters`` or for any ``uaddr`` returns ``-EFAULT``.
41+
42+
If userspace has 32-bit pointers, it should do a explicit cast to make sure
43+
the upper bits are zeroed. ``uintptr_t`` does the tricky and it works for
44+
both 32/64-bit pointers.
45+
46+
``nr_futexes`` specifies the size of the array. Numbers out of [1, 128]
47+
interval will make the syscall return ``-EINVAL``.
48+
49+
The ``flags`` argument of the syscall needs to be 0, but it can be used for
50+
future extension.
51+
52+
For each entry in ``waiters`` array, the current value at ``uaddr`` is compared
53+
to ``val``. If it's different, the syscall undo all the work done so far and
54+
return ``-EAGAIN``. If all tests and verifications succeeds, syscall waits until
55+
one of the following happens:
56+
57+
- The timeout expires, returning ``-ETIMEOUT``.
58+
- A signal was sent to the sleeping task, returning ``-ERESTARTSYS``.
59+
- Some futex at the list was woken, returning the index of some waked futex.
60+
61+
An example of how to use the interface can be found at ``tools/testing/selftests/futex/functional/futex_waitv.c``.
62+
63+
Timeout
64+
-------
65+
66+
``struct timespec *timeout`` argument is an optional argument that points to an
67+
absolute timeout. You need to specify the type of clock being used at
68+
``clockid`` argument. ``CLOCK_MONOTONIC`` and ``CLOCK_REALTIME`` are supported.
69+
This syscall accepts only 64bit timespec structs.
70+
71+
Types of futex
72+
--------------
73+
74+
A futex can be either private or shared. Private is used for processes that
75+
shares the same memory space and the virtual address of the futex will be the
76+
same for all processes. This allows for optimizations in the kernel. To use
77+
private futexes, it's necessary to specify ``FUTEX_PRIVATE_FLAG`` in the futex
78+
flag. For processes that doesn't share the same memory space and therefore can
79+
have different virtual addresses for the same futex (using, for instance, a
80+
file-backed shared memory) requires different internal mechanisms to be get
81+
properly enqueued. This is the default behavior, and it works with both private
82+
and shared futexes.
83+
84+
Futexes can be of different sizes: 8, 16, 32 or 64 bits. Currently, the only
85+
supported one is 32 bit sized futex, and it need to be specified using
86+
``FUTEX_32`` flag.

Documentation/userspace-api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ place where this information is gathered.
2828
media/index
2929
sysfs-platform_profile
3030
vduse
31+
futex2
3132

3233
.. only:: subproject and html
3334

MAINTAINERS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7737,14 +7737,15 @@ M: Ingo Molnar <[email protected]>
77377737
R: Peter Zijlstra <[email protected]>
77387738
R: Darren Hart <[email protected]>
77397739
R: Davidlohr Bueso <[email protected]>
7740+
R: André Almeida <[email protected]>
77407741
77417742
S: Maintained
77427743
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git locking/core
77437744
F: Documentation/locking/*futex*
77447745
F: include/asm-generic/futex.h
77457746
F: include/linux/futex.h
77467747
F: include/uapi/linux/futex.h
7747-
F: kernel/futex.c
7748+
F: kernel/futex/*
77487749
F: tools/perf/bench/futex*
77497750
F: tools/testing/selftests/futex/
77507751

arch/arm/tools/syscall.tbl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,4 @@
462462
446 common landlock_restrict_self sys_landlock_restrict_self
463463
# 447 reserved for memfd_secret
464464
448 common process_mrelease sys_process_mrelease
465+
449 common futex_waitv sys_futex_waitv

arch/arm64/include/asm/unistd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
#define __ARM_NR_compat_set_tls (__ARM_NR_COMPAT_BASE + 5)
3939
#define __ARM_NR_COMPAT_END (__ARM_NR_COMPAT_BASE + 0x800)
4040

41-
#define __NR_compat_syscalls 449
41+
#define __NR_compat_syscalls 450
4242
#endif
4343

4444
#define __ARCH_WANT_SYS_CLONE

arch/arm64/include/asm/unistd32.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -903,6 +903,8 @@ __SYSCALL(__NR_landlock_add_rule, sys_landlock_add_rule)
903903
__SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self)
904904
#define __NR_process_mrelease 448
905905
__SYSCALL(__NR_process_mrelease, sys_process_mrelease)
906+
#define __NR_futex_waitv 449
907+
__SYSCALL(__NR_futex_waitv, sys_futex_waitv)
906908

907909
/*
908910
* Please add new compat syscalls above this comment and update

arch/ia64/include/asm/spinlock.h

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -124,18 +124,13 @@ static __always_inline void arch_spin_unlock(arch_spinlock_t *lock)
124124
__ticket_spin_unlock(lock);
125125
}
126126

127-
static __always_inline void arch_spin_lock_flags(arch_spinlock_t *lock,
128-
unsigned long flags)
129-
{
130-
arch_spin_lock(lock);
131-
}
132-
#define arch_spin_lock_flags arch_spin_lock_flags
133-
134127
#ifdef ASM_SUPPORTED
135128

136129
static __always_inline void
137-
arch_read_lock_flags(arch_rwlock_t *lock, unsigned long flags)
130+
arch_read_lock(arch_rwlock_t *lock)
138131
{
132+
unsigned long flags = 0;
133+
139134
__asm__ __volatile__ (
140135
"tbit.nz p6, p0 = %1,%2\n"
141136
"br.few 3f\n"
@@ -157,13 +152,8 @@ arch_read_lock_flags(arch_rwlock_t *lock, unsigned long flags)
157152
: "p6", "p7", "r2", "memory");
158153
}
159154

160-
#define arch_read_lock_flags arch_read_lock_flags
161-
#define arch_read_lock(lock) arch_read_lock_flags(lock, 0)
162-
163155
#else /* !ASM_SUPPORTED */
164156

165-
#define arch_read_lock_flags(rw, flags) arch_read_lock(rw)
166-
167157
#define arch_read_lock(rw) \
168158
do { \
169159
arch_rwlock_t *__read_lock_ptr = (rw); \
@@ -186,8 +176,10 @@ do { \
186176
#ifdef ASM_SUPPORTED
187177

188178
static __always_inline void
189-
arch_write_lock_flags(arch_rwlock_t *lock, unsigned long flags)
179+
arch_write_lock(arch_rwlock_t *lock)
190180
{
181+
unsigned long flags = 0;
182+
191183
__asm__ __volatile__ (
192184
"tbit.nz p6, p0 = %1, %2\n"
193185
"mov ar.ccv = r0\n"
@@ -210,9 +202,6 @@ arch_write_lock_flags(arch_rwlock_t *lock, unsigned long flags)
210202
: "ar.ccv", "p6", "p7", "r2", "r29", "memory");
211203
}
212204

213-
#define arch_write_lock_flags arch_write_lock_flags
214-
#define arch_write_lock(rw) arch_write_lock_flags(rw, 0)
215-
216205
#define arch_write_trylock(rw) \
217206
({ \
218207
register long result; \

arch/openrisc/include/asm/spinlock.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919

2020
#include <asm/qrwlock.h>
2121

22-
#define arch_read_lock_flags(lock, flags) arch_read_lock(lock)
23-
#define arch_write_lock_flags(lock, flags) arch_write_lock(lock)
24-
2522
#define arch_spin_relax(lock) cpu_relax()
2623
#define arch_read_relax(lock) cpu_relax()
2724
#define arch_write_relax(lock) cpu_relax()

0 commit comments

Comments
 (0)