futex: Add sys_futex_requeue()
authorpeterz@infradead.org <peterz@infradead.org>
Thu, 21 Sep 2023 10:45:15 +0000 (12:45 +0200)
committerPeter Zijlstra <peterz@infradead.org>
Thu, 21 Sep 2023 17:22:10 +0000 (19:22 +0200)
Finish off the 'simple' futex2 syscall group by adding
sys_futex_requeue(). Unlike sys_futex_{wait,wake}() its arguments are
too numerous to fit into a regular syscall. As such, use struct
futex_waitv to pass the 'source' and 'destination' futexes to the
syscall.

This syscall implements what was previously known as FUTEX_CMP_REQUEUE
and uses {val, uaddr, flags} for source and {uaddr, flags} for
destination.

This design explicitly allows requeueing between different types of
futex by having a different flags word per uaddr.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Geert Uytterhoeven <geert@linux-m68k.org>
Link: https://lore.kernel.org/r/20230921105248.511860556@noisy.programming.kicks-ass.net
22 files changed:
arch/alpha/kernel/syscalls/syscall.tbl
arch/arm/tools/syscall.tbl
arch/arm64/include/asm/unistd.h
arch/arm64/include/asm/unistd32.h
arch/ia64/kernel/syscalls/syscall.tbl
arch/m68k/kernel/syscalls/syscall.tbl
arch/microblaze/kernel/syscalls/syscall.tbl
arch/mips/kernel/syscalls/syscall_n32.tbl
arch/mips/kernel/syscalls/syscall_n64.tbl
arch/mips/kernel/syscalls/syscall_o32.tbl
arch/parisc/kernel/syscalls/syscall.tbl
arch/powerpc/kernel/syscalls/syscall.tbl
arch/s390/kernel/syscalls/syscall.tbl
arch/sh/kernel/syscalls/syscall.tbl
arch/sparc/kernel/syscalls/syscall.tbl
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/xtensa/kernel/syscalls/syscall.tbl
include/linux/syscalls.h
include/uapi/asm-generic/unistd.h
kernel/futex/syscalls.c
kernel/sys_ni.c

index c49f12fd264e362db98fc60891edbfc60faedfbc..b1865f9bb31e227600a89222993f0cf091cb4262 100644 (file)
 562    common  fchmodat2                       sys_fchmodat2
 563    common  futex_wake                      sys_futex_wake
 564    common  futex_wait                      sys_futex_wait
+565    common  futex_requeue                   sys_futex_requeue
index a6cf56277327023047841dea70d94c5fac44c4fc..93d0d46cbb15ab85b5f2e31c17a701084859c71c 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index f33190f17ebb6173c5335282100db7bd47624d2d..531effca5f1fc0e83d187bbf1c35749bcc740683 100644 (file)
@@ -39,7 +39,7 @@
 #define __ARM_NR_compat_set_tls                (__ARM_NR_COMPAT_BASE + 5)
 #define __ARM_NR_COMPAT_END            (__ARM_NR_COMPAT_BASE + 0x800)
 
-#define __NR_compat_syscalls           456
+#define __NR_compat_syscalls           457
 #endif
 
 #define __ARCH_WANT_SYS_CLONE
index 6e7d37282ba1150d9fc8326b7b350c311ca2675d..c453291154fde6025df96b455a3d26168cbbf35b 100644 (file)
@@ -915,6 +915,8 @@ __SYSCALL(__NR_fchmodat2, sys_fchmodat2)
 __SYSCALL(__NR_futex_wake, sys_futex_wake)
 #define __NR_futex_wait 455
 __SYSCALL(__NR_futex_wait, sys_futex_wait)
+#define __NR_futex_requeue 456
+__SYSCALL(__NR_futex_requeue, sys_futex_requeue)
 
 /*
  * Please add new compat syscalls above this comment and update
index 4043f0c55170e0e2e33dda402e3a07f57b200d0a..81375ea7828821edab163bd80a352769ca2bec02 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index 24841674acc53b431f5addc4e13c0b0f1c019c29..f7f997a88bab56a54f6fa1dbdfaa9892bea4bd35 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index f03927ab0220a79137cb831785b599aff0c5c0ac..2967ec26b9781ff4fc33538ecf88db1ad7c7e77d 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index dbb5edfb667b3017f5208205b2be0d7aa1877785..383abb1713f4432dfea5763554337a87e219dab3 100644 (file)
 452    n32     fchmodat2                       sys_fchmodat2
 454    n32     futex_wake                      sys_futex_wake
 455    n32     futex_wait                      sys_futex_wait
+456    n32     futex_requeue                   sys_futex_requeue
index faff8dfd298337c974dd14a9bb4616c8d5883482..c9bd09ba905f172af03b6e6cb376f9897c40e3a1 100644 (file)
 452    n64     fchmodat2                       sys_fchmodat2
 454    n64     futex_wake                      sys_futex_wake
 455    n64     futex_wait                      sys_futex_wait
+456    n64     futex_requeue                   sys_futex_requeue
index 542f75605b3e44771d8dfd21b03ff359df6ffbe1..ba5ef6cea97a56506c1adff8a8037ed67eea94eb 100644 (file)
 452    o32     fchmodat2                       sys_fchmodat2
 454    o32     futex_wake                      sys_futex_wake
 455    o32     futex_wait                      sys_futex_wait
+456    o32     futex_requeue                   sys_futex_requeue
index 8e50e89551f7b405362785f1b9a3982e92d58bfa..9f0f6df55361d8dc3db43b7f6b6b13dc628f1b59 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index ad33a9993a6acb61a3a4c5db574bfdcf4177bab8..26fc41904266295a700d1432cfaac6088b717067 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index 418853fd2a6be156fe3992837192482d7a286458..31be90b241f7e838e65a379df195574e7e672ff6 100644 (file)
 452  common    fchmodat2               sys_fchmodat2                   sys_fchmodat2
 454  common    futex_wake              sys_futex_wake                  sys_futex_wake
 455  common    futex_wait              sys_futex_wait                  sys_futex_wait
+456  common    futex_requeue           sys_futex_requeue                       sys_futex_requeue
index 8ef9557d27796471bb688c1de1190580247db07f..4bc5d488ab178a602f3a5f5aefd2e4fd0ff2f390 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index df59a9d5f109ff3ff1fb1ca9e07622bdf84d93a9..8404c8e50394d906c237920a6b500f46131db3bc 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index 0f6616822bd5010a373a48716b0d325f4e0f498b..31c48bc2c3d8663bda2cefef37adf17393faec91 100644 (file)
 452    i386    fchmodat2               sys_fchmodat2
 454    i386    futex_wake              sys_futex_wake
 455    i386    futex_wait              sys_futex_wait
+456    i386    futex_requeue           sys_futex_requeue
index ddf6288823ad06ad4727b9fd2f357a9bbc336261..a577bb27c16d19b74645a9b322412265c18212df 100644 (file)
 453    64      map_shadow_stack        sys_map_shadow_stack
 454    common  futex_wake              sys_futex_wake
 455    common  futex_wait              sys_futex_wait
+456    common  futex_requeue           sys_futex_requeue
 
 #
 # Due to a historical design error, certain syscalls are numbered differently
index ac278dbce2eeef80a7c878da1d9515afaeb9b9fd..dd71ecce8b86e217d65222041d52f7cb1d447285 100644 (file)
 452    common  fchmodat2                       sys_fchmodat2
 454    common  futex_wake                      sys_futex_wake
 455    common  futex_wait                      sys_futex_wait
+456    common  futex_requeue                   sys_futex_requeue
index 11f3fdd1ee0378730386e19f301ec6da6764378d..0901af60d971f803ff017e718032e37ed8a8cf3b 100644 (file)
@@ -556,6 +556,9 @@ asmlinkage long sys_futex_wait(void __user *uaddr, unsigned long val, unsigned l
                               unsigned int flags, struct __kernel_timespec __user *timespec,
                               clockid_t clockid);
 
+asmlinkage long sys_futex_requeue(struct futex_waitv __user *waiters,
+                                 unsigned int flags, int nr_wake, int nr_requeue);
+
 asmlinkage long sys_nanosleep(struct __kernel_timespec __user *rqtp,
                              struct __kernel_timespec __user *rmtp);
 asmlinkage long sys_nanosleep_time32(struct old_timespec32 __user *rqtp,
index f6553bd5d213b2e26e3fa26c5846e91c94c0f9c7..d9e9cd13e577454229bdfe631732ee76c4855387 100644 (file)
@@ -826,9 +826,11 @@ __SYSCALL(__NR_fchmodat2, sys_fchmodat2)
 __SYSCALL(__NR_futex_wake, sys_futex_wake)
 #define __NR_futex_wait 455
 __SYSCALL(__NR_futex_wait, sys_futex_wait)
+#define __NR_futex_requeue 456
+__SYSCALL(__NR_futex_requeue, sys_futex_requeue)
 
 #undef __NR_syscalls
-#define __NR_syscalls 456
+#define __NR_syscalls 457
 
 /*
  * 32 bit systems traditionally used different
index dde9b74db9affe2caf197ee01b49d4b40cd8fb2e..8200d86d30e196848525c8dbd2883a88f67b3c2c 100644 (file)
@@ -396,6 +396,44 @@ SYSCALL_DEFINE6(futex_wait,
        return ret;
 }
 
+/*
+ * sys_futex_requeue - Requeue a waiter from one futex to another
+ * @waiters:   array describing the source and destination futex
+ * @flags:     unused
+ * @nr_wake:   number of futexes to wake
+ * @nr_requeue:        number of futexes to requeue
+ *
+ * Identical to the traditional FUTEX_CMP_REQUEUE op, except it is part of the
+ * futex2 family of calls.
+ */
+
+SYSCALL_DEFINE4(futex_requeue,
+               struct futex_waitv __user *, waiters,
+               unsigned int, flags,
+               int, nr_wake,
+               int, nr_requeue)
+{
+       struct futex_vector futexes[2];
+       u32 cmpval;
+       int ret;
+
+       if (flags)
+               return -EINVAL;
+
+       if (!waiters)
+               return -EINVAL;
+
+       ret = futex_parse_waitv(futexes, waiters, 2);
+       if (ret)
+               return ret;
+
+       cmpval = futexes[0].w.val;
+
+       return futex_requeue(u64_to_user_ptr(futexes[0].w.uaddr), futexes[0].w.flags,
+                            u64_to_user_ptr(futexes[1].w.uaddr), futexes[1].w.flags,
+                            nr_wake, nr_requeue, &cmpval, 0);
+}
+
 #ifdef CONFIG_COMPAT
 COMPAT_SYSCALL_DEFINE2(set_robust_list,
                struct compat_robust_list_head __user *, head,
index 13df391194e2b3fb4fc7ef340a4f27a46a85bf46..9db51ea373b05b2abffe99fa4542c293bd61acca 100644 (file)
@@ -89,6 +89,7 @@ COND_SYSCALL_COMPAT(get_robust_list);
 COND_SYSCALL(futex_waitv);
 COND_SYSCALL(futex_wake);
 COND_SYSCALL(futex_wait);
+COND_SYSCALL(futex_requeue);
 COND_SYSCALL(kexec_load);
 COND_SYSCALL_COMPAT(kexec_load);
 COND_SYSCALL(init_module);