diff options
author | Matteo De Carlo | 2021-08-10 13:29:36 +0200 |
---|---|---|
committer | Matteo De Carlo | 2021-08-10 13:30:24 +0200 |
commit | adc11f5eaab1c8de1fdcfff8a022255a602ad3c8 (patch) | |
tree | 0ea8f2bd34de0724c3c39196199788911d068771 | |
parent | 8f7cd134918b49ccf5e66a0ebea8e72930d5d2d4 (diff) | |
download | aur-adc11f5eaab1c8de1fdcfff8a022255a602ad3c8.tar.gz |
update to 5.13.8 and futex2
-rw-r--r-- | .SRCINFO | 25 | ||||
-rw-r--r-- | 0001-futex-wait-multiple.patch | 543 | ||||
-rw-r--r-- | 0001-futex2-implement-wait-and-wake-functions.patch | 476 | ||||
-rw-r--r-- | 0002-futex-wait-multiple-proton-compatibility.patch | 53 | ||||
-rw-r--r-- | 0002-futex2-implement-vectorized-wait.patch | 850 | ||||
-rw-r--r-- | 0003-futex2-implement-requeue-operation.patch | 425 | ||||
-rw-r--r-- | 0004-futex2-documentation.patch | 279 | ||||
-rw-r--r-- | 0005-futex2-test-wake-wait.patch | 416 | ||||
-rw-r--r-- | 0006-futex2-test-timeout.patch | 129 | ||||
-rw-r--r-- | 0007-futex2-test-wouldblock.patch | 145 | ||||
-rw-r--r-- | 0008-futex2-test-waitv.patch | 303 | ||||
-rw-r--r-- | 0009-futex2-test-requeue.patch | 297 | ||||
-rw-r--r-- | 0011-futex2-enable-waitpid-for-futex2.patch | 161 | ||||
-rw-r--r-- | PKGBUILD | 36 | ||||
-rw-r--r-- | bfq-default.patch | 13 | ||||
-rw-r--r-- | config | 232 |
16 files changed, 3688 insertions, 695 deletions
@@ -1,8 +1,8 @@ pkgbase = linux-covolunablu-gaming pkgdesc = Linux - pkgver = 5.12.15.arch1 + pkgver = 5.13.8.arch1 pkgrel = 1 - url = https://github.com/archlinux/linux/commits/v5.12.15-arch1 + url = https://github.com/archlinux/linux/commits/v5.13.8-arch1 arch = x86_64 license = GPL2 makedepends = bc @@ -20,19 +20,26 @@ pkgbase = linux-covolunablu-gaming makedepends = imagemagick makedepends = git options = !strip - source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v5.12.15-arch1 + source = archlinux-linux::git+https://github.com/archlinux/linux?signed#tag=v5.13.8-arch1 source = config source = bfq-default.patch - source = 0001-futex-wait-multiple.patch - source = 0002-futex-wait-multiple-proton-compatibility.patch + source = 0001-futex2-implement-wait-and-wake-functions.patch + source = 0002-futex2-implement-vectorized-wait.patch + source = 0003-futex2-implement-requeue-operation.patch + source = 0004-futex2-documentation.patch + source = 0011-futex2-enable-waitpid-for-futex2.patch validpgpkeys = ABAF11C65A2970B130ABE3C479BE3E4300411886 validpgpkeys = 647F28654894E3BD457199BE38DBBDC86092693E validpgpkeys = A2FF3A36AAA56654109064AB19802F8B0D70FC30 + validpgpkeys = C7E7849466FE2358343588377258734B41C31549 sha256sums = SKIP - sha256sums = 828d90d788ad44ba1480486081afb3ec730de5b48dfe344662043940a0b42cdf - sha256sums = 136fd376e27fd8503f0ea2c7c3df645fea60a9c05286b53e2bceb7ff8c1d0201 - sha256sums = cb37801751ea51bc7e784331132f9390b61e477491f103bec3b48f1e751c79b7 - sha256sums = bbbbc90c25659c16f2697b509a15a3969bf0dd277e81b44718a8149e61b51dbc + sha256sums = fcfb29005032125010bcf18ce2f177af7c84c74cff729de8f0cc3e4a552a59a4 + sha256sums = f6701a4b9ed60ad98396606a4c7db26c7197e76d00a28f5299d2567bf6d17d3d + sha256sums = 695af5865c0048ccc2a458a151607cb609642ad295b9f562440f7cdec7dffae2 + sha256sums = a8183948f375ceb4ac4623531a97aa885b3e4403e50e02c4698af5aaade05bb8 + sha256sums = 2a8c8ed6607150a4ab25db3320b91d15d9693c55b7b01fbbb00d4b323b8a1230 + sha256sums = 91e604ce4fb59df365ad88219269a57bbf09811b0a7ff4833b3fab072ad5b038 + sha256sums = c71f09b597b5f97895421dba2e7d76e4fb4338c6b18ed51f5a09e0775f749b4f pkgname = linux-covolunablu-gaming pkgdesc = The Linux kernel and modules; it includes BFQ as default scheduler and the steam fsync_v1 patches for proton diff --git a/0001-futex-wait-multiple.patch b/0001-futex-wait-multiple.patch deleted file mode 100644 index 489144dbb531..000000000000 --- a/0001-futex-wait-multiple.patch +++ /dev/null @@ -1,543 +0,0 @@ -From 7b5df0248ce255ef5b7204d65a7b3783ebb76a3d Mon Sep 17 00:00:00 2001 -From: Gabriel Krisman Bertazi <krisman@collabora.com> -Date: Fri, 13 Dec 2019 11:08:02 -0300 -Subject: [PATCH 1/2] futex: Implement mechanism to wait on any of several - futexes -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a new futex operation, called FUTEX_WAIT_MULTIPLE, which allows -a thread to wait on several futexes at the same time, and be awoken by -any of them. In a sense, it implements one of the features that was -supported by pooling on the old FUTEX_FD interface. - -The use case lies in the Wine implementation of the Windows NT interface -WaitMultipleObjects. This Windows API function allows a thread to sleep -waiting on the first of a set of event sources (mutexes, timers, signal, -console input, etc) to signal. Considering this is a primitive -synchronization operation for Windows applications, being able to quickly -signal events on the producer side, and quickly go to sleep on the -consumer side is essential for good performance of those running over Wine. - -Wine developers have an implementation that uses eventfd, but it suffers -from FD exhaustion (there is applications that go to the order of -multi-milion FDs), and higher CPU utilization than this new operation. - -The futex list is passed as an array of `struct futex_wait_block` -(pointer, value, bitset) to the kernel, which will enqueue all of them -and sleep if none was already triggered. It returns a hint of which -futex caused the wake up event to userspace, but the hint doesn't -guarantee that is the only futex triggered. Before calling the syscall -again, userspace should traverse the list, trying to re-acquire any of -the other futexes, to prevent an immediate -EWOULDBLOCK return code from -the kernel. - -This was tested using three mechanisms: - -1) By reimplementing FUTEX_WAIT in terms of FUTEX_WAIT_MULTIPLE and -running the unmodified tools/testing/selftests/futex and a full linux -distro on top of this kernel. - -2) By an example code that exercises the FUTEX_WAIT_MULTIPLE path on a -multi-threaded, event-handling setup. - -3) By running the Wine fsync implementation and executing multi-threaded -applications, in particular modern games, on top of this implementation. - -Changes were tested for the following ABIs: x86_64, i386 and x32. -Support for x32 applications is not implemented since it would -take a major rework adding a new entry point and splitting the current -futex 64 entry point in two and we can't change the current x32 syscall -number without breaking user space compatibility. - -CC: Steven Rostedt <rostedt@goodmis.org> -Cc: Richard Yao <ryao@gentoo.org> -Cc: Thomas Gleixner <tglx@linutronix.de> -Cc: Peter Zijlstra <peterz@infradead.org> -Co-developed-by: Zebediah Figura <z.figura12@gmail.com> -Signed-off-by: Zebediah Figura <z.figura12@gmail.com> -Co-developed-by: Steven Noonan <steven@valvesoftware.com> -Signed-off-by: Steven Noonan <steven@valvesoftware.com> -Co-developed-by: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com> -Signed-off-by: Pierre-Loup A. Griffais <pgriffais@valvesoftware.com> -Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.com> -[Added compatibility code] -Co-developed-by: André Almeida <andrealmeid@collabora.com> -Signed-off-by: André Almeida <andrealmeid@collabora.com> - -Adjusted for v5.9: Removed `put_futex_key` calls. ---- - include/uapi/linux/futex.h | 20 +++ - kernel/futex.c | 352 ++++++++++++++++++++++++++++++++++++- - 2 files changed, 370 insertions(+), 2 deletions(-) - -diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h -index a89eb0accd5e2..580001e89c6ca 100644 ---- a/include/uapi/linux/futex.h -+++ b/include/uapi/linux/futex.h -@@ -21,6 +21,7 @@ - #define FUTEX_WAKE_BITSET 10 - #define FUTEX_WAIT_REQUEUE_PI 11 - #define FUTEX_CMP_REQUEUE_PI 12 -+#define FUTEX_WAIT_MULTIPLE 13 - - #define FUTEX_PRIVATE_FLAG 128 - #define FUTEX_CLOCK_REALTIME 256 -@@ -40,6 +41,8 @@ - FUTEX_PRIVATE_FLAG) - #define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ - FUTEX_PRIVATE_FLAG) -+#define FUTEX_WAIT_MULTIPLE_PRIVATE (FUTEX_WAIT_MULTIPLE | \ -+ FUTEX_PRIVATE_FLAG) - - /* - * Support for robust futexes: the kernel cleans up held futexes at -@@ -150,4 +153,21 @@ struct robust_list_head { - (((op & 0xf) << 28) | ((cmp & 0xf) << 24) \ - | ((oparg & 0xfff) << 12) | (cmparg & 0xfff)) - -+/* -+ * Maximum number of multiple futexes to wait for -+ */ -+#define FUTEX_MULTIPLE_MAX_COUNT 128 -+ -+/** -+ * struct futex_wait_block - Block of futexes to be waited for -+ * @uaddr: User address of the futex -+ * @val: Futex value expected by userspace -+ * @bitset: Bitset for the optional bitmasked wakeup -+ */ -+struct futex_wait_block { -+ __u32 __user *uaddr; -+ __u32 val; -+ __u32 bitset; -+}; -+ - #endif /* _UAPI_LINUX_FUTEX_H */ -diff --git a/kernel/futex.c b/kernel/futex.c -index a5876694a60eb..6f4bea76df460 100644 ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -197,6 +197,8 @@ struct futex_pi_state { - * @rt_waiter: rt_waiter storage for use with requeue_pi - * @requeue_pi_key: the requeue_pi target futex key - * @bitset: bitset for the optional bitmasked wakeup -+ * @uaddr: userspace address of futex -+ * @uval: expected futex's value - * - * We use this hashed waitqueue, instead of a normal wait_queue_entry_t, so - * we can wake only the relevant ones (hashed queues may be shared). -@@ -219,6 +221,8 @@ struct futex_q { - struct rt_mutex_waiter *rt_waiter; - union futex_key *requeue_pi_key; - u32 bitset; -+ u32 __user *uaddr; -+ u32 uval; - } __randomize_layout; - - static const struct futex_q futex_q_init = { -@@ -2304,6 +2308,29 @@ static int unqueue_me(struct futex_q *q) - return ret; - } - -+/** -+ * unqueue_multiple() - Remove several futexes from their futex_hash_bucket -+ * @q: The list of futexes to unqueue -+ * @count: Number of futexes in the list -+ * -+ * Helper to unqueue a list of futexes. This can't fail. -+ * -+ * Return: -+ * - >=0 - Index of the last futex that was awoken; -+ * - -1 - If no futex was awoken -+ */ -+static int unqueue_multiple(struct futex_q *q, int count) -+{ -+ int ret = -1; -+ int i; -+ -+ for (i = 0; i < count; i++) { -+ if (!unqueue_me(&q[i])) -+ ret = i; -+ } -+ return ret; -+} -+ - /* - * PI futexes can not be requeued and must remove themself from the - * hash bucket. The hash bucket lock (i.e. lock_ptr) is held on entry -@@ -2662,6 +2689,205 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, - return ret; - } - -+/** -+ * futex_wait_multiple_setup() - Prepare to wait and enqueue multiple futexes -+ * @qs: The corresponding futex list -+ * @count: The size of the lists -+ * @flags: Futex flags (FLAGS_SHARED, etc.) -+ * @awaken: Index of the last awoken futex -+ * -+ * Prepare multiple futexes in a single step and enqueue them. This may fail if -+ * the futex list is invalid or if any futex was already awoken. On success the -+ * task is ready to interruptible sleep. -+ * -+ * Return: -+ * - 1 - One of the futexes was awaken by another thread -+ * - 0 - Success -+ * - <0 - -EFAULT, -EWOULDBLOCK or -EINVAL -+ */ -+static int futex_wait_multiple_setup(struct futex_q *qs, int count, -+ unsigned int flags, int *awaken) -+{ -+ struct futex_hash_bucket *hb; -+ int ret, i; -+ u32 uval; -+ -+ /* -+ * Enqueuing multiple futexes is tricky, because we need to -+ * enqueue each futex in the list before dealing with the next -+ * one to avoid deadlocking on the hash bucket. But, before -+ * enqueuing, we need to make sure that current->state is -+ * TASK_INTERRUPTIBLE, so we don't absorb any awake events, which -+ * cannot be done before the get_futex_key of the next key, -+ * because it calls get_user_pages, which can sleep. Thus, we -+ * fetch the list of futexes keys in two steps, by first pinning -+ * all the memory keys in the futex key, and only then we read -+ * each key and queue the corresponding futex. -+ */ -+retry: -+ for (i = 0; i < count; i++) { -+ qs[i].key = FUTEX_KEY_INIT; -+ ret = get_futex_key(qs[i].uaddr, flags & FLAGS_SHARED, -+ &qs[i].key, FUTEX_READ); -+ if (unlikely(ret)) { -+ return ret; -+ } -+ } -+ -+ set_current_state(TASK_INTERRUPTIBLE); -+ -+ for (i = 0; i < count; i++) { -+ struct futex_q *q = &qs[i]; -+ -+ hb = queue_lock(q); -+ -+ ret = get_futex_value_locked(&uval, q->uaddr); -+ if (ret) { -+ /* -+ * We need to try to handle the fault, which -+ * cannot be done without sleep, so we need to -+ * undo all the work already done, to make sure -+ * we don't miss any wake ups. Therefore, clean -+ * up, handle the fault and retry from the -+ * beginning. -+ */ -+ queue_unlock(hb); -+ -+ /* -+ * Keys 0..(i-1) are implicitly put -+ * on unqueue_multiple. -+ */ -+ *awaken = unqueue_multiple(qs, i); -+ -+ __set_current_state(TASK_RUNNING); -+ -+ /* -+ * On a real fault, prioritize the error even if -+ * some other futex was awoken. Userspace gave -+ * us a bad address, -EFAULT them. -+ */ -+ ret = get_user(uval, q->uaddr); -+ if (ret) -+ return ret; -+ -+ /* -+ * Even if the page fault was handled, If -+ * something was already awaken, we can safely -+ * give up and succeed to give a hint for userspace to -+ * acquire the right futex faster. -+ */ -+ if (*awaken >= 0) -+ return 1; -+ -+ goto retry; -+ } -+ -+ if (uval != q->uval) { -+ queue_unlock(hb); -+ -+ /* -+ * If something was already awaken, we can -+ * safely ignore the error and succeed. -+ */ -+ *awaken = unqueue_multiple(qs, i); -+ __set_current_state(TASK_RUNNING); -+ if (*awaken >= 0) -+ return 1; -+ -+ return -EWOULDBLOCK; -+ } -+ -+ /* -+ * The bucket lock can't be held while dealing with the -+ * next futex. Queue each futex at this moment so hb can -+ * be unlocked. -+ */ -+ queue_me(&qs[i], hb); -+ } -+ return 0; -+} -+ -+/** -+ * futex_wait_multiple() - Prepare to wait on and enqueue several futexes -+ * @qs: The list of futexes to wait on -+ * @op: Operation code from futex's syscall -+ * @count: The number of objects -+ * @abs_time: Timeout before giving up and returning to userspace -+ * -+ * Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function -+ * sleeps on a group of futexes and returns on the first futex that -+ * triggered, or after the timeout has elapsed. -+ * -+ * Return: -+ * - >=0 - Hint to the futex that was awoken -+ * - <0 - On error -+ */ -+static int futex_wait_multiple(struct futex_q *qs, int op, -+ u32 count, ktime_t *abs_time) -+{ -+ struct hrtimer_sleeper timeout, *to; -+ int ret, flags = 0, hint = 0; -+ unsigned int i; -+ -+ if (!(op & FUTEX_PRIVATE_FLAG)) -+ flags |= FLAGS_SHARED; -+ -+ if (op & FUTEX_CLOCK_REALTIME) -+ flags |= FLAGS_CLOCKRT; -+ -+ to = futex_setup_timer(abs_time, &timeout, flags, 0); -+ while (1) { -+ ret = futex_wait_multiple_setup(qs, count, flags, &hint); -+ if (ret) { -+ if (ret > 0) { -+ /* A futex was awaken during setup */ -+ ret = hint; -+ } -+ break; -+ } -+ -+ if (to) -+ hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); -+ -+ /* -+ * Avoid sleeping if another thread already tried to -+ * wake us. -+ */ -+ for (i = 0; i < count; i++) { -+ if (plist_node_empty(&qs[i].list)) -+ break; -+ } -+ -+ if (i == count && (!to || to->task)) -+ freezable_schedule(); -+ -+ ret = unqueue_multiple(qs, count); -+ -+ __set_current_state(TASK_RUNNING); -+ -+ if (ret >= 0) -+ break; -+ if (to && !to->task) { -+ ret = -ETIMEDOUT; -+ break; -+ } else if (signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ /* -+ * The final case is a spurious wakeup, for -+ * which just retry. -+ */ -+ } -+ -+ if (to) { -+ hrtimer_cancel(&to->timer); -+ destroy_hrtimer_on_stack(&to->timer); -+ } -+ -+ return ret; -+} -+ - static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, - ktime_t *abs_time, u32 bitset) - { -@@ -3774,6 +4000,43 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, - return -ENOSYS; - } - -+/** -+ * futex_read_wait_block - Read an array of futex_wait_block from userspace -+ * @uaddr: Userspace address of the block -+ * @count: Number of blocks to be read -+ * -+ * This function creates and allocate an array of futex_q (we zero it to -+ * initialize the fields) and then, for each futex_wait_block element from -+ * userspace, fill a futex_q element with proper values. -+ */ -+inline struct futex_q *futex_read_wait_block(u32 __user *uaddr, u32 count) -+{ -+ unsigned int i; -+ struct futex_q *qs; -+ struct futex_wait_block fwb; -+ struct futex_wait_block __user *entry = -+ (struct futex_wait_block __user *)uaddr; -+ -+ if (!count || count > FUTEX_MULTIPLE_MAX_COUNT) -+ return ERR_PTR(-EINVAL); -+ -+ qs = kcalloc(count, sizeof(*qs), GFP_KERNEL); -+ if (!qs) -+ return ERR_PTR(-ENOMEM); -+ -+ for (i = 0; i < count; i++) { -+ if (copy_from_user(&fwb, &entry[i], sizeof(fwb))) { -+ kfree(qs); -+ return ERR_PTR(-EFAULT); -+ } -+ -+ qs[i].uaddr = fwb.uaddr; -+ qs[i].uval = fwb.val; -+ qs[i].bitset = fwb.bitset; -+ } -+ -+ return qs; -+} - - SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - struct __kernel_timespec __user *, utime, u32 __user *, uaddr2, -@@ -3786,7 +4049,8 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || - cmd == FUTEX_WAIT_BITSET || -- cmd == FUTEX_WAIT_REQUEUE_PI)) { -+ cmd == FUTEX_WAIT_REQUEUE_PI || -+ cmd == FUTEX_WAIT_MULTIPLE)) { - if (unlikely(should_fail_futex(!(op & FUTEX_PRIVATE_FLAG)))) - return -EFAULT; - if (get_timespec64(&ts, utime)) -@@ -3807,6 +4071,25 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP) - val2 = (u32) (unsigned long) utime; - -+ if (cmd == FUTEX_WAIT_MULTIPLE) { -+ int ret; -+ struct futex_q *qs; -+ -+#ifdef CONFIG_X86_X32 -+ if (unlikely(in_x32_syscall())) -+ return -ENOSYS; -+#endif -+ qs = futex_read_wait_block(uaddr, val); -+ -+ if (IS_ERR(qs)) -+ return PTR_ERR(qs); -+ -+ ret = futex_wait_multiple(qs, op, val, tp); -+ kfree(qs); -+ -+ return ret; -+ } -+ - return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); - } - -@@ -3969,6 +4252,57 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, - #endif /* CONFIG_COMPAT */ - - #ifdef CONFIG_COMPAT_32BIT_TIME -+/** -+ * struct compat_futex_wait_block - Block of futexes to be waited for -+ * @uaddr: User address of the futex (compatible pointer) -+ * @val: Futex value expected by userspace -+ * @bitset: Bitset for the optional bitmasked wakeup -+ */ -+struct compat_futex_wait_block { -+ compat_uptr_t uaddr; -+ __u32 val; -+ __u32 bitset; -+}; -+ -+/** -+ * compat_futex_read_wait_block - Read an array of futex_wait_block from -+ * userspace -+ * @uaddr: Userspace address of the block -+ * @count: Number of blocks to be read -+ * -+ * This function does the same as futex_read_wait_block(), except that it -+ * converts the pointer to the futex from the compat version to the regular one. -+ */ -+inline struct futex_q *compat_futex_read_wait_block(u32 __user *uaddr, -+ u32 count) -+{ -+ unsigned int i; -+ struct futex_q *qs; -+ struct compat_futex_wait_block fwb; -+ struct compat_futex_wait_block __user *entry = -+ (struct compat_futex_wait_block __user *)uaddr; -+ -+ if (!count || count > FUTEX_MULTIPLE_MAX_COUNT) -+ return ERR_PTR(-EINVAL); -+ -+ qs = kcalloc(count, sizeof(*qs), GFP_KERNEL); -+ if (!qs) -+ return ERR_PTR(-ENOMEM); -+ -+ for (i = 0; i < count; i++) { -+ if (copy_from_user(&fwb, &entry[i], sizeof(fwb))) { -+ kfree(qs); -+ return ERR_PTR(-EFAULT); -+ } -+ -+ qs[i].uaddr = compat_ptr(fwb.uaddr); -+ qs[i].uval = fwb.val; -+ qs[i].bitset = fwb.bitset; -+ } -+ -+ return qs; -+} -+ - SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val, - struct old_timespec32 __user *, utime, u32 __user *, uaddr2, - u32, val3) -@@ -3980,7 +4314,8 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val, - - if (utime && (cmd == FUTEX_WAIT || cmd == FUTEX_LOCK_PI || - cmd == FUTEX_WAIT_BITSET || -- cmd == FUTEX_WAIT_REQUEUE_PI)) { -+ cmd == FUTEX_WAIT_REQUEUE_PI || -+ cmd == FUTEX_WAIT_MULTIPLE)) { - if (get_old_timespec32(&ts, utime)) - return -EFAULT; - if (!timespec64_valid(&ts)) -@@ -3995,6 +4330,19 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val, - cmd == FUTEX_CMP_REQUEUE_PI || cmd == FUTEX_WAKE_OP) - val2 = (int) (unsigned long) utime; - -+ if (cmd == FUTEX_WAIT_MULTIPLE) { -+ int ret; -+ struct futex_q *qs = compat_futex_read_wait_block(uaddr, val); -+ -+ if (IS_ERR(qs)) -+ return PTR_ERR(qs); -+ -+ ret = futex_wait_multiple(qs, op, val, tp); -+ kfree(qs); -+ -+ return ret; -+ } -+ - return do_futex(uaddr, op, val, tp, uaddr2, val2, val3); - } - #endif /* CONFIG_COMPAT_32BIT_TIME */ diff --git a/0001-futex2-implement-wait-and-wake-functions.patch b/0001-futex2-implement-wait-and-wake-functions.patch new file mode 100644 index 000000000000..c7704bd259c7 --- /dev/null +++ b/0001-futex2-implement-wait-and-wake-functions.patch @@ -0,0 +1,476 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 48A1BC07E99 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:04 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 2E66E61468 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:04 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S229910AbhGIAQp (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:16:45 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38090 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229497AbhGIAQo (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:16:44 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 40D3FC061574; + Thu, 8 Jul 2021 17:14:02 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 3C9451F41516 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 01/11] futex2: Implement wait and wake functions +Date: Thu, 8 Jul 2021 21:13:18 -0300 +Message-Id: <20210709001328.329716-2-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Create a new set of futex syscalls known as futex2. This new interface +is aimed to expand it with new functionalities without modifying the +current complex interface. + +Implement wait and wake functions with support for 32 sized futexes: + +- futex_wait(void *uaddr, unsigned int val, unsigned int flags, + struct timespec *timo) + + The user thread is put to sleep, waiting for a futex_wake() at uaddr, + if the value at *uaddr is the same as val (otherwise, the syscall + returns immediately with -EAGAIN). timo is an optional timeout value + for the operation. + + Return 0 on success, error code otherwise. + + - futex_wake(void *uaddr, unsigned long nr_wake, unsigned int flags) + + Wake `nr_wake` threads waiting at uaddr. + + Return the number of woken threads on success, error code otherwise. + +** The `flag` argument + + The flag is used to specify the size of the futex word + (FUTEX_[8, 16, 32, 64]). It's mandatory to define one. + + By default, the timeout uses a monotonic clock, but can be used as a + realtime one by using the FUTEX_REALTIME_CLOCK flag. + + By default, futexes are of the private type, that means that this user + address will be accessed by threads that shares the same memory region. + This allows for some internal optimizations, so they are faster. + However, if the address needs to be shared with different processes + (like using `mmap()` or `shm()`), they need to be defined as shared and + the flag FUTEX_SHARED_FLAG is used to set that. + + By default, the operation has no NUMA-awareness, meaning that the user + can't choose the memory node where the kernel side futex data will be + stored. The user can choose the node where it wants to operate by + setting the FUTEX_NUMA_FLAG and using the following structure (where X + can be 8, 16, or 32, 64): + + struct futexX_numa { + __uX value; + __sX hint; + }; + + This structure should be passed at the `void *uaddr` of futex + functions. The address of the structure will be used to be waited/waken + on, and the `value` will be compared to `val` as usual. The `hint` + member is used to defined which node the futex will use. When waiting, + the futex will be registered on a kernel-side table stored on that + node; when waking, the futex will be searched for on that given table. + That means that there's no redundancy between tables, and the wrong + `hint` value will led to undesired behavior. Userspace is responsible + for dealing with node migrations issues that may occur. `hint` can + range from [0, MAX_NUMA_NODES], for specifying a node, or -1, to use + the same node the current process is using. + + When not using FUTEX_NUMA_FLAG on a NUMA system, the futex will be + stored on a global table on some node, defined at compilation time. + +** The `timo` argument + +As per the Y2038 work done in the kernel, new interfaces shouldn't add +timeout options known to be buggy. Given that, `timo` should be a 64bit +timeout at all platforms, using an absolute timeout value. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + arch/x86/entry/syscalls/syscall_32.tbl | 2 + + arch/x86/entry/syscalls/syscall_64.tbl | 2 + + include/linux/compat.h | 4 + + include/linux/futex.h | 21 +++++ + include/linux/syscalls.h | 6 ++ + include/uapi/asm-generic/unistd.h | 7 +- + include/uapi/linux/futex.h | 4 +- + init/Kconfig | 7 ++ + kernel/Makefile | 1 + + kernel/futex.c | 23 +----- + kernel/futex2.c | 103 +++++++++++++++++++++++++ + kernel/sys_ni.c | 5 ++ + 12 files changed, 163 insertions(+), 22 deletions(-) + create mode 100644 kernel/futex2.c + +diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl +index 4bbc267fb36b..e3b827a9c094 100644 +--- a/arch/x86/entry/syscalls/syscall_32.tbl ++++ b/arch/x86/entry/syscalls/syscall_32.tbl +@@ -451,3 +451,5 @@ + 444 i386 landlock_create_ruleset sys_landlock_create_ruleset + 445 i386 landlock_add_rule sys_landlock_add_rule + 446 i386 landlock_restrict_self sys_landlock_restrict_self ++447 i386 futex_wait sys_futex_wait compat_sys_futex_wait ++448 i386 futex_wake sys_futex_wake +diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl +index ce18119ea0d0..63b447255df2 100644 +--- a/arch/x86/entry/syscalls/syscall_64.tbl ++++ b/arch/x86/entry/syscalls/syscall_64.tbl +@@ -368,6 +368,8 @@ + 444 common landlock_create_ruleset sys_landlock_create_ruleset + 445 common landlock_add_rule sys_landlock_add_rule + 446 common landlock_restrict_self sys_landlock_restrict_self ++447 common futex_wait sys_futex_wait ++448 common futex_wake sys_futex_wake + + # + # Due to a historical design error, certain syscalls are numbered differently +diff --git a/include/linux/compat.h b/include/linux/compat.h +index 8855b1b702b2..5a910e0c437a 100644 +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -692,6 +692,10 @@ asmlinkage long + compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, + compat_size_t __user *len_ptr); + ++/* kernel/futex2.c */ ++asmlinkage long compat_sys_futex_wait(void __user *uaddr, compat_u64 val, ++ unsigned int flags, ++ struct __kernel_timespec __user *timo); + /* kernel/itimer.c */ + asmlinkage long compat_sys_getitimer(int which, + struct old_itimerval32 __user *it); +diff --git a/include/linux/futex.h b/include/linux/futex.h +index b70df27d7e85..f0eaa05ec8bc 100644 +--- a/include/linux/futex.h ++++ b/include/linux/futex.h +@@ -77,6 +77,27 @@ void futex_exec_release(struct task_struct *tsk); + + long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + u32 __user *uaddr2, u32 val2, u32 val3); ++ ++int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset); ++int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, ++ u32 bitset); ++ ++/* ++ * Futex flags used to encode options to functions and preserve them across ++ * restarts. ++ */ ++#ifdef CONFIG_MMU ++# define FLAGS_SHARED 0x01 ++#else ++/* ++ * NOMMU does not have per process address space. Let the compiler optimize ++ * code away. ++ */ ++# define FLAGS_SHARED 0x00 ++#endif ++#define FLAGS_CLOCKRT 0x02 ++#define FLAGS_HAS_TIMEOUT 0x04 ++ + #else + static inline void futex_init_task(struct task_struct *tsk) { } + static inline void futex_exit_recursive(struct task_struct *tsk) { } +diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h +index 050511e8f1f8..b9c2874410d0 100644 +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -623,6 +623,12 @@ asmlinkage long sys_get_robust_list(int pid, + asmlinkage long sys_set_robust_list(struct robust_list_head __user *head, + size_t len); + ++/* kernel/futex2.c */ ++asmlinkage long sys_futex_wait(void __user *uaddr, u64 val, unsigned int flags, ++ struct __kernel_timespec __user *timo); ++asmlinkage long sys_futex_wake(void __user *uaddr, unsigned int nr_wake, ++ unsigned int flags); ++ + /* kernel/hrtimer.c */ + asmlinkage long sys_nanosleep(struct __kernel_timespec __user *rqtp, + struct __kernel_timespec __user *rmtp); +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index d2a942086fcb..df9fe2e23ee0 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -872,8 +872,13 @@ __SYSCALL(__NR_landlock_add_rule, sys_landlock_add_rule) + #define __NR_landlock_restrict_self 446 + __SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self) + ++#define __NR_futex_wait 447 ++__SC_COMP(__NR_futex_wait, sys_futex_wait, compat_sys_futex_wait) ++#define __NR_futex_wake 448 ++__SYSCALL(__NR_futex_wake, sys_futex_wake) ++ + #undef __NR_syscalls +-#define __NR_syscalls 447 ++#define __NR_syscalls 449 + + /* + * 32 bit systems traditionally used different +diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h +index 235e5b2facaa..44750caa261e 100644 +--- a/include/uapi/linux/futex.h ++++ b/include/uapi/linux/futex.h +@@ -42,7 +42,9 @@ + FUTEX_PRIVATE_FLAG) + #define FUTEX_CMP_REQUEUE_PI_PRIVATE (FUTEX_CMP_REQUEUE_PI | \ + FUTEX_PRIVATE_FLAG) +- ++#define FUTEX_32 2 ++#define FUTEX_SHARED_FLAG 8 ++#define FUTEX_SIZE_MASK 0x3 + /* + * Support for robust futexes: the kernel cleans up held futexes at + * thread exit time. +diff --git a/init/Kconfig b/init/Kconfig +index a61c92066c2e..d87629ec7e48 100644 +--- a/init/Kconfig ++++ b/init/Kconfig +@@ -1555,6 +1555,13 @@ config FUTEX + support for "fast userspace mutexes". The resulting kernel may not + run glibc-based applications correctly. + ++config FUTEX2 ++ bool "Enable futex2 support" if EXPERT ++ depends on FUTEX ++ default y ++ help ++ Support for futex2 interface. ++ + config FUTEX_PI + bool + depends on FUTEX && RT_MUTEXES +diff --git a/kernel/Makefile b/kernel/Makefile +index 4df609be42d0..1eaf2af50283 100644 +--- a/kernel/Makefile ++++ b/kernel/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_PROFILING) += profile.o + obj-$(CONFIG_STACKTRACE) += stacktrace.o + obj-y += time/ + obj-$(CONFIG_FUTEX) += futex.o ++obj-$(CONFIG_FUTEX2) += futex2.o + obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o + obj-$(CONFIG_SMP) += smp.o + ifneq ($(CONFIG_SMP),y) +diff --git a/kernel/futex.c b/kernel/futex.c +index 2ecb07575055..ef7131bd8bc4 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -150,22 +150,6 @@ + static int __read_mostly futex_cmpxchg_enabled; + #endif + +-/* +- * Futex flags used to encode options to functions and preserve them across +- * restarts. +- */ +-#ifdef CONFIG_MMU +-# define FLAGS_SHARED 0x01 +-#else +-/* +- * NOMMU does not have per process address space. Let the compiler optimize +- * code away. +- */ +-# define FLAGS_SHARED 0x00 +-#endif +-#define FLAGS_CLOCKRT 0x02 +-#define FLAGS_HAS_TIMEOUT 0x04 +- + /* + * Priority Inheritance state: + */ +@@ -1588,8 +1572,7 @@ double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) + /* + * Wake up waiters matching bitset queued on this futex (uaddr). + */ +-static int +-futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) ++int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) + { + struct futex_hash_bucket *hb; + struct futex_q *this, *next; +@@ -2676,8 +2659,8 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags, + return ret; + } + +-static int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, +- ktime_t *abs_time, u32 bitset) ++int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, ++ ktime_t *abs_time, u32 bitset) + { + struct hrtimer_sleeper timeout, *to; + struct restart_block *restart; +diff --git a/kernel/futex2.c b/kernel/futex2.c +new file mode 100644 +index 000000000000..990c665280fd +--- /dev/null ++++ b/kernel/futex2.c +@@ -0,0 +1,103 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * futex2 system call interface by André Almeida <andrealmeid@collabora.com> ++ * ++ * Copyright 2021 Collabora Ltd. ++ */ ++ ++#include <asm/futex.h> ++ ++#include <linux/syscalls.h> ++ ++/* ++ * Set of flags that futex2 accepts ++ */ ++#define FUTEX2_MASK (FUTEX_SIZE_MASK | FUTEX_SHARED_FLAG | FUTEX_CLOCK_REALTIME) ++ ++static long ksys_futex_wait(void __user *uaddr, u64 val, unsigned int flags, ++ struct __kernel_timespec __user *timo) ++{ ++ unsigned int size = flags & FUTEX_SIZE_MASK, futex_flags = 0; ++ ktime_t *kt = NULL, time; ++ struct timespec64 ts; ++ ++ if (flags & ~FUTEX2_MASK) ++ return -EINVAL; ++ ++ if (flags & FUTEX_SHARED_FLAG) ++ futex_flags |= FLAGS_SHARED; ++ ++ if (flags & FUTEX_CLOCK_REALTIME) ++ futex_flags |= FLAGS_CLOCKRT; ++ ++ if (size != FUTEX_32) ++ return -EINVAL; ++ ++ if (timo) { ++ if (get_timespec64(&ts, timo)) ++ return -EFAULT; ++ ++ if (!timespec64_valid(&ts)) ++ return -EINVAL; ++ ++ time = timespec64_to_ktime(ts); ++ kt = &time; ++ } ++ ++ return futex_wait(uaddr, futex_flags, val, kt, FUTEX_BITSET_MATCH_ANY); ++} ++ ++/** ++ * sys_futex_wait - Wait on a futex address if (*uaddr) == val ++ * @uaddr: User address of futex ++ * @val: Expected value of futex ++ * @flags: Specify the size of futex and the clockid ++ * @timo: Optional absolute timeout. ++ * ++ * The user thread is put to sleep, waiting for a futex_wake() at uaddr, if the ++ * value at *uaddr is the same as val (otherwise, the syscall returns ++ * immediately with -EAGAIN). ++ * ++ * Returns 0 on success, error code otherwise. ++ */ ++SYSCALL_DEFINE4(futex_wait, void __user *, uaddr, u64, val, unsigned int, flags, ++ struct __kernel_timespec __user *, timo) ++{ ++ return ksys_futex_wait(uaddr, val, flags, timo); ++} ++ ++#ifdef CONFIG_COMPAT ++COMPAT_SYSCALL_DEFINE4(futex_wait, void __user *, uaddr, compat_u64, val, ++ unsigned int, flags, ++ struct __kernel_timespec __user *, timo) ++{ ++ return ksys_futex_wait(uaddr, val, flags, timo); ++} ++#endif ++ ++/** ++ * sys_futex_wake - Wake a number of futexes waiting on an address ++ * @uaddr: Address of futex to be woken up ++ * @nr_wake: Number of futexes waiting in uaddr to be woken up ++ * @flags: Flags for size and shared ++ * ++ * Wake `nr_wake` threads waiting at uaddr. ++ * ++ * Returns the number of woken threads on success, error code otherwise. ++ */ ++SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake, ++ unsigned int, flags) ++{ ++ unsigned int size = flags & FUTEX_SIZE_MASK, futex_flags = 0; ++ ++ if (flags & ~FUTEX2_MASK) ++ return -EINVAL; ++ ++ if (flags & FUTEX_SHARED_FLAG) ++ futex_flags |= FLAGS_SHARED; ++ ++ if (size != FUTEX_32) ++ return -EINVAL; ++ ++ return futex_wake(uaddr, futex_flags, nr_wake, FUTEX_BITSET_MATCH_ANY); ++} +diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c +index 0ea8128468c3..dbe397eaea46 100644 +--- a/kernel/sys_ni.c ++++ b/kernel/sys_ni.c +@@ -151,6 +151,11 @@ COND_SYSCALL_COMPAT(set_robust_list); + COND_SYSCALL(get_robust_list); + COND_SYSCALL_COMPAT(get_robust_list); + ++/* kernel/futex2.c */ ++COND_SYSCALL(futex_wait); ++COND_SYSCALL_COMPAT(futex_wait); ++COND_SYSCALL(futex_wake); ++ + /* kernel/hrtimer.c */ + + /* kernel/itimer.c */ +-- +2.32.0 + + diff --git a/0002-futex-wait-multiple-proton-compatibility.patch b/0002-futex-wait-multiple-proton-compatibility.patch deleted file mode 100644 index 040bb6a1e535..000000000000 --- a/0002-futex-wait-multiple-proton-compatibility.patch +++ /dev/null @@ -1,53 +0,0 @@ -From ccdddb50d330d2ee1a4d2cbfdd27bdd7fb10eec3 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> -Date: Fri, 7 Feb 2020 23:28:02 -0300 -Subject: [PATCH 2/2] futex: Add Proton compatibility code - ---- - include/uapi/linux/futex.h | 2 +- - kernel/futex.c | 5 +++-- - 2 files changed, 4 insertions(+), 3 deletions(-) - -diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h -index 580001e89c6ca..a3e760886b8e7 100644 ---- a/include/uapi/linux/futex.h -+++ b/include/uapi/linux/futex.h -@@ -21,7 +21,7 @@ - #define FUTEX_WAKE_BITSET 10 - #define FUTEX_WAIT_REQUEUE_PI 11 - #define FUTEX_CMP_REQUEUE_PI 12 --#define FUTEX_WAIT_MULTIPLE 13 -+#define FUTEX_WAIT_MULTIPLE 31 - - #define FUTEX_PRIVATE_FLAG 128 - #define FUTEX_CLOCK_REALTIME 256 -diff --git a/kernel/futex.c b/kernel/futex.c -index 6f4bea76df460..03d89fe7b8392 100644 ---- a/kernel/futex.c -+++ b/kernel/futex.c -@@ -4059,7 +4059,7 @@ SYSCALL_DEFINE6(futex, u32 __user *, uaddr, int, op, u32, val, - return -EINVAL; - - t = timespec64_to_ktime(ts); -- if (cmd == FUTEX_WAIT) -+ if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_MULTIPLE) - t = ktime_add_safe(ktime_get(), t); - tp = &t; - } -@@ -4260,6 +4260,7 @@ COMPAT_SYSCALL_DEFINE3(get_robust_list, int, pid, - */ - struct compat_futex_wait_block { - compat_uptr_t uaddr; -+ __u32 pad; - __u32 val; - __u32 bitset; - }; -@@ -4322,7 +4323,7 @@ SYSCALL_DEFINE6(futex_time32, u32 __user *, uaddr, int, op, u32, val, - return -EINVAL; - - t = timespec64_to_ktime(ts); -- if (cmd == FUTEX_WAIT) -+ if (cmd == FUTEX_WAIT || cmd == FUTEX_WAIT_MULTIPLE) - t = ktime_add_safe(ktime_get(), t); - tp = &t; - } diff --git a/0002-futex2-implement-vectorized-wait.patch b/0002-futex2-implement-vectorized-wait.patch new file mode 100644 index 000000000000..8feef67823bc --- /dev/null +++ b/0002-futex2-implement-vectorized-wait.patch @@ -0,0 +1,850 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id BDEA4C11F66 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:11 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id A3BE861467 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:11 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230024AbhGIAQw (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:16:52 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38124 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229497AbhGIAQv (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:16:51 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6E8F8C061574; + Thu, 8 Jul 2021 17:14:08 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 04F221F415F9 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 02/11] futex2: Implement vectorized wait +Date: Thu, 8 Jul 2021 21:13:19 -0300 +Message-Id: <20210709001328.329716-3-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Add support to wait on multiple futexes. This is the interface +implemented by this syscall: + +futex_waitv(struct futex_waitv *waiters, unsigned int nr_futexes, + unsigned int flags, struct timespec *timo) + +struct futex_waitv { + __u64 val; + void *uaddr; + unsigned int flags; +}; + +Given an array of struct futex_waitv, wait on each uaddr. The thread +wakes if a futex_wake() is performed at any uaddr. The syscall returns +immediately if any waiter has *uaddr != val. *timo is an optional +timeout value for the operation. The flags argument of the syscall +should be used solely for specifying the timeout clock as realtime, if +needed. Flags for shared futexes, sizes, etc. should be used on the +individual flags of each waiter. + +Returns the array index of one of the awakened futexes. There’s no given +information of how many were awakened, or any particular attribute of it +(if it’s the first awakened, if it is of the smaller index...). + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + arch/x86/entry/syscalls/syscall_32.tbl | 1 + + arch/x86/entry/syscalls/syscall_64.tbl | 1 + + include/linux/compat.h | 9 + + include/linux/futex.h | 108 ++++++-- + include/uapi/asm-generic/unistd.h | 4 +- + include/uapi/linux/futex.h | 15 ++ + kernel/futex.c | 72 +----- + kernel/futex2.c | 345 +++++++++++++++++++++++++ + kernel/sys_ni.c | 2 + + 9 files changed, 477 insertions(+), 80 deletions(-) + +diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl +index e3b827a9c094..5573437c1914 100644 +--- a/arch/x86/entry/syscalls/syscall_32.tbl ++++ b/arch/x86/entry/syscalls/syscall_32.tbl +@@ -453,3 +453,4 @@ + 446 i386 landlock_restrict_self sys_landlock_restrict_self + 447 i386 futex_wait sys_futex_wait compat_sys_futex_wait + 448 i386 futex_wake sys_futex_wake ++449 i386 futex_waitv sys_futex_waitv compat_sys_futex_waitv +diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl +index 63b447255df2..bad4aca3e9ba 100644 +--- a/arch/x86/entry/syscalls/syscall_64.tbl ++++ b/arch/x86/entry/syscalls/syscall_64.tbl +@@ -370,6 +370,7 @@ + 446 common landlock_restrict_self sys_landlock_restrict_self + 447 common futex_wait sys_futex_wait + 448 common futex_wake sys_futex_wake ++449 common futex_waitv sys_futex_waitv + + # + # Due to a historical design error, certain syscalls are numbered differently +diff --git a/include/linux/compat.h b/include/linux/compat.h +index 5a910e0c437a..75b90e41e05b 100644 +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -368,6 +368,12 @@ struct compat_robust_list_head { + compat_uptr_t list_op_pending; + }; + ++struct compat_futex_waitv { ++ compat_u64 val; ++ compat_uptr_t uaddr; ++ compat_uint_t flags; ++}; ++ + #ifdef CONFIG_COMPAT_OLD_SIGACTION + struct compat_old_sigaction { + compat_uptr_t sa_handler; +@@ -696,6 +702,9 @@ compat_sys_get_robust_list(int pid, compat_uptr_t __user *head_ptr, + asmlinkage long compat_sys_futex_wait(void __user *uaddr, compat_u64 val, + unsigned int flags, + struct __kernel_timespec __user *timo); ++asmlinkage long compat_sys_futex_waitv(struct compat_futex_waitv *waiters, ++ compat_uint_t nr_futexes, compat_uint_t flags, ++ struct __kernel_timespec __user *timo); + /* kernel/itimer.c */ + asmlinkage long compat_sys_getitimer(int which, + struct old_itimerval32 __user *it); +diff --git a/include/linux/futex.h b/include/linux/futex.h +index f0eaa05ec8bc..7afef5bb3da2 100644 +--- a/include/linux/futex.h ++++ b/include/linux/futex.h +@@ -29,6 +29,22 @@ struct task_struct; + #define FUT_OFF_INODE 1 /* We set bit 0 if key has a reference on inode */ + #define FUT_OFF_MMSHARED 2 /* We set bit 1 if key has a reference on mm */ + ++/* ++ * Futex flags used to encode options to functions and preserve them across ++ * restarts. ++ */ ++#ifdef CONFIG_MMU ++# define FLAGS_SHARED 0x01 ++#else ++/* ++ * NOMMU does not have per process address space. Let the compiler optimize ++ * code away. ++ */ ++# define FLAGS_SHARED 0x00 ++#endif ++#define FLAGS_CLOCKRT 0x02 ++#define FLAGS_HAS_TIMEOUT 0x04 ++ + union futex_key { + struct { + u64 i_seq; +@@ -50,6 +66,63 @@ union futex_key { + } both; + }; + ++/** ++ * struct futex_q - The hashed futex queue entry, one per waiting task ++ * @list: priority-sorted list of tasks waiting on this futex ++ * @task: the task waiting on the futex ++ * @lock_ptr: the hash bucket lock ++ * @key: the key the futex is hashed on ++ * @pi_state: optional priority inheritance state ++ * @rt_waiter: rt_waiter storage for use with requeue_pi ++ * @requeue_pi_key: the requeue_pi target futex key ++ * @bitset: bitset for the optional bitmasked wakeup ++ * ++ * We use this hashed waitqueue, instead of a normal wait_queue_entry_t, so ++ * we can wake only the relevant ones (hashed queues may be shared). ++ * ++ * A futex_q has a woken state, just like tasks have TASK_RUNNING. ++ * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. ++ * The order of wakeup is always to make the first condition true, then ++ * the second. ++ * ++ * PI futexes are typically woken before they are removed from the hash list via ++ * the rt_mutex code. See unqueue_me_pi(). ++ */ ++struct futex_q { ++ struct plist_node list; ++ ++ struct task_struct *task; ++ spinlock_t *lock_ptr; ++ union futex_key key; ++ struct futex_pi_state *pi_state; ++ struct rt_mutex_waiter *rt_waiter; ++ union futex_key *requeue_pi_key; ++ u32 bitset; ++} __randomize_layout; ++ ++/** ++ * struct futex_vector - Auxiliary struct for futex_waitv() ++ * @w: Userspace provided data ++ * @q: Kernel side data ++ * ++ * Struct used to build an array with all data need for futex_waitv() ++ */ ++struct futex_vector { ++ struct futex_waitv w; ++ struct futex_q q; ++}; ++ ++/* ++ * Hash buckets are shared by all the futex_keys that hash to the same ++ * location. Each key may have multiple futex_q structures, one for each task ++ * waiting on a futex. ++ */ ++struct futex_hash_bucket { ++ atomic_t waiters; ++ spinlock_t lock; ++ struct plist_head chain; ++} ____cacheline_aligned_in_smp; ++ + #define FUTEX_KEY_INIT (union futex_key) { .both = { .ptr = 0ULL } } + + #ifdef CONFIG_FUTEX +@@ -59,6 +132,11 @@ enum { + FUTEX_STATE_DEAD, + }; + ++enum futex_access { ++ FUTEX_READ, ++ FUTEX_WRITE ++}; ++ + static inline void futex_init_task(struct task_struct *tsk) + { + tsk->robust_list = NULL; +@@ -81,22 +159,22 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset); + int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, + u32 bitset); ++void queue_me(struct futex_q *q, struct futex_hash_bucket *hb); ++int unqueue_me(struct futex_q *q); ++void queue_unlock(struct futex_hash_bucket *hb); ++int get_futex_value_locked(u32 *dest, u32 __user *from); ++int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, ++ enum futex_access rw); ++struct futex_hash_bucket *queue_lock(struct futex_q *q); ++struct hrtimer_sleeper *futex_setup_timer(ktime_t *time, ++ struct hrtimer_sleeper *timeout, ++ int flags, u64 range_ns); + +-/* +- * Futex flags used to encode options to functions and preserve them across +- * restarts. +- */ +-#ifdef CONFIG_MMU +-# define FLAGS_SHARED 0x01 +-#else +-/* +- * NOMMU does not have per process address space. Let the compiler optimize +- * code away. +- */ +-# define FLAGS_SHARED 0x00 +-#endif +-#define FLAGS_CLOCKRT 0x02 +-#define FLAGS_HAS_TIMEOUT 0x04 ++static const struct futex_q futex_q_init = { ++ /* list gets initialized in queue_me()*/ ++ .key = FUTEX_KEY_INIT, ++ .bitset = FUTEX_BITSET_MATCH_ANY ++}; + + #else + static inline void futex_init_task(struct task_struct *tsk) { } +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index df9fe2e23ee0..57acb3a0f69f 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -876,9 +876,11 @@ __SYSCALL(__NR_landlock_restrict_self, sys_landlock_restrict_self) + __SC_COMP(__NR_futex_wait, sys_futex_wait, compat_sys_futex_wait) + #define __NR_futex_wake 448 + __SYSCALL(__NR_futex_wake, sys_futex_wake) ++#define __NR_futex_waitv 449 ++__SC_COMP(__NR_futex_waitv, sys_futex_waitv, compat_sys_futex_waitv) + + #undef __NR_syscalls +-#define __NR_syscalls 449 ++#define __NR_syscalls 450 + + /* + * 32 bit systems traditionally used different +diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h +index 44750caa261e..daa135bdedda 100644 +--- a/include/uapi/linux/futex.h ++++ b/include/uapi/linux/futex.h +@@ -45,6 +45,21 @@ + #define FUTEX_32 2 + #define FUTEX_SHARED_FLAG 8 + #define FUTEX_SIZE_MASK 0x3 ++ ++#define FUTEX_WAITV_MAX 128 ++ ++/** ++ * struct futex_waitv - A waiter for vectorized wait ++ * @val: Expected value at uaddr ++ * @uaddr: User address to wait on ++ * @flags: Flags for this waiter ++ */ ++struct futex_waitv { ++ __u64 val; ++ void __user *uaddr; ++ unsigned int flags; ++}; ++ + /* + * Support for robust futexes: the kernel cleans up held futexes at + * thread exit time. +diff --git a/kernel/futex.c b/kernel/futex.c +index ef7131bd8bc4..135782fc3461 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -171,57 +171,6 @@ struct futex_pi_state { + union futex_key key; + } __randomize_layout; + +-/** +- * struct futex_q - The hashed futex queue entry, one per waiting task +- * @list: priority-sorted list of tasks waiting on this futex +- * @task: the task waiting on the futex +- * @lock_ptr: the hash bucket lock +- * @key: the key the futex is hashed on +- * @pi_state: optional priority inheritance state +- * @rt_waiter: rt_waiter storage for use with requeue_pi +- * @requeue_pi_key: the requeue_pi target futex key +- * @bitset: bitset for the optional bitmasked wakeup +- * +- * We use this hashed waitqueue, instead of a normal wait_queue_entry_t, so +- * we can wake only the relevant ones (hashed queues may be shared). +- * +- * A futex_q has a woken state, just like tasks have TASK_RUNNING. +- * It is considered woken when plist_node_empty(&q->list) || q->lock_ptr == 0. +- * The order of wakeup is always to make the first condition true, then +- * the second. +- * +- * PI futexes are typically woken before they are removed from the hash list via +- * the rt_mutex code. See unqueue_me_pi(). +- */ +-struct futex_q { +- struct plist_node list; +- +- struct task_struct *task; +- spinlock_t *lock_ptr; +- union futex_key key; +- struct futex_pi_state *pi_state; +- struct rt_mutex_waiter *rt_waiter; +- union futex_key *requeue_pi_key; +- u32 bitset; +-} __randomize_layout; +- +-static const struct futex_q futex_q_init = { +- /* list gets initialized in queue_me()*/ +- .key = FUTEX_KEY_INIT, +- .bitset = FUTEX_BITSET_MATCH_ANY +-}; +- +-/* +- * Hash buckets are shared by all the futex_keys that hash to the same +- * location. Each key may have multiple futex_q structures, one for each task +- * waiting on a futex. +- */ +-struct futex_hash_bucket { +- atomic_t waiters; +- spinlock_t lock; +- struct plist_head chain; +-} ____cacheline_aligned_in_smp; +- + /* + * The base of the bucket array and its size are always used together + * (after initialization only in hash_futex()), so ensure that they +@@ -364,11 +313,6 @@ static inline int match_futex(union futex_key *key1, union futex_key *key2) + && key1->both.offset == key2->both.offset); + } + +-enum futex_access { +- FUTEX_READ, +- FUTEX_WRITE +-}; +- + /** + * futex_setup_timer - set up the sleeping hrtimer. + * @time: ptr to the given timeout value +@@ -379,7 +323,7 @@ enum futex_access { + * Return: Initialized hrtimer_sleeper structure or NULL if no timeout + * value given + */ +-static inline struct hrtimer_sleeper * ++inline struct hrtimer_sleeper * + futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, + int flags, u64 range_ns) + { +@@ -465,8 +409,8 @@ static u64 get_inode_sequence_number(struct inode *inode) + * + * lock_page() might sleep, the caller should not hold a spinlock. + */ +-static int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, +- enum futex_access rw) ++int get_futex_key(u32 __user *uaddr, bool fshared, union futex_key *key, ++ enum futex_access rw) + { + unsigned long address = (unsigned long)uaddr; + struct mm_struct *mm = current->mm; +@@ -698,7 +642,7 @@ static int cmpxchg_futex_value_locked(u32 *curval, u32 __user *uaddr, + return ret; + } + +-static int get_futex_value_locked(u32 *dest, u32 __user *from) ++inline int get_futex_value_locked(u32 *dest, u32 __user *from) + { + int ret; + +@@ -2173,7 +2117,7 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, + } + + /* The key must be already stored in q->key. */ +-static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) ++inline struct futex_hash_bucket *queue_lock(struct futex_q *q) + __acquires(&hb->lock) + { + struct futex_hash_bucket *hb; +@@ -2196,7 +2140,7 @@ static inline struct futex_hash_bucket *queue_lock(struct futex_q *q) + return hb; + } + +-static inline void ++inline void + queue_unlock(struct futex_hash_bucket *hb) + __releases(&hb->lock) + { +@@ -2235,7 +2179,7 @@ static inline void __queue_me(struct futex_q *q, struct futex_hash_bucket *hb) + * state is implicit in the state of woken task (see futex_wait_requeue_pi() for + * an example). + */ +-static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) ++inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) + __releases(&hb->lock) + { + __queue_me(q, hb); +@@ -2253,7 +2197,7 @@ static inline void queue_me(struct futex_q *q, struct futex_hash_bucket *hb) + * - 1 - if the futex_q was still queued (and we removed unqueued it); + * - 0 - if the futex_q was already removed by the waking thread + */ +-static int unqueue_me(struct futex_q *q) ++int unqueue_me(struct futex_q *q) + { + spinlock_t *lock_ptr; + int ret = 0; +diff --git a/kernel/futex2.c b/kernel/futex2.c +index 990c665280fd..cc1f31afb281 100644 +--- a/kernel/futex2.c ++++ b/kernel/futex2.c +@@ -7,6 +7,7 @@ + + #include <asm/futex.h> + ++#include <linux/freezer.h> + #include <linux/syscalls.h> + + /* +@@ -14,6 +15,350 @@ + */ + #define FUTEX2_MASK (FUTEX_SIZE_MASK | FUTEX_SHARED_FLAG | FUTEX_CLOCK_REALTIME) + ++/* Mask for each futex in futex_waitv list */ ++#define FUTEXV_WAITER_MASK (FUTEX_SIZE_MASK | FUTEX_SHARED_FLAG) ++ ++/* Mask for sys_futex_waitv flag */ ++#define FUTEXV_MASK (FUTEX_CLOCK_REALTIME) ++ ++/** ++ * unqueue_multiple() - Remove various futexes from their futex_hash_bucket ++ * @v: The list of futexes to unqueue ++ * @count: Number of futexes in the list ++ * ++ * Helper to unqueue a list of futexes. This can't fail. ++ * ++ * Return: ++ * - >=0 - Index of the last futex that was awoken; ++ * - -1 - No futex was awoken ++ */ ++static int unqueue_multiple(struct futex_vector *v, int count) ++{ ++ int ret = -1, i; ++ ++ for (i = 0; i < count; i++) { ++ if (!unqueue_me(&v[i].q)) ++ ret = i; ++ } ++ ++ return ret; ++} ++ ++/** ++ * futex_wait_multiple_setup() - Prepare to wait and enqueue multiple futexes ++ * @vs: The corresponding futex list ++ * @count: The size of the list ++ * @awaken: Index of the last awoken futex (return parameter) ++ * ++ * Prepare multiple futexes in a single step and enqueue them. This may fail if ++ * the futex list is invalid or if any futex was already awoken. On success the ++ * task is ready to interruptible sleep. ++ * ++ * Return: ++ * - 1 - One of the futexes was awaken by another thread ++ * - 0 - Success ++ * - <0 - -EFAULT, -EWOULDBLOCK or -EINVAL ++ */ ++static int futex_wait_multiple_setup(struct futex_vector *vs, int count, int *awaken) ++{ ++ struct futex_hash_bucket *hb; ++ int ret, i; ++ u32 uval; ++ ++ /* ++ * Enqueuing multiple futexes is tricky, because we need to ++ * enqueue each futex in the list before dealing with the next ++ * one to avoid deadlocking on the hash bucket. But, before ++ * enqueuing, we need to make sure that current->state is ++ * TASK_INTERRUPTIBLE, so we don't absorb any awake events, which ++ * cannot be done before the get_futex_key of the next key, ++ * because it calls get_user_pages, which can sleep. Thus, we ++ * fetch the list of futexes keys in two steps, by first pinning ++ * all the memory keys in the futex key, and only then we read ++ * each key and queue the corresponding futex. ++ */ ++retry: ++ for (i = 0; i < count; i++) { ++ ret = get_futex_key(vs[i].w.uaddr, ++ vs[i].w.flags & FUTEX_SHARED_FLAG, ++ &vs[i].q.key, FUTEX_READ); ++ if (unlikely(ret)) ++ return ret; ++ } ++ ++ set_current_state(TASK_INTERRUPTIBLE); ++ ++ for (i = 0; i < count; i++) { ++ struct futex_q *q = &vs[i].q; ++ struct futex_waitv *waitv = &vs[i].w; ++ ++ hb = queue_lock(q); ++ ret = get_futex_value_locked(&uval, waitv->uaddr); ++ if (ret) { ++ /* ++ * We need to try to handle the fault, which ++ * cannot be done without sleep, so we need to ++ * undo all the work already done, to make sure ++ * we don't miss any wake ups. Therefore, clean ++ * up, handle the fault and retry from the ++ * beginning. ++ */ ++ queue_unlock(hb); ++ __set_current_state(TASK_RUNNING); ++ ++ *awaken = unqueue_multiple(vs, i); ++ if (*awaken >= 0) ++ return 1; ++ ++ if (get_user(uval, (u32 __user *)waitv->uaddr)) ++ return -EINVAL; ++ ++ goto retry; ++ } ++ ++ if (uval != waitv->val) { ++ queue_unlock(hb); ++ __set_current_state(TASK_RUNNING); ++ ++ /* ++ * If something was already awaken, we can ++ * safely ignore the error and succeed. ++ */ ++ *awaken = unqueue_multiple(vs, i); ++ if (*awaken >= 0) ++ return 1; ++ ++ return -EWOULDBLOCK; ++ } ++ ++ /* ++ * The bucket lock can't be held while dealing with the ++ * next futex. Queue each futex at this moment so hb can ++ * be unlocked. ++ */ ++ queue_me(&vs[i].q, hb); ++ } ++ return 0; ++} ++ ++/** ++ * futex_wait_multiple() - Prepare to wait on and enqueue several futexes ++ * @vs: The list of futexes to wait on ++ * @count: The number of objects ++ * @to: Timeout before giving up and returning to userspace ++ * ++ * Entry point for the FUTEX_WAIT_MULTIPLE futex operation, this function ++ * sleeps on a group of futexes and returns on the first futex that ++ * triggered, or after the timeout has elapsed. ++ * ++ * Return: ++ * - >=0 - Hint to the futex that was awoken ++ * - <0 - On error ++ */ ++static int futex_wait_multiple(struct futex_vector *vs, unsigned int count, ++ struct hrtimer_sleeper *to) ++{ ++ int ret, hint = 0; ++ unsigned int i; ++ ++ while (1) { ++ ret = futex_wait_multiple_setup(vs, count, &hint); ++ if (ret) { ++ if (ret > 0) { ++ /* A futex was awaken during setup */ ++ ret = hint; ++ } ++ return ret; ++ } ++ ++ if (to) ++ hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS); ++ ++ /* ++ * Avoid sleeping if another thread already tried to ++ * wake us. ++ */ ++ for (i = 0; i < count; i++) { ++ if (plist_node_empty(&vs[i].q.list)) ++ break; ++ } ++ ++ if (i == count && (!to || to->task)) ++ freezable_schedule(); ++ ++ __set_current_state(TASK_RUNNING); ++ ++ ret = unqueue_multiple(vs, count); ++ if (ret >= 0) ++ return ret; ++ ++ if (to && !to->task) ++ return -ETIMEDOUT; ++ else if (signal_pending(current)) ++ return -ERESTARTSYS; ++ /* ++ * The final case is a spurious wakeup, for ++ * which just retry. ++ */ ++ } ++} ++ ++#ifdef CONFIG_COMPAT ++/** ++ * compat_futex_parse_waitv - Parse a waitv array from userspace ++ * @futexv: Kernel side list of waiters to be filled ++ * @uwaitv: Userspace list to be parsed ++ * @nr_futexes: Length of futexv ++ * ++ * Return: Error code on failure, pointer to a prepared futexv otherwise ++ */ ++static int compat_futex_parse_waitv(struct futex_vector *futexv, ++ struct compat_futex_waitv __user *uwaitv, ++ unsigned int nr_futexes) ++{ ++ struct compat_futex_waitv aux; ++ unsigned int i; ++ ++ for (i = 0; i < nr_futexes; i++) { ++ if (copy_from_user(&aux, &uwaitv[i], sizeof(aux))) ++ return -EFAULT; ++ ++ if ((aux.flags & ~FUTEXV_WAITER_MASK) || ++ (aux.flags & FUTEX_SIZE_MASK) != FUTEX_32) ++ return -EINVAL; ++ ++ futexv[i].w.flags = aux.flags; ++ futexv[i].w.val = aux.val; ++ futexv[i].w.uaddr = compat_ptr(aux.uaddr); ++ futexv[i].q = futex_q_init; ++ } ++ ++ return 0; ++} ++ ++COMPAT_SYSCALL_DEFINE4(futex_waitv, struct compat_futex_waitv __user *, waiters, ++ unsigned int, nr_futexes, unsigned int, flags, ++ struct __kernel_timespec __user *, timo) ++{ ++ struct hrtimer_sleeper to; ++ struct futex_vector *futexv; ++ struct timespec64 ts; ++ ktime_t time; ++ int ret; ++ ++ if (flags & ~FUTEXV_MASK) ++ return -EINVAL; ++ ++ if (!nr_futexes || nr_futexes > FUTEX_WAITV_MAX || !waiters) ++ return -EINVAL; ++ ++ if (timo) { ++ int flag_clkid = 0; ++ ++ if (get_timespec64(&ts, timo)) ++ return -EFAULT; ++ ++ if (!timespec64_valid(&ts)) ++ return -EINVAL; ++ ++ if (flags & FUTEX_CLOCK_REALTIME) ++ flag_clkid = FLAGS_CLOCKRT; ++ ++ time = timespec64_to_ktime(ts); ++ futex_setup_timer(&time, &to, flag_clkid, 0); ++ } ++ ++ futexv = kcalloc(nr_futexes, sizeof(*futexv), GFP_KERNEL); ++ if (!futexv) ++ return -ENOMEM; ++ ++ ret = compat_futex_parse_waitv(futexv, waiters, nr_futexes); ++ if (!ret) ++ ret = futex_wait_multiple(futexv, nr_futexes, timo ? &to : NULL); ++ ++ if (timo) { ++ hrtimer_cancel(&to.timer); ++ destroy_hrtimer_on_stack(&to.timer); ++ } ++ ++ kfree(futexv); ++ return ret; ++} ++#endif ++ ++static int futex_parse_waitv(struct futex_vector *futexv, ++ struct futex_waitv __user *uwaitv, ++ unsigned int nr_futexes) ++{ ++ struct futex_waitv aux; ++ unsigned int i; ++ ++ for (i = 0; i < nr_futexes; i++) { ++ if (copy_from_user(&aux, &uwaitv[i], sizeof(aux))) ++ return -EFAULT; ++ ++ if ((aux.flags & ~FUTEXV_WAITER_MASK) || ++ (aux.flags & FUTEX_SIZE_MASK) != FUTEX_32) ++ return -EINVAL; ++ ++ futexv[i].w.flags = aux.flags; ++ futexv[i].w.val = aux.val; ++ futexv[i].w.uaddr = aux.uaddr; ++ futexv[i].q = futex_q_init; ++ } ++ ++ return 0; ++} ++ ++SYSCALL_DEFINE4(futex_waitv, struct futex_waitv __user *, waiters, ++ unsigned int, nr_futexes, unsigned int, flags, ++ struct __kernel_timespec __user *, timo) ++{ ++ struct hrtimer_sleeper to; ++ struct futex_vector *futexv; ++ struct timespec64 ts; ++ ktime_t time; ++ int ret; ++ ++ if (flags & ~FUTEXV_MASK) ++ return -EINVAL; ++ ++ if (!nr_futexes || nr_futexes > FUTEX_WAITV_MAX || !waiters) ++ return -EINVAL; ++ ++ if (timo) { ++ int flag_clkid = 0; ++ ++ if (get_timespec64(&ts, timo)) ++ return -EFAULT; ++ ++ if (!timespec64_valid(&ts)) ++ return -EINVAL; ++ ++ if (flags & FUTEX_CLOCK_REALTIME) ++ flag_clkid = FLAGS_CLOCKRT; ++ ++ time = timespec64_to_ktime(ts); ++ futex_setup_timer(&time, &to, flag_clkid, 0); ++ } ++ ++ futexv = kcalloc(nr_futexes, sizeof(*futexv), GFP_KERNEL); ++ if (!futexv) ++ return -ENOMEM; ++ ++ ret = futex_parse_waitv(futexv, waiters, nr_futexes); ++ if (!ret) ++ ret = futex_wait_multiple(futexv, nr_futexes, timo ? &to : NULL); ++ ++ if (timo) { ++ hrtimer_cancel(&to.timer); ++ destroy_hrtimer_on_stack(&to.timer); ++ } ++ ++ kfree(futexv); ++ return ret; ++} ++ + static long ksys_futex_wait(void __user *uaddr, u64 val, unsigned int flags, + struct __kernel_timespec __user *timo) + { +diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c +index dbe397eaea46..93807bb7be51 100644 +--- a/kernel/sys_ni.c ++++ b/kernel/sys_ni.c +@@ -155,6 +155,8 @@ COND_SYSCALL_COMPAT(get_robust_list); + COND_SYSCALL(futex_wait); + COND_SYSCALL_COMPAT(futex_wait); + COND_SYSCALL(futex_wake); ++COND_SYSCALL(futex_waitv); ++COND_SYSCALL_COMPAT(futex_waitv); + + /* kernel/hrtimer.c */ + +-- +2.32.0 + + diff --git a/0003-futex2-implement-requeue-operation.patch b/0003-futex2-implement-requeue-operation.patch new file mode 100644 index 000000000000..dcc68de913d5 --- /dev/null +++ b/0003-futex2-implement-requeue-operation.patch @@ -0,0 +1,425 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id A4009C07E96 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:17 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 87F4261467 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:17 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230093AbhGIAQ6 (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:16:58 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38156 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S229497AbhGIAQ5 (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:16:57 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 220D4C061574; + Thu, 8 Jul 2021 17:14:15 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id C3F5E1F421A2 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 03/11] futex2: Implement requeue operation +Date: Thu, 8 Jul 2021 21:13:20 -0300 +Message-Id: <20210709001328.329716-4-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Implement requeue interface similarly to FUTEX_CMP_REQUEUE operation. + +This is the syscall implemented by this patch: + +futex_requeue(struct futex_requeue *rq1, struct futex_requeue *rq2, + unsigned int nr_wake, unsigned int nr_requeue, + u64 cmpval, unsigned int flags) + +struct futex_requeue { + void *uaddr; + unsigned int flags; +}; + +If (rq1->uaddr == cmpval), wake at rq1->uaddr a nr_wake number of +waiters and then, remove a number of nr_requeue waiters at rq1->uaddr +and add them to rq2->uaddr list. Each uaddr has its own set of flags, +that must be defined at struct futex_requeue (such as size, shared, NUMA). +The flags argument of the syscall is there just for the sake of +extensibility, and right now it needs to be zero. + +Return the number of the woken futexes + the number of requeued ones on +success, error code otherwise. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + +The original FUTEX_CMP_REQUEUE interfaces is such as follows: + +futex(*uaddr1, FUTEX_CMP_REQUEUE, nr_wake, nr_requeue, *uaddr2, cmpval); + +Given that when this interface was created they was only one type of +futex (as opposed to futex2, where there is shared, sizes, and NUMA), +there was no way to specify individual flags for uaddr1 and 2. When +FUTEX_PRIVATE was implemented, a new opcode was created as well +(FUTEX_CMP_REQUEUE_PRIVATE), but they apply both futexes, so they +should be of the same type regarding private/shared. This imposes a +limitation on the use cases of the operation, and to overcome that at futex2, +`struct futex_requeue` was created, so one can set individual flags for +each futex. This flexibility is a trade-off with performance, given that +now we need to perform two extra copy_from_user(). One alternative would +be to use the upper half of flags bits to the first one, and the bottom +half for the second futex, but this would also impose limitations, given +that we would limit by half the flags possibilities. If equal futexes +are common enough, the following extension could be added to overcome +the current performance: + +- A flag FUTEX_REQUEUE_EQUAL is added to futex2() flags; +- If futex_requeue() see this flag, that means that both futexes uses + the same set of attributes. +- Then, the function parses the flags as of futex_wait/wake(). +- *rq1 and *rq2 are used as void* (instead of struct + futex_requeue) just like wait/wake(). + +In that way, we could avoid the copy_from_user(). +--- + arch/x86/entry/syscalls/syscall_32.tbl | 1 + + arch/x86/entry/syscalls/syscall_64.tbl | 1 + + include/linux/compat.h | 10 +++ + include/linux/futex.h | 3 + + include/uapi/asm-generic/unistd.h | 4 +- + include/uapi/linux/futex.h | 10 +++ + kernel/futex.c | 18 ++-- + kernel/futex2.c | 111 +++++++++++++++++++++++++ + kernel/sys_ni.c | 2 + + 9 files changed, 150 insertions(+), 10 deletions(-) + +diff --git a/arch/x86/entry/syscalls/syscall_32.tbl b/arch/x86/entry/syscalls/syscall_32.tbl +index 5573437c1914..f02c3da76945 100644 +--- a/arch/x86/entry/syscalls/syscall_32.tbl ++++ b/arch/x86/entry/syscalls/syscall_32.tbl +@@ -454,3 +454,4 @@ + 447 i386 futex_wait sys_futex_wait compat_sys_futex_wait + 448 i386 futex_wake sys_futex_wake + 449 i386 futex_waitv sys_futex_waitv compat_sys_futex_waitv ++450 i386 futex_requeue sys_futex_requeue compat_sys_futex_requeue +diff --git a/arch/x86/entry/syscalls/syscall_64.tbl b/arch/x86/entry/syscalls/syscall_64.tbl +index bad4aca3e9ba..8815c0de5d05 100644 +--- a/arch/x86/entry/syscalls/syscall_64.tbl ++++ b/arch/x86/entry/syscalls/syscall_64.tbl +@@ -371,6 +371,7 @@ + 447 common futex_wait sys_futex_wait + 448 common futex_wake sys_futex_wake + 449 common futex_waitv sys_futex_waitv ++450 common futex_requeue sys_futex_requeue + + # + # Due to a historical design error, certain syscalls are numbered differently +diff --git a/include/linux/compat.h b/include/linux/compat.h +index 75b90e41e05b..861616de6d75 100644 +--- a/include/linux/compat.h ++++ b/include/linux/compat.h +@@ -374,6 +374,11 @@ struct compat_futex_waitv { + compat_uint_t flags; + }; + ++struct compat_futex_requeue { ++ compat_uptr_t uaddr; ++ compat_uint_t flags; ++}; ++ + #ifdef CONFIG_COMPAT_OLD_SIGACTION + struct compat_old_sigaction { + compat_uptr_t sa_handler; +@@ -705,6 +710,11 @@ asmlinkage long compat_sys_futex_wait(void __user *uaddr, compat_u64 val, + asmlinkage long compat_sys_futex_waitv(struct compat_futex_waitv *waiters, + compat_uint_t nr_futexes, compat_uint_t flags, + struct __kernel_timespec __user *timo); ++asmlinkage long compat_sys_futex_requeue(struct futex_requeue __user *rq1, ++ struct futex_requeue __user *rq2, ++ unsigned int nr_wake, ++ unsigned int nr_requeue, ++ u64 cmpval, unsigned int flags); + /* kernel/itimer.c */ + asmlinkage long compat_sys_getitimer(int which, + struct old_itimerval32 __user *it); +diff --git a/include/linux/futex.h b/include/linux/futex.h +index 7afef5bb3da2..95afac7b2f76 100644 +--- a/include/linux/futex.h ++++ b/include/linux/futex.h +@@ -159,6 +159,9 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset); + int futex_wait(u32 __user *uaddr, unsigned int flags, u32 val, ktime_t *abs_time, + u32 bitset); ++int futex_requeue(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, ++ unsigned int flags2, int nr_wake, int nr_requeue, u32 *cmpval, ++ int requeue_pi); + void queue_me(struct futex_q *q, struct futex_hash_bucket *hb); + int unqueue_me(struct futex_q *q); + void queue_unlock(struct futex_hash_bucket *hb); +diff --git a/include/uapi/asm-generic/unistd.h b/include/uapi/asm-generic/unistd.h +index 57acb3a0f69f..89a480490dca 100644 +--- a/include/uapi/asm-generic/unistd.h ++++ b/include/uapi/asm-generic/unistd.h +@@ -878,9 +878,11 @@ __SC_COMP(__NR_futex_wait, sys_futex_wait, compat_sys_futex_wait) + __SYSCALL(__NR_futex_wake, sys_futex_wake) + #define __NR_futex_waitv 449 + __SC_COMP(__NR_futex_waitv, sys_futex_waitv, compat_sys_futex_waitv) ++#define __NR_futex_requeue 450 ++__SC_COMP(__NR_futex_requeue, sys_futex_requeue, compat_sys_futex_requeue) + + #undef __NR_syscalls +-#define __NR_syscalls 450 ++#define __NR_syscalls 451 + + /* + * 32 bit systems traditionally used different +diff --git a/include/uapi/linux/futex.h b/include/uapi/linux/futex.h +index daa135bdedda..7effdd568699 100644 +--- a/include/uapi/linux/futex.h ++++ b/include/uapi/linux/futex.h +@@ -60,6 +60,16 @@ struct futex_waitv { + unsigned int flags; + }; + ++/** ++ * struct futex_requeue - Define an address and its flags for requeue operation ++ * @uaddr: User address of one of the requeue arguments ++ * @flags: Flags for this address ++ */ ++struct futex_requeue { ++ void __user *uaddr; ++ unsigned int flags; ++}; ++ + /* + * Support for robust futexes: the kernel cleans up held futexes at + * thread exit time. +diff --git a/kernel/futex.c b/kernel/futex.c +index 135782fc3461..7e6d70195d8a 100644 +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1843,9 +1843,9 @@ futex_proxy_trylock_atomic(u32 __user *pifutex, struct futex_hash_bucket *hb1, + * - >=0 - on success, the number of tasks requeued or woken; + * - <0 - on error + */ +-static int futex_requeue(u32 __user *uaddr1, unsigned int flags, +- u32 __user *uaddr2, int nr_wake, int nr_requeue, +- u32 *cmpval, int requeue_pi) ++int futex_requeue(u32 __user *uaddr1, unsigned int flags1, u32 __user *uaddr2, ++ unsigned int flags2, int nr_wake, int nr_requeue, ++ u32 *cmpval, int requeue_pi) + { + union futex_key key1 = FUTEX_KEY_INIT, key2 = FUTEX_KEY_INIT; + int task_count = 0, ret; +@@ -1895,10 +1895,10 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, + } + + retry: +- ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, FUTEX_READ); ++ ret = get_futex_key(uaddr1, flags1 & FLAGS_SHARED, &key1, FUTEX_READ); + if (unlikely(ret != 0)) + return ret; +- ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, ++ ret = get_futex_key(uaddr2, flags2 & FLAGS_SHARED, &key2, + requeue_pi ? FUTEX_WRITE : FUTEX_READ); + if (unlikely(ret != 0)) + return ret; +@@ -1930,7 +1930,7 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags, + if (ret) + return ret; + +- if (!(flags & FLAGS_SHARED)) ++ if (!(flags1 & FLAGS_SHARED)) + goto retry_private; + + goto retry; +@@ -3661,9 +3661,9 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + case FUTEX_WAKE_BITSET: + return futex_wake(uaddr, flags, val, val3); + case FUTEX_REQUEUE: +- return futex_requeue(uaddr, flags, uaddr2, val, val2, NULL, 0); ++ return futex_requeue(uaddr, flags, uaddr2, flags, val, val2, NULL, 0); + case FUTEX_CMP_REQUEUE: +- return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 0); ++ return futex_requeue(uaddr, flags, uaddr2, flags, val, val2, &val3, 0); + case FUTEX_WAKE_OP: + return futex_wake_op(uaddr, flags, uaddr2, val, val2, val3); + case FUTEX_LOCK_PI: +@@ -3680,7 +3680,7 @@ long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout, + return futex_wait_requeue_pi(uaddr, flags, val, timeout, val3, + uaddr2); + case FUTEX_CMP_REQUEUE_PI: +- return futex_requeue(uaddr, flags, uaddr2, val, val2, &val3, 1); ++ return futex_requeue(uaddr, flags, uaddr2, flags, val, val2, &val3, 1); + } + return -ENOSYS; + } +diff --git a/kernel/futex2.c b/kernel/futex2.c +index cc1f31afb281..4f6d099badec 100644 +--- a/kernel/futex2.c ++++ b/kernel/futex2.c +@@ -446,3 +446,114 @@ SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake, + + return futex_wake(uaddr, futex_flags, nr_wake, FUTEX_BITSET_MATCH_ANY); + } ++ ++#ifdef CONFIG_COMPAT ++static int compat_futex_parse_requeue(struct compat_futex_requeue __user *rq, ++ void __user **uaddr, unsigned int *flags) ++{ ++ struct compat_futex_requeue aux; ++ unsigned int futex_flags = 0; ++ ++ if (copy_from_user(&aux, rq, sizeof(*rq))) ++ return -EFAULT; ++ ++ if (aux.flags & ~FUTEXV_WAITER_MASK || ++ (aux.flags & FUTEX_SIZE_MASK) != FUTEX_32) ++ return -EINVAL; ++ ++ if (aux.flags & FUTEX_SHARED_FLAG) ++ futex_flags |= FLAGS_SHARED; ++ ++ *uaddr = compat_ptr(aux.uaddr); ++ *flags = futex_flags; ++ ++ return 0; ++} ++ ++COMPAT_SYSCALL_DEFINE6(futex_requeue, struct compat_futex_requeue __user *, rq1, ++ struct compat_futex_requeue __user *, rq2, ++ unsigned int, nr_wake, unsigned int, nr_requeue, ++ compat_u64, cmpval, unsigned int, flags) ++{ ++ void __user *uaddr1, *uaddr2; ++ unsigned int flags1, flags2; ++ u32 val = cmpval; ++ int ret; ++ ++ if (flags) ++ return -EINVAL; ++ ++ ret = compat_futex_parse_requeue(rq1, &uaddr1, &flags1); ++ if (ret) ++ return ret; ++ ++ ret = compat_futex_parse_requeue(rq2, &uaddr2, &flags2); ++ if (ret) ++ return ret; ++ ++ return futex_requeue(uaddr1, flags1, uaddr2, flags2, nr_wake, nr_requeue, &val, 0); ++} ++#endif ++ ++static int futex_parse_requeue(struct futex_requeue __user *rq, ++ void __user **uaddr, unsigned int *flags) ++{ ++ struct futex_requeue aux; ++ unsigned int futex_flags = 0; ++ ++ if (copy_from_user(&aux, rq, sizeof(*rq))) ++ return -EFAULT; ++ ++ if (aux.flags & ~FUTEXV_WAITER_MASK || ++ (aux.flags & FUTEX_SIZE_MASK) != FUTEX_32) ++ return -EINVAL; ++ ++ if (aux.flags & FUTEX_SHARED_FLAG) ++ futex_flags |= FLAGS_SHARED; ++ ++ *uaddr = aux.uaddr; ++ *flags = futex_flags; ++ ++ return 0; ++} ++ ++/** ++ * sys_futex_requeue - Wake futexes at rq1 and requeue from rq1 to rq2 ++ * @rq1: Address of futexes to be waken/dequeued ++ * @rq2: Address for the futexes to be enqueued ++ * @nr_wake: Number of futexes waiting in uaddr1 to be woken up ++ * @nr_requeue: Number of futexes to be requeued from uaddr1 to uaddr2 ++ * @cmpval: Expected value at uaddr1 ++ * @flags: Reserved flags arg for requeue operation expansion. Must be 0. ++ * ++ * If (rq1->uaddr == cmpval), wake at uaddr1->uaddr a nr_wake number of ++ * waiters and then, remove a number of nr_requeue waiters at rq1->uaddr ++ * and add then to rq2->uaddr list. Each uaddr has its own set of flags, ++ * that must be defined at struct futex_requeue (such as size, shared, NUMA). ++ * ++ * Return the number of the woken futexes + the number of requeued ones on ++ * success, error code otherwise. ++ */ ++SYSCALL_DEFINE6(futex_requeue, struct futex_requeue __user *, rq1, ++ struct futex_requeue __user *, rq2, ++ unsigned int, nr_wake, unsigned int, nr_requeue, ++ u64, cmpval, unsigned int, flags) ++{ ++ void __user *uaddr1, *uaddr2; ++ unsigned int flags1, flags2; ++ u32 val = cmpval; ++ int ret; ++ ++ if (flags) ++ return -EINVAL; ++ ++ ret = futex_parse_requeue(rq1, &uaddr1, &flags1); ++ if (ret) ++ return ret; ++ ++ ret = futex_parse_requeue(rq2, &uaddr2, &flags2); ++ if (ret) ++ return ret; ++ ++ return futex_requeue(uaddr1, flags1, uaddr2, flags2, nr_wake, nr_requeue, &val, 0); ++} +diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c +index 93807bb7be51..20a425b79fca 100644 +--- a/kernel/sys_ni.c ++++ b/kernel/sys_ni.c +@@ -157,6 +157,8 @@ COND_SYSCALL_COMPAT(futex_wait); + COND_SYSCALL(futex_wake); + COND_SYSCALL(futex_waitv); + COND_SYSCALL_COMPAT(futex_waitv); ++COND_SYSCALL(futex_requeue); ++COND_SYSCALL_COMPAT(futex_requeue); + + /* kernel/hrtimer.c */ + +-- +2.32.0 + + diff --git a/0004-futex2-documentation.patch b/0004-futex2-documentation.patch new file mode 100644 index 000000000000..fae79406e16b --- /dev/null +++ b/0004-futex2-documentation.patch @@ -0,0 +1,279 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id BD97AC11F66 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:23 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id A962061467 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:23 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230129AbhGIARF (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:05 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38188 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230103AbhGIARE (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:04 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9139BC061574; + Thu, 8 Jul 2021 17:14:21 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 4E9701F41790 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 04/11] docs: locking: futex2: Add documentation +Date: Thu, 8 Jul 2021 21:13:21 -0300 +Message-Id: <20210709001328.329716-5-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Add a new documentation file specifying both userspace API and internal +implementation details of futex2 syscalls. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + Documentation/locking/futex2.rst | 185 +++++++++++++++++++++++++++++++ + Documentation/locking/index.rst | 1 + + 2 files changed, 186 insertions(+) + create mode 100644 Documentation/locking/futex2.rst + +diff --git a/Documentation/locking/futex2.rst b/Documentation/locking/futex2.rst +new file mode 100644 +index 000000000000..2bf40f2abd00 +--- /dev/null ++++ b/Documentation/locking/futex2.rst +@@ -0,0 +1,185 @@ ++.. SPDX-License-Identifier: GPL-2.0 ++ ++====== ++futex2 ++====== ++ ++:Author: André Almeida <andrealmeid@collabora.com> ++ ++futex, or fast user mutex, is a set of syscalls to allow userspace to create ++performant synchronization mechanisms, such as mutexes, semaphores and ++conditional variables in userspace. C standard libraries, like glibc, uses it ++as a means to implement more high level interfaces like pthreads. ++ ++The interface ++============= ++ ++uAPI functions ++-------------- ++ ++.. kernel-doc:: kernel/futex2.c ++ :identifiers: sys_futex_wait sys_futex_wake sys_futex_waitv sys_futex_requeue ++ ++uAPI structures ++--------------- ++ ++.. kernel-doc:: include/uapi/linux/futex.h ++ ++The ``flag`` argument ++--------------------- ++ ++The flag is used to specify the size of the futex word ++(FUTEX_[8, 16, 32, 64]). It's mandatory to define one, since there's no ++default size. ++ ++By default, the timeout uses a monotonic clock, but can be used as a realtime ++one by using the FUTEX_REALTIME_CLOCK flag. ++ ++By default, futexes are of the private type, that means that this user address ++will be accessed by threads that share the same memory region. This allows for ++some internal optimizations, so they are faster. However, if the address needs ++to be shared with different processes (like using ``mmap()`` or ``shm()``), they ++need to be defined as shared and the flag FUTEX_SHARED_FLAG is used to set that. ++ ++By default, the operation has no NUMA-awareness, meaning that the user can't ++choose the memory node where the kernel side futex data will be stored. The ++user can choose the node where it wants to operate by setting the ++FUTEX_NUMA_FLAG and using the following structure (where X can be 8, 16, 32 or ++64):: ++ ++ struct futexX_numa { ++ __uX value; ++ __sX hint; ++ }; ++ ++This structure should be passed at the ``void *uaddr`` of futex functions. The ++address of the structure will be used to be waited on/waken on, and the ++``value`` will be compared to ``val`` as usual. The ``hint`` member is used to ++define which node the futex will use. When waiting, the futex will be ++registered on a kernel-side table stored on that node; when waking, the futex ++will be searched for on that given table. That means that there's no redundancy ++between tables, and the wrong ``hint`` value will lead to undesired behavior. ++Userspace is responsible for dealing with node migrations issues that may ++occur. ``hint`` can range from [0, MAX_NUMA_NODES), for specifying a node, or ++-1, to use the same node the current process is using. ++ ++When not using FUTEX_NUMA_FLAG on a NUMA system, the futex will be stored on a ++global table on allocated on the first node. ++ ++The ``timo`` argument ++--------------------- ++ ++As per the Y2038 work done in the kernel, new interfaces shouldn't add timeout ++options known to be buggy. Given that, ``timo`` should be a 64-bit timeout at ++all platforms, using an absolute timeout value. ++ ++Implementation ++============== ++ ++Kernel side implementation is made on top of current futex codebase. ++ ++Waiting ++------- ++ ++We have a hash table, where waiters register themselves before sleeping. Then ++the wake function checks this table looking for waiters at uaddr. The hash ++bucket to be used is determined by a struct futex_key, that stores information ++to uniquely identify an address from a given process. Given the huge address ++space, there'll be hash collisions, so we store information to be later used on ++collision treatment. ++ ++First, for every futex we want to wait on, we check if (``*uaddr == val``). ++This check is done holding the bucket lock, so we are correctly serialized with ++any futex_wake() calls. If any waiter fails the check above we return. For ++futex_waitv() calls, we dequeue all futexes queue until this point. The check ++(``*uaddr == val``) can fail for two reasons: ++ ++- The values are different, and we return -EAGAIN. However, if while ++ dequeueing we found that some futexes were awakened, we prioritize this ++ and return success. ++ ++- When trying to access the user address, we do so with page faults ++ disabled because we are holding a bucket's spin lock (and can't sleep ++ while holding a spin lock). If there's an error, it might be a page ++ fault, or an invalid address. We release the lock, dequeue everyone if it's a ++ futex_waitv() call (because it's illegal to sleep while there are futexes ++ enqueued, we could lose wakeups) and try again with page fault enabled. If we ++ succeed, this means that the address is valid, but we need to do all the work ++ again. For serialization reasons, we need to have the spin lock when getting ++ the user value. Additionally, for shared futexes, we also need to recalculate ++ the hash, since the underlying mapping mechanisms could have changed when ++ dealing with page fault. If, even with page fault enabled, we can't access ++ the address, it means it's an invalid user address, and we return -EFAULT. ++ ++If the check is OK, they are enqueued on a linked list in our bucket, and ++proceed to the next one. If all waiters succeed, we put the thread to sleep ++until a futex_wake() call, timeout expires or we get a signal. After waking up, ++we dequeue everyone, and check if some futex was awakened. ++ ++All enqueuing/dequeuing operations requires to hold the bucket lock, to avoid ++racing while modifying the list. ++ ++Waking ++------ ++ ++We get the bucket that's storing the waiters at uaddr, and wake the required ++number of waiters, checking for hash collision. ++ ++There's an optimization that makes futex_wake() not take the bucket lock if ++there's no one to be woken on that bucket. It checks an atomic counter that each ++bucket has, if it says 0, then the syscall exits. In order for this to work, the ++waiter thread increases it before taking the lock, so the wake thread will ++correctly see that there's someone waiting and will continue the path to take ++the bucket lock. To get the correct serialization, the waiter issues a memory ++barrier after increasing the bucket counter and the waker issues a memory ++barrier before checking it. ++ ++Requeuing ++--------- ++ ++The requeue path first checks for each struct futex_requeue and their flags. ++Then, it will compare the expected value with the one at rq1::uaddr. ++Following the same serialization explained at Waking_, we increase the atomic ++counter for the bucket of rq2::uaddr before taking the lock. We need to have ++both buckets locks at same time so we don't race with other futex operation. To ++ensure the locks are taken in the same order for all threads (and thus avoiding ++deadlocks), every requeue operation takes the "smaller" bucket first, when ++comparing both addresses. ++ ++If the compare with user value succeeds, we proceed by waking ``nr_wake`` ++futexes, and then requeuing ``nr_requeue`` from bucket of uaddr1 to the uaddr2. ++This consists in a simple list deletion/addition and replacing the old futex key ++with the new one. ++ ++Futex keys ++---------- ++ ++There are two types of futexes: private and shared ones. The private are futexes ++meant to be used by threads that share the same memory space, are easier to be ++uniquely identified and thus can have some performance optimization. The ++elements for identifying one are: the start address of the page where the ++address is, the address offset within the page and the current->mm pointer. ++ ++Now, for uniquely identifying a shared futex: ++ ++- If the page containing the user address is an anonymous page, we can ++ just use the same data used for private futexes (the start address of ++ the page, the address offset within the page and the current->mm ++ pointer); that will be enough for uniquely identifying such futex. We ++ also set one bit at the key to differentiate if a private futex is ++ used on the same address (mixing shared and private calls does not ++ work). ++ ++- If the page is file-backed, current->mm maybe isn't the same one for ++ every user of this futex, so we need to use other data: the ++ page->index, a UUID for the struct inode and the offset within the ++ page. ++ ++Note that members of futex_key don't have any particular meaning after they ++are part of the struct - they are just bytes to identify a futex. ++ ++Source code documentation ++========================= ++ ++.. kernel-doc:: kernel/futex2.c ++ :no-identifiers: sys_futex_wait sys_futex_wake sys_futex_waitv sys_futex_requeue +diff --git a/Documentation/locking/index.rst b/Documentation/locking/index.rst +index 7003bd5aeff4..9bf03c7fa1ec 100644 +--- a/Documentation/locking/index.rst ++++ b/Documentation/locking/index.rst +@@ -24,6 +24,7 @@ locking + percpu-rw-semaphore + robust-futexes + robust-futex-ABI ++ futex2 + + .. only:: subproject and html + +-- +2.32.0 + + diff --git a/0005-futex2-test-wake-wait.patch b/0005-futex2-test-wake-wait.patch new file mode 100644 index 000000000000..6746d28c9bbb --- /dev/null +++ b/0005-futex2-test-wake-wait.patch @@ -0,0 +1,416 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 67C97C07E9E + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:31 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 535B4611C2 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:31 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230146AbhGIARM (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:12 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38222 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230135AbhGIARK (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:10 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1EC2AC061760; + Thu, 8 Jul 2021 17:14:28 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id BBDC01F4186C +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 05/11] selftests: futex2: Add wake/wait test +Date: Thu, 8 Jul 2021 21:13:22 -0300 +Message-Id: <20210709001328.329716-6-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Add a simple file to test wake/wait mechanism using futex2 interface. +Test three scenarios: using a common local int variable as private +futex, a shm futex as shared futex and a file-backed shared memory as a +shared futex. This should test all branches of futex_get_key(). + +Create helper files so more tests can evaluate futex2. While 32bit ABIs +from glibc aren't yet able to use 64 bit sized time variables, add a +temporary workaround that implements the required types and calls the +appropriated syscalls, since futex2 doesn't supports 32 bit sized time. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + .../selftests/futex/functional/.gitignore | 1 + + .../selftests/futex/functional/Makefile | 4 +- + .../selftests/futex/functional/futex2_wait.c | 195 ++++++++++++++++++ + .../testing/selftests/futex/functional/run.sh | 3 + + .../selftests/futex/include/futex2test.h | 79 +++++++ + 5 files changed, 281 insertions(+), 1 deletion(-) + create mode 100644 tools/testing/selftests/futex/functional/futex2_wait.c + create mode 100644 tools/testing/selftests/futex/include/futex2test.h + +diff --git a/tools/testing/selftests/futex/functional/.gitignore b/tools/testing/selftests/futex/functional/.gitignore +index 0e78b49d0f2f..3e2d577c0595 100644 +--- a/tools/testing/selftests/futex/functional/.gitignore ++++ b/tools/testing/selftests/futex/functional/.gitignore +@@ -8,3 +8,4 @@ futex_wait_uninitialized_heap + futex_wait_timeout + futex_wait_uninitialized_heap + futex_wait_wouldblock ++futex2_wait +diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile +index bd1fec59e010..e4e4aa2e0368 100644 +--- a/tools/testing/selftests/futex/functional/Makefile ++++ b/tools/testing/selftests/futex/functional/Makefile +@@ -6,6 +6,7 @@ LDLIBS := -lpthread -lrt + + HEADERS := \ + ../include/futextest.h \ ++ ../include/futex2test.h \ + ../include/atomic.h \ + ../include/logging.h + TEST_GEN_FILES := \ +@@ -17,7 +18,8 @@ TEST_GEN_FILES := \ + futex_requeue_pi \ + futex_requeue_pi_signal_restart \ + futex_requeue_pi_mismatched_ops \ + futex_wait_uninitialized_heap \ +- futex_wait_private_mapped_file ++ futex_wait_private_mapped_file \ ++ futex2_wait + + TEST_PROGS := run.sh + +diff --git a/tools/testing/selftests/futex/functional/futex2_wait.c b/tools/testing/selftests/futex/functional/futex2_wait.c +new file mode 100644 +index 000000000000..25ac6d0898f5 +--- /dev/null ++++ b/tools/testing/selftests/futex/functional/futex2_wait.c +@@ -0,0 +1,195 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/****************************************************************************** ++ * ++ * Copyright Collabora Ltd., 2021 ++ * ++ * DESCRIPTION ++ * Test wait/wake mechanism of futex2, using 32bit sized futexes. ++ * ++ * AUTHOR ++ * André Almeida <andrealmeid@collabora.com> ++ * ++ * HISTORY ++ * 2021-Feb-5: Initial version by André <andrealmeid@collabora.com> ++ * ++ *****************************************************************************/ ++ ++#include <errno.h> ++#include <error.h> ++#include <getopt.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <time.h> ++#include <pthread.h> ++#include <sys/shm.h> ++#include <sys/mman.h> ++#include <fcntl.h> ++#include <string.h> ++#include "futex2test.h" ++#include "logging.h" ++ ++#define TEST_NAME "futex2-wait" ++#define timeout_ns 30000000 ++#define WAKE_WAIT_US 10000 ++#define SHM_PATH "futex2_shm_file" ++ ++void *futex; ++ ++void usage(char *prog) ++{ ++ printf("Usage: %s\n", prog); ++ printf(" -c Use color\n"); ++ printf(" -h Display this help message\n"); ++ printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", ++ VQUIET, VCRITICAL, VINFO); ++} ++ ++static void *waiterfn(void *arg) ++{ ++ struct timespec64 to64; ++ unsigned int flags = 0; ++ ++ if (arg) ++ flags = *((unsigned int *) arg); ++ ++ /* setting absolute timeout for futex2 */ ++ if (gettime64(CLOCK_MONOTONIC, &to64)) ++ error("gettime64 failed\n", errno); ++ ++ to64.tv_nsec += timeout_ns; ++ ++ if (to64.tv_nsec >= 1000000000) { ++ to64.tv_sec++; ++ to64.tv_nsec -= 1000000000; ++ } ++ ++ if (futex2_wait(futex, 0, FUTEX_32 | flags, &to64)) ++ printf("waiter failed errno %d\n", errno); ++ ++ return NULL; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ unsigned int flags = FUTEX_SHARED_FLAG; ++ int res, ret = RET_PASS, fd, c, shm_id; ++ u_int32_t f_private = 0, *shared_data; ++ pthread_t waiter; ++ void *shm; ++ ++ futex = &f_private; ++ ++ while ((c = getopt(argc, argv, "cht:v:")) != -1) { ++ switch (c) { ++ case 'c': ++ log_color(1); ++ break; ++ case 'h': ++ usage(basename(argv[0])); ++ exit(0); ++ case 'v': ++ log_verbosity(atoi(optarg)); ++ break; ++ default: ++ usage(basename(argv[0])); ++ exit(1); ++ } ++ } ++ ++ ksft_print_header(); ++ ksft_set_plan(3); ++ ksft_print_msg("%s: Test FUTEX2_WAIT\n", basename(argv[0])); ++ ++ /* Testing a private futex */ ++ info("Calling private futex2_wait on futex: %p\n", futex); ++ if (pthread_create(&waiter, NULL, waiterfn, NULL)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ info("Calling private futex2_wake on futex: %p\n", futex); ++ res = futex2_wake(futex, 1, FUTEX_32); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_wake private returned: %d %s\n", ++ errno, strerror(errno)); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_wake private\n"); ++ } ++ ++ /* Testing an anon page shared memory */ ++ shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); ++ if (shm_id < 0) { ++ perror("shmget"); ++ exit(1); ++ } ++ ++ shared_data = shmat(shm_id, NULL, 0); ++ ++ *shared_data = 0; ++ futex = shared_data; ++ ++ info("Calling (page anon) shared futex2_wait on futex: %p\n", futex); ++ if (pthread_create(&waiter, NULL, waiterfn, &flags)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ info("Calling (page anon) shared futex2_wake on futex: %p\n", futex); ++ res = futex2_wake(futex, 1, FUTEX_32 | FUTEX_SHARED_FLAG); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_wake shared (page anon) returned: %d %s\n", ++ errno, strerror(errno)); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_wake shared (page anon)\n"); ++ } ++ ++ ++ /* Testing a file backed shared memory */ ++ fd = open(SHM_PATH, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); ++ if (fd < 0) { ++ perror("open"); ++ exit(1); ++ } ++ ++ if (ftruncate(fd, sizeof(f_private))) { ++ perror("ftruncate"); ++ exit(1); ++ } ++ ++ shm = mmap(NULL, sizeof(f_private), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); ++ if (shm == MAP_FAILED) { ++ perror("mmap"); ++ exit(1); ++ } ++ ++ memcpy(shm, &f_private, sizeof(f_private)); ++ ++ futex = shm; ++ ++ info("Calling shared (file backed) futex2_wait on futex: %p\n", futex); ++ if (pthread_create(&waiter, NULL, waiterfn, &flags)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ info("Calling shared (file backed) futex2_wake on futex: %p\n", futex); ++ res = futex2_wake(shm, 1, FUTEX_32 | FUTEX_SHARED_FLAG); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_wake shared (file backed) returned: %d %s\n", ++ errno, strerror(errno)); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_wake shared (file backed)\n"); ++ } ++ ++ /* Freeing resources */ ++ shmdt(shared_data); ++ munmap(shm, sizeof(f_private)); ++ remove(SHM_PATH); ++ ++ ksft_print_cnts(); ++ return ret; ++} +diff --git a/tools/testing/selftests/futex/functional/run.sh b/tools/testing/selftests/futex/functional/run.sh +index 11a9d62290f5..dbe82275617c 100755 +--- a/tools/testing/selftests/futex/functional/run.sh ++++ b/tools/testing/selftests/futex/functional/run.sh +@@ -79,3 +79,6 @@ echo + echo + ./futex_wait_uninitialized_heap $COLOR + ./futex_wait_private_mapped_file $COLOR ++ ++echo ++./futex2_wait $COLOR +diff --git a/tools/testing/selftests/futex/include/futex2test.h b/tools/testing/selftests/futex/include/futex2test.h +new file mode 100644 +index 000000000000..e724d56b917e +--- /dev/null ++++ b/tools/testing/selftests/futex/include/futex2test.h +@@ -0,0 +1,79 @@ ++/* SPDX-License-Identifier: GPL-2.0-or-later */ ++/****************************************************************************** ++ * ++ * Copyright Collabora Ltd., 2021 ++ * ++ * DESCRIPTION ++ * Futex2 library addons for old futex library ++ * ++ * AUTHOR ++ * André Almeida <andrealmeid@collabora.com> ++ * ++ * HISTORY ++ * 2021-Feb-5: Initial version by André <andrealmeid@collabora.com> ++ * ++ *****************************************************************************/ ++#include "futextest.h" ++#include <stdio.h> ++ ++#define NSEC_PER_SEC 1000000000L ++ ++#ifndef FUTEX_8 ++# define FUTEX_8 0 ++#endif ++#ifndef FUTEX_16 ++# define FUTEX_16 1 ++#endif ++#ifndef FUTEX_32 ++# define FUTEX_32 2 ++#endif ++ ++/* ++ * - Y2038 section for 32-bit applications - ++ * ++ * Remove this when glibc is ready for y2038. Then, always compile with ++ * `-DTIME_BITS=64` or `-D__USE_TIME_BITS64`. glibc will provide both ++ * timespec64 and clock_gettime64 so we won't need to define here. ++ */ ++#if defined(__i386__) || __TIMESIZE == 32 ++# define NR_gettime __NR_clock_gettime64 ++#else ++# define NR_gettime __NR_clock_gettime ++#endif ++ ++struct timespec64 { ++ long long tv_sec; /* seconds */ ++ long long tv_nsec; /* nanoseconds */ ++}; ++ ++int gettime64(clock_t clockid, struct timespec64 *tv) ++{ ++ return syscall(NR_gettime, clockid, tv); ++} ++/* ++ * - End of Y2038 section - ++ */ ++ ++/** ++ * futex2_wait - If (*uaddr == val), wait at uaddr until timo ++ * @uaddr: User address to wait on ++ * @val: Expected value at uaddr, return if is not equal ++ * @flags: Operation flags ++ * @timo: Optional timeout for operation ++ */ ++static inline int futex2_wait(volatile void *uaddr, unsigned long val, ++ unsigned long flags, struct timespec64 *timo) ++{ ++ return syscall(__NR_futex_wait, uaddr, val, flags, timo); ++} ++ ++/** ++ * futex2_wake - Wake a number of waiters at uaddr ++ * @uaddr: Address to wake ++ * @nr: Number of waiters to wake ++ * @flags: Operation flags ++ */ ++static inline int futex2_wake(volatile void *uaddr, unsigned int nr, unsigned long flags) ++{ ++ return syscall(__NR_futex_wake, uaddr, nr, flags); ++} +-- +2.32.0 + + diff --git a/0006-futex2-test-timeout.patch b/0006-futex2-test-timeout.patch new file mode 100644 index 000000000000..3d43093098de --- /dev/null +++ b/0006-futex2-test-timeout.patch @@ -0,0 +1,129 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 59498C07E96 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:41 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 3F19B611C2 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:41 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230185AbhGIARU (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:20 -0400 +Received: from bhuna.collabora.co.uk ([46.235.227.227]:44816 "EHLO + bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230135AbhGIARQ (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:16 -0400 +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 5207F1F4198C +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 06/11] selftests: futex2: Add timeout test +Date: Thu, 8 Jul 2021 21:13:23 -0300 +Message-Id: <20210709001328.329716-7-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Adapt existing futex wait timeout file to test the same mechanism for +futex2. futex2 accepts only absolute 64bit timers, but supports both +monotonic and realtime clocks. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + .../futex/functional/futex_wait_timeout.c | 24 +++++++++++++++++-- + 1 file changed, 22 insertions(+), 2 deletions(-) + +diff --git a/tools/testing/selftests/futex/functional/futex_wait_timeout.c b/tools/testing/selftests/futex/functional/futex_wait_timeout.c +index 1f8f6daaf1e7..d20f54745c2e 100644 +--- a/tools/testing/selftests/futex/functional/futex_wait_timeout.c ++++ b/tools/testing/selftests/futex/functional/futex_wait_timeout.c +@@ -17,6 +17,14 @@ + + #include <pthread.h> + #include "futextest.h" ++ ++#include <errno.h> ++#include <getopt.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <time.h> ++#include "futex2test.h" + #include "logging.h" + + #define TEST_NAME "futex-wait-timeout" +@@ -92,8 +100,8 @@ static int futex_get_abs_timeout(clockid_t clockid, struct timespec *to, + int main(int argc, char *argv[]) + { + futex_t f1 = FUTEX_INITIALIZER; ++ struct timespec to = {.tv_sec = 0, .tv_nsec = timeout_ns}; + int res, ret = RET_PASS; +- struct timespec to; + pthread_t thread; + int c; + +@@ -118,7 +126,7 @@ int main(int argc, char *argv[]) + } + + ksft_print_header(); +- ksft_set_plan(7); ++ ksft_set_plan(9); + ksft_print_msg("%s: Block on a futex and wait for timeout\n", + basename(argv[0])); + ksft_print_msg("\tArguments: timeout=%ldns\n", timeout_ns); +@@ -175,6 +183,18 @@ int main(int argc, char *argv[]) + res = futex_lock_pi(&futex_pi, NULL, 0, FUTEX_CLOCK_REALTIME); + test_timeout(res, &ret, "futex_lock_pi invalid timeout flag", ENOSYS); + ++ /* setting absolute monotonic timeout for futex2 */ ++ if (futex_get_abs_timeout(CLOCK_MONOTONIC, &to, timeout_ns)) ++ return RET_FAIL; ++ res = futex2_wait(&f1, f1, FUTEX_32, &to); ++ test_timeout(res, &ret, "futex2_wait monotonic", ETIMEDOUT); ++ ++ /* setting absolute realtime timeout for futex2 */ ++ if (futex_get_abs_timeout(CLOCK_REALTIME, &to, timeout_ns)) ++ return RET_FAIL; ++ res = futex2_wait(&f1, f1, FUTEX_32 | FUTEX_CLOCK_REALTIME, &to); ++ test_timeout(res, &ret, "futex2_wait realtime", ETIMEDOUT); ++ + ksft_print_cnts(); + return ret; + } +-- +2.32.0 + + diff --git a/0007-futex2-test-wouldblock.patch b/0007-futex2-test-wouldblock.patch new file mode 100644 index 000000000000..c9a163d9a15b --- /dev/null +++ b/0007-futex2-test-wouldblock.patch @@ -0,0 +1,145 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id F1FBEC07E9C + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:48 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id E00336113A + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:48 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230189AbhGIAR3 (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:29 -0400 +Received: from bhuna.collabora.co.uk ([46.235.227.227]:44844 "EHLO + bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230210AbhGIARX (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:23 -0400 +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id BBD551F41AF2 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 07/11] selftests: futex2: Add wouldblock test +Date: Thu, 8 Jul 2021 21:13:24 -0300 +Message-Id: <20210709001328.329716-8-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Adapt existing futex wait wouldblock file to test the same mechanism for +futex2. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + .../futex/functional/futex_wait_wouldblock.c | 33 ++++++++++++++++--- + 1 file changed, 29 insertions(+), 4 deletions(-) + +diff --git a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c +index 0ae390ff8164..510a98320248 100644 +--- a/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c ++++ b/tools/testing/selftests/futex/functional/futex_wait_wouldblock.c +@@ -12,6 +12,7 @@ + * + * HISTORY + * 2009-Nov-14: Initial version by Gowrishankar <gowrishankar.m@in.ibm.com> ++ * 2021-Feb-5: Add futex2 test by André <andrealmeid@collabora.com> + * + *****************************************************************************/ + +@@ -21,7 +22,7 @@ + #include <stdlib.h> + #include <string.h> + #include <time.h> +-#include "futextest.h" ++#include "futex2test.h" + #include "logging.h" + + #define TEST_NAME "futex-wait-wouldblock" +@@ -39,6 +40,7 @@ void usage(char *prog) + int main(int argc, char *argv[]) + { + struct timespec to = {.tv_sec = 0, .tv_nsec = timeout_ns}; ++ struct timespec64 to64; + futex_t f1 = FUTEX_INITIALIZER; + int res, ret = RET_PASS; + int c; +@@ -61,18 +63,41 @@ int main(int argc, char *argv[]) + } + + ksft_print_header(); +- ksft_set_plan(1); ++ ksft_set_plan(2); + ksft_print_msg("%s: Test the unexpected futex value in FUTEX_WAIT\n", + basename(argv[0])); + + info("Calling futex_wait on f1: %u @ %p with val=%u\n", f1, &f1, f1+1); + res = futex_wait(&f1, f1+1, &to, FUTEX_PRIVATE_FLAG); + if (!res || errno != EWOULDBLOCK) { +- fail("futex_wait returned: %d %s\n", ++ ksft_test_result_fail("futex_wait returned: %d %s\n", + res ? errno : res, res ? strerror(errno) : ""); + ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex_wait wouldblock\n"); + } + +- print_result(TEST_NAME, ret); ++ /* setting absolute timeout for futex2 */ ++ if (gettime64(CLOCK_MONOTONIC, &to64)) ++ error("gettime64 failed\n", errno); ++ ++ to64.tv_nsec += timeout_ns; ++ ++ if (to64.tv_nsec >= 1000000000) { ++ to64.tv_sec++; ++ to64.tv_nsec -= 1000000000; ++ } ++ ++ info("Calling futex2_wait on f1: %u @ %p with val=%u\n", f1, &f1, f1+1); ++ res = futex2_wait(&f1, f1+1, FUTEX_32, &to64); ++ if (!res || errno != EWOULDBLOCK) { ++ ksft_test_result_fail("futex2_wait returned: %d %s\n", ++ res ? errno : res, res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_wait wouldblock\n"); ++ } ++ ++ ksft_print_cnts(); + return ret; + } +-- +2.32.0 + + diff --git a/0008-futex2-test-waitv.patch b/0008-futex2-test-waitv.patch new file mode 100644 index 000000000000..32442bc89b53 --- /dev/null +++ b/0008-futex2-test-waitv.patch @@ -0,0 +1,303 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id C318CC07E99 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:51 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id AE949611C2 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:51 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230220AbhGIARb (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:31 -0400 +Received: from bhuna.collabora.co.uk ([46.235.227.227]:44886 "EHLO + bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230091AbhGIARa (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:30 -0400 +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 34CB71F41BA9 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 08/11] selftests: futex2: Add waitv test +Date: Thu, 8 Jul 2021 21:13:25 -0300 +Message-Id: <20210709001328.329716-9-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Create a new file to test the waitv mechanism. Test both private and +shared futexes. Wake the last futex in the array, and check if the +return value from futex_waitv() is the right index. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + .../selftests/futex/functional/.gitignore | 1 + + .../selftests/futex/functional/Makefile | 3 +- + .../selftests/futex/functional/futex2_waitv.c | 154 ++++++++++++++++++ + .../testing/selftests/futex/functional/run.sh | 3 + + .../selftests/futex/include/futex2test.h | 17 ++ + 5 files changed, 177 insertions(+), 1 deletion(-) + create mode 100644 tools/testing/selftests/futex/functional/futex2_waitv.c + +diff --git a/tools/testing/selftests/futex/functional/.gitignore b/tools/testing/selftests/futex/functional/.gitignore +index 3e2d577c0595..22c572de8d10 100644 +--- a/tools/testing/selftests/futex/functional/.gitignore ++++ b/tools/testing/selftests/futex/functional/.gitignore +@@ -9,3 +9,4 @@ futex_wait_wouldblock + futex_wait + futex_requeue + futex2_wait ++futex2_waitv +diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile +index e4e4aa2e0368..240b53d8cb07 100644 +--- a/tools/testing/selftests/futex/functional/Makefile ++++ b/tools/testing/selftests/futex/functional/Makefile +@@ -19,7 +19,8 @@ TEST_GEN_FILES := \ + futex_wait_private_mapped_file \ + futex_wait \ + futex_requeue \ +- futex2_wait ++ futex2_wait \ ++ futex2_waitv + + TEST_PROGS := run.sh + +diff --git a/tools/testing/selftests/futex/functional/futex2_waitv.c b/tools/testing/selftests/futex/functional/futex2_waitv.c +new file mode 100644 +index 000000000000..0f625a0657d5 +--- /dev/null ++++ b/tools/testing/selftests/futex/functional/futex2_waitv.c +@@ -0,0 +1,154 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/****************************************************************************** ++ * ++ * Copyright Collabora Ltd., 2021 ++ * ++ * DESCRIPTION ++ * Test waitv/wake mechanism of futex2, using 32bit sized futexes. ++ * ++ * AUTHOR ++ * André Almeida <andrealmeid@collabora.com> ++ * ++ * HISTORY ++ * 2021-Feb-5: Initial version by André <andrealmeid@collabora.com> ++ * ++ *****************************************************************************/ ++ ++#include <errno.h> ++#include <error.h> ++#include <getopt.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <time.h> ++#include <pthread.h> ++#include <sys/shm.h> ++#include "futex2test.h" ++#include "logging.h" ++ ++#define TEST_NAME "futex2-wait" ++#define WAKE_WAIT_US 10000 ++#define NR_FUTEXES 30 ++struct futex_waitv waitv[NR_FUTEXES]; ++u_int32_t futexes[NR_FUTEXES] = {0}; ++ ++void usage(char *prog) ++{ ++ printf("Usage: %s\n", prog); ++ printf(" -c Use color\n"); ++ printf(" -h Display this help message\n"); ++ printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", ++ VQUIET, VCRITICAL, VINFO); ++} ++ ++void *waiterfn(void *arg) ++{ ++ struct timespec64 to64; ++ int res; ++ ++ /* setting absolute timeout for futex2 */ ++ if (gettime64(CLOCK_MONOTONIC, &to64)) ++ error("gettime64 failed\n", errno); ++ ++ to64.tv_sec++; ++ ++ res = futex2_waitv(waitv, NR_FUTEXES, 0, &to64); ++ if (res < 0) { ++ ksft_test_result_fail("futex2_waitv returned: %d %s\n", ++ errno, strerror(errno)); ++ } else if (res != NR_FUTEXES - 1) { ++ ksft_test_result_fail("futex2_waitv returned: %d, expecting %d\n", ++ res, NR_FUTEXES - 1); ++ } ++ ++ return NULL; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ pthread_t waiter; ++ int res, ret = RET_PASS; ++ int c, i; ++ ++ while ((c = getopt(argc, argv, "cht:v:")) != -1) { ++ switch (c) { ++ case 'c': ++ log_color(1); ++ break; ++ case 'h': ++ usage(basename(argv[0])); ++ exit(0); ++ case 'v': ++ log_verbosity(atoi(optarg)); ++ break; ++ default: ++ usage(basename(argv[0])); ++ exit(1); ++ } ++ } ++ ++ ksft_print_header(); ++ ksft_set_plan(2); ++ ksft_print_msg("%s: Test FUTEX2_WAITV\n", ++ basename(argv[0])); ++ ++ for (i = 0; i < NR_FUTEXES; i++) { ++ waitv[i].uaddr = &futexes[i]; ++ waitv[i].flags = FUTEX_32; ++ waitv[i].val = 0; ++ } ++ ++ /* Private waitv */ ++ if (pthread_create(&waiter, NULL, waiterfn, NULL)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ res = futex2_wake(waitv[NR_FUTEXES - 1].uaddr, 1, FUTEX_32); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_waitv private returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_waitv private\n"); ++ } ++ ++ /* Shared waitv */ ++ for (i = 0; i < NR_FUTEXES; i++) { ++ int shm_id = shmget(IPC_PRIVATE, 4096, IPC_CREAT | 0666); ++ ++ if (shm_id < 0) { ++ perror("shmget"); ++ exit(1); ++ } ++ ++ unsigned int *shared_data = shmat(shm_id, NULL, 0); ++ ++ *shared_data = 0; ++ waitv[i].uaddr = shared_data; ++ waitv[i].flags = FUTEX_32 | FUTEX_SHARED_FLAG; ++ waitv[i].val = 0; ++ } ++ ++ if (pthread_create(&waiter, NULL, waiterfn, NULL)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ res = futex2_wake(waitv[NR_FUTEXES - 1].uaddr, 1, FUTEX_32 | FUTEX_SHARED_FLAG); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_waitv shared returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_waitv shared\n"); ++ } ++ ++ for (i = 0; i < NR_FUTEXES; i++) ++ shmdt(waitv[i].uaddr); ++ ++ ksft_print_cnts(); ++ return ret; ++} +diff --git a/tools/testing/selftests/futex/functional/run.sh b/tools/testing/selftests/futex/functional/run.sh +index dbe82275617c..6d30a30547da 100755 +--- a/tools/testing/selftests/futex/functional/run.sh ++++ b/tools/testing/selftests/futex/functional/run.sh +@@ -82,3 +82,6 @@ echo + + echo + ./futex2_wait $COLOR ++ ++echo ++./futex2_waitv $COLOR +diff --git a/tools/testing/selftests/futex/include/futex2test.h b/tools/testing/selftests/futex/include/futex2test.h +index e724d56b917e..0ed3b20935be 100644 +--- a/tools/testing/selftests/futex/include/futex2test.h ++++ b/tools/testing/selftests/futex/include/futex2test.h +@@ -28,6 +28,10 @@ + # define FUTEX_32 2 + #endif + ++#ifndef FUTEX_SHARED_FLAG ++#define FUTEX_SHARED_FLAG 8 ++#endif ++ + /* + * - Y2038 section for 32-bit applications - + * +@@ -77,3 +81,16 @@ static inline int futex2_wake(volatile void *uaddr, unsigned int nr, unsigned lo + { + return syscall(__NR_futex_wake, uaddr, nr, flags); + } ++ ++/** ++ * futex2_waitv - Wait at multiple futexes, wake on any ++ * @waiters: Array of waiters ++ * @nr_waiters: Length of waiters array ++ * @flags: Operation flags ++ * @timo: Optional timeout for operation ++ */ ++static inline int futex2_waitv(volatile struct futex_waitv *waiters, unsigned long nr_waiters, ++ unsigned long flags, struct timespec64 *timo) ++{ ++ return syscall(__NR_futex_waitv, waiters, nr_waiters, flags, timo); ++} +-- +2.32.0 + + diff --git a/0009-futex2-test-requeue.patch b/0009-futex2-test-requeue.patch new file mode 100644 index 000000000000..d31b0a3cb798 --- /dev/null +++ b/0009-futex2-test-requeue.patch @@ -0,0 +1,297 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 58C4CC07E99 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:59 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 3E09761468 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:14:59 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230324AbhGIARk (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:40 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38346 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230130AbhGIARh (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:37 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2ADB2C061764; + Thu, 8 Jul 2021 17:14:54 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id 996E21F433BD +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 09/11] selftests: futex2: Add requeue test +Date: Thu, 8 Jul 2021 21:13:26 -0300 +Message-Id: <20210709001328.329716-10-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +Add testing for futex_requeue(). The first test just requeue from one +waiter to another one, and wake it. The second performs both wake and +requeue, and we check return values to see if the operation +woke/requeued the expected number of waiters. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + .../selftests/futex/functional/.gitignore | 1 + + .../selftests/futex/functional/Makefile | 3 +- + .../futex/functional/futex2_requeue.c | 164 ++++++++++++++++++ + .../selftests/futex/include/futex2test.h | 16 ++ + 4 files changed, 183 insertions(+), 1 deletion(-) + create mode 100644 tools/testing/selftests/futex/functional/futex2_requeue.c + +diff --git a/tools/testing/selftests/futex/functional/.gitignore b/tools/testing/selftests/futex/functional/.gitignore +index 22c572de8d10..d63b5f74bd6f 100644 +--- a/tools/testing/selftests/futex/functional/.gitignore ++++ b/tools/testing/selftests/futex/functional/.gitignore +@@ -10,3 +10,4 @@ futex_wait + futex_requeue + futex2_wait + futex2_waitv ++futex2_requeue +diff --git a/tools/testing/selftests/futex/functional/Makefile b/tools/testing/selftests/futex/functional/Makefile +index 240b53d8cb07..e162e40ce38f 100644 +--- a/tools/testing/selftests/futex/functional/Makefile ++++ b/tools/testing/selftests/futex/functional/Makefile +@@ -20,7 +20,8 @@ TEST_GEN_FILES := \ + futex_wait \ + futex_requeue \ + futex2_wait \ +- futex2_waitv ++ futex2_waitv \ ++ futex2_requeue + + TEST_PROGS := run.sh + +diff --git a/tools/testing/selftests/futex/functional/futex2_requeue.c b/tools/testing/selftests/futex/functional/futex2_requeue.c +new file mode 100644 +index 000000000000..1bc3704dc8c2 +--- /dev/null ++++ b/tools/testing/selftests/futex/functional/futex2_requeue.c +@@ -0,0 +1,164 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/****************************************************************************** ++ * ++ * Copyright Collabora Ltd., 2021 ++ * ++ * DESCRIPTION ++ * Test requeue mechanism of futex2, using 32bit sized futexes. ++ * ++ * AUTHOR ++ * André Almeida <andrealmeid@collabora.com> ++ * ++ * HISTORY ++ * 2021-Feb-5: Initial version by André <andrealmeid@collabora.com> ++ * ++ *****************************************************************************/ ++ ++#include <errno.h> ++#include <error.h> ++#include <getopt.h> ++#include <stdio.h> ++#include <stdlib.h> ++#include <string.h> ++#include <time.h> ++#include <pthread.h> ++#include <sys/shm.h> ++#include <limits.h> ++#include "futex2test.h" ++#include "logging.h" ++ ++#define TEST_NAME "futex2-wait" ++#define timeout_ns 30000000 ++#define WAKE_WAIT_US 10000 ++volatile futex_t *f1; ++ ++void usage(char *prog) ++{ ++ printf("Usage: %s\n", prog); ++ printf(" -c Use color\n"); ++ printf(" -h Display this help message\n"); ++ printf(" -v L Verbosity level: %d=QUIET %d=CRITICAL %d=INFO\n", ++ VQUIET, VCRITICAL, VINFO); ++} ++ ++void *waiterfn(void *arg) ++{ ++ struct timespec64 to64; ++ ++ /* setting absolute timeout for futex2 */ ++ if (gettime64(CLOCK_MONOTONIC, &to64)) ++ error("gettime64 failed\n", errno); ++ ++ to64.tv_nsec += timeout_ns; ++ ++ if (to64.tv_nsec >= 1000000000) { ++ to64.tv_sec++; ++ to64.tv_nsec -= 1000000000; ++ } ++ ++ if (futex2_wait(f1, *f1, FUTEX_32, &to64)) ++ printf("waiter failed errno %d\n", errno); ++ ++ return NULL; ++} ++ ++int main(int argc, char *argv[]) ++{ ++ pthread_t waiter[10]; ++ int res, ret = RET_PASS; ++ int c, i; ++ volatile futex_t _f1 = 0; ++ volatile futex_t f2 = 0; ++ struct futex_requeue r1, r2; ++ ++ f1 = &_f1; ++ ++ r1.flags = FUTEX_32; ++ r2.flags = FUTEX_32; ++ ++ r1.uaddr = f1; ++ r2.uaddr = &f2; ++ ++ while ((c = getopt(argc, argv, "cht:v:")) != -1) { ++ switch (c) { ++ case 'c': ++ log_color(1); ++ break; ++ case 'h': ++ usage(basename(argv[0])); ++ exit(0); ++ case 'v': ++ log_verbosity(atoi(optarg)); ++ break; ++ default: ++ usage(basename(argv[0])); ++ exit(1); ++ } ++ } ++ ++ ksft_print_header(); ++ ksft_set_plan(2); ++ ksft_print_msg("%s: Test FUTEX2_REQUEUE\n", ++ basename(argv[0])); ++ ++ /* ++ * Requeue a waiter from f1 to f2, and wake f2. ++ */ ++ if (pthread_create(&waiter[0], NULL, waiterfn, NULL)) ++ error("pthread_create failed\n", errno); ++ ++ usleep(WAKE_WAIT_US); ++ ++ res = futex2_requeue(&r1, &r2, 0, 1, 0, 0); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_requeue private returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } ++ ++ ++ info("Calling private futex2_wake on f2: %u @ %p with val=%u\n", f2, &f2, f2); ++ res = futex2_wake(&f2, 1, FUTEX_32); ++ if (res != 1) { ++ ksft_test_result_fail("futex2_requeue private returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_requeue simple succeeds\n"); ++ } ++ ++ ++ /* ++ * Create 10 waiters at f1. At futex_requeue, wake 3 and requeue 7. ++ * At futex_wake, wake INT_MAX (should be exaclty 7). ++ */ ++ for (i = 0; i < 10; i++) { ++ if (pthread_create(&waiter[i], NULL, waiterfn, NULL)) ++ error("pthread_create failed\n", errno); ++ } ++ ++ usleep(WAKE_WAIT_US); ++ ++ res = futex2_requeue(&r1, &r2, 3, 7, 0, 0); ++ if (res != 10) { ++ ksft_test_result_fail("futex2_requeue private returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } ++ ++ res = futex2_wake(&f2, INT_MAX, FUTEX_32); ++ if (res != 7) { ++ ksft_test_result_fail("futex2_requeue private returned: %d %s\n", ++ res ? errno : res, ++ res ? strerror(errno) : ""); ++ ret = RET_FAIL; ++ } else { ++ ksft_test_result_pass("futex2_requeue succeeds\n"); ++ } ++ ++ ksft_print_cnts(); ++ return ret; ++} +diff --git a/tools/testing/selftests/futex/include/futex2test.h b/tools/testing/selftests/futex/include/futex2test.h +index 0ed3b20935be..682ba8319590 100644 +--- a/tools/testing/selftests/futex/include/futex2test.h ++++ b/tools/testing/selftests/futex/include/futex2test.h +@@ -94,3 +94,19 @@ static inline int futex2_waitv(volatile struct futex_waitv *waiters, unsigned lo + { + return syscall(__NR_futex_waitv, waiters, nr_waiters, flags, timo); + } ++ ++/** ++ * futex2_requeue - Wake futexes at uaddr1 and requeue from uaddr1 to uaddr2 ++ * @uaddr1: Original address to wake and requeue from ++ * @uaddr2: Address to requeue to ++ * @nr_wake: Number of futexes to wake at uaddr1 before requeuing ++ * @nr_requeue: Number of futexes to requeue from uaddr1 to uaddr2 ++ * @cmpval: If (uaddr1->uaddr != cmpval), return immediatally ++ * @flgas: Operation flags ++ */ ++static inline int futex2_requeue(struct futex_requeue *rq1, struct futex_requeue *rq2, ++ unsigned int nr_wake, unsigned int nr_requeue, ++ unsigned int cmpval, unsigned long flags) ++{ ++ return syscall(__NR_futex_requeue, rq1, rq2, nr_wake, nr_requeue, cmpval, flags); ++} +-- +2.32.0 + + diff --git a/0011-futex2-enable-waitpid-for-futex2.patch b/0011-futex2-enable-waitpid-for-futex2.patch new file mode 100644 index 000000000000..9f470a360029 --- /dev/null +++ b/0011-futex2-enable-waitpid-for-futex2.patch @@ -0,0 +1,161 @@ +From mboxrd@z Thu Jan 1 00:00:00 1970 +Return-Path: <linux-kernel-owner@kernel.org> +X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on + aws-us-west-2-korg-lkml-1.web.codeaurora.org +X-Spam-Level: +X-Spam-Status: No, score=-17.0 required=3.0 tests=BAYES_00, + HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, + MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT + autolearn=unavailable autolearn_force=no version=3.4.0 +Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) + by smtp.lore.kernel.org (Postfix) with ESMTP id 2F111C07E9E + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:15:14 +0000 (UTC) +Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) + by mail.kernel.org (Postfix) with ESMTP id 13D36611C2 + for <linux-kernel@archiver.kernel.org>; Fri, 9 Jul 2021 00:15:14 +0000 (UTC) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S230433AbhGIARz (ORCPT <rfc822;linux-kernel@archiver.kernel.org>); + Thu, 8 Jul 2021 20:17:55 -0400 +Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38414 "EHLO + lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S230262AbhGIARt (ORCPT + <rfc822;linux-kernel@vger.kernel.org>); + Thu, 8 Jul 2021 20:17:49 -0400 +Received: from bhuna.collabora.co.uk (bhuna.collabora.co.uk [IPv6:2a00:1098:0:82:1000:25:2eeb:e3e3]) + by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE64EC061760; + Thu, 8 Jul 2021 17:15:06 -0700 (PDT) +Received: from [127.0.0.1] (localhost [127.0.0.1]) + (Authenticated sender: tonyk) + with ESMTPSA id AD5281F41E36 +From: =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +To: Thomas Gleixner <tglx@linutronix.de>, + Ingo Molnar <mingo@redhat.com>, + Peter Zijlstra <peterz@infradead.org>, + Darren Hart <dvhart@infradead.org>, + linux-kernel@vger.kernel.org, Steven Rostedt <rostedt@goodmis.org>, + Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Cc: kernel@collabora.com, krisman@collabora.com, + pgriffais@valvesoftware.com, z.figura12@gmail.com, + joel@joelfernandes.org, malteskarupke@fastmail.fm, + linux-api@vger.kernel.org, fweimer@redhat.com, + libc-alpha@sourceware.org, linux-kselftest@vger.kernel.org, + shuah@kernel.org, acme@kernel.org, corbet@lwn.net, + Peter Oskolkov <posk@posk.io>, + Andrey Semashev <andrey.semashev@gmail.com>, + Davidlohr Bueso <dave@stgolabs.net>, + Nicholas Piggin <npiggin@gmail.com>, + Adhemerval Zanella <adhemerval.zanella@linaro.org>, + =?UTF-8?q?Andr=C3=A9=20Almeida?= <andrealmeid@collabora.com> +Subject: [PATCH v5 11/11] kernel: Enable waitpid() for futex2 +Date: Thu, 8 Jul 2021 21:13:28 -0300 +Message-Id: <20210709001328.329716-12-andrealmeid@collabora.com> +X-Mailer: git-send-email 2.32.0 +In-Reply-To: <20210709001328.329716-1-andrealmeid@collabora.com> +References: <20210709001328.329716-1-andrealmeid@collabora.com> +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +Precedence: bulk +List-ID: <linux-kernel.vger.kernel.org> +X-Mailing-List: linux-kernel@vger.kernel.org +List-Archive: <https://lore.kernel.org/lkml/> + +To make pthreads works as expected if they are using futex2, wake +clear_child_tid with futex2 as well. This is make applications that uses +waitpid() (and clone(CLONE_CHILD_SETTID)) wake while waiting for the +child to terminate. Given that apps should not mix futex() and futex2(), +any correct app will trigger a harmless noop wakeup on the interface +that it isn't using. + +Signed-off-by: André Almeida <andrealmeid@collabora.com> +--- + +This commit is here for the intend to show what we need to do in order +to get a full NPTL working on top of futex2. It should be merged after +we talk to glibc folks on the details around the futex_wait() side. For +instance, we could use this as an opportunity to use private futexes or +8bit sized futexes, but both sides need to use the exactly same flags. +--- + include/linux/syscalls.h | 2 ++ + kernel/fork.c | 2 ++ + kernel/futex2.c | 30 ++++++++++++++++++------------ + 3 files changed, 22 insertions(+), 12 deletions(-) + +diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h +index b9c2874410d0..85b5a501fb96 100644 +--- a/include/linux/syscalls.h ++++ b/include/linux/syscalls.h +@@ -1315,6 +1315,8 @@ int ksys_ipc(unsigned int call, int first, unsigned long second, + unsigned long third, void __user * ptr, long fifth); + int compat_ksys_ipc(u32 call, int first, int second, + u32 third, u32 ptr, u32 fifth); ++long ksys_futex_wake(void __user *uaddr, unsigned int nr_wake, ++ unsigned int flags); + + /* + * The following kernel syscall equivalents are just wrappers to fs-internal +diff --git a/kernel/fork.c b/kernel/fork.c +index b4386ff6a641..f3f98e197fb6 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1328,6 +1328,8 @@ static void mm_release(struct task_struct *tsk, struct mm_struct *mm) + put_user(0, tsk->clear_child_tid); + do_futex(tsk->clear_child_tid, FUTEX_WAKE, + 1, NULL, NULL, 0, 0); ++ ksys_futex_wake(tsk->clear_child_tid, 1, ++ FUTEX_32 | FUTEX_SHARED_FLAG); + } + tsk->clear_child_tid = NULL; + } +diff --git a/kernel/futex2.c b/kernel/futex2.c +index 4f6d099badec..2ca2f40fcdd2 100644 +--- a/kernel/futex2.c ++++ b/kernel/futex2.c +@@ -420,18 +420,8 @@ COMPAT_SYSCALL_DEFINE4(futex_wait, void __user *, uaddr, compat_u64, val, + } + #endif + +-/** +- * sys_futex_wake - Wake a number of futexes waiting on an address +- * @uaddr: Address of futex to be woken up +- * @nr_wake: Number of futexes waiting in uaddr to be woken up +- * @flags: Flags for size and shared +- * +- * Wake `nr_wake` threads waiting at uaddr. +- * +- * Returns the number of woken threads on success, error code otherwise. +- */ +-SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake, +- unsigned int, flags) ++long ksys_futex_wake(void __user *uaddr, unsigned int nr_wake, ++ unsigned int flags) + { + unsigned int size = flags & FUTEX_SIZE_MASK, futex_flags = 0; + +@@ -447,6 +437,22 @@ SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake, + return futex_wake(uaddr, futex_flags, nr_wake, FUTEX_BITSET_MATCH_ANY); + } + ++/** ++ * sys_futex_wake - Wake a number of futexes waiting on an address ++ * @uaddr: Address of futex to be woken up ++ * @nr_wake: Number of futexes waiting in uaddr to be woken up ++ * @flags: Flags for size and shared ++ * ++ * Wake `nr_wake` threads waiting at uaddr. ++ * ++ * Returns the number of woken threads on success, error code otherwise. ++ */ ++SYSCALL_DEFINE3(futex_wake, void __user *, uaddr, unsigned int, nr_wake, ++ unsigned int, flags) ++{ ++ return ksys_futex_wake(uaddr, nr_wake, flags); ++} ++ + #ifdef CONFIG_COMPAT + static int compat_futex_parse_requeue(struct compat_futex_requeue __user *rq, + void __user **uaddr, unsigned int *flags) +-- +2.32.0 + + @@ -3,7 +3,7 @@ # Contributor: Jan Alexander Steffens (heftig) <jan dot steffens at gmail dot com> pkgbase=linux-covolunablu-gaming -pkgver=5.12.15.arch1 +pkgver=5.13.8.arch1 pkgrel=1 pkgdesc='Linux' _srctag=v${pkgver%.*}-${pkgver##*.} @@ -21,20 +21,42 @@ source=( "$_srcname::git+https://github.com/archlinux/linux?signed#tag=$_srctag" config # the main kernel config file bfq-default.patch - 0001-futex-wait-multiple.patch - 0002-futex-wait-multiple-proton-compatibility.patch + 0001-futex2-implement-wait-and-wake-functions.patch + 0002-futex2-implement-vectorized-wait.patch + 0003-futex2-implement-requeue-operation.patch + 0004-futex2-documentation.patch +# 0005-futex2-test-wake-wait.patch +# 0006-futex2-test-timeout.patch +# 0007-futex2-test-wouldblock.patch +# 0008-futex2-test-waitv.patch +# 0009-futex2-test-requeue.patch +# 0010-futex2-benchmark.patch + 0011-futex2-enable-waitpid-for-futex2.patch ) validpgpkeys=( 'ABAF11C65A2970B130ABE3C479BE3E4300411886' # Linus Torvalds '647F28654894E3BD457199BE38DBBDC86092693E' # Greg Kroah-Hartman 'A2FF3A36AAA56654109064AB19802F8B0D70FC30' # Jan Alexander Steffens (heftig) + 'C7E7849466FE2358343588377258734B41C31549' # David Runge <dvzrv@archlinux.org> ) sha256sums=('SKIP' - '828d90d788ad44ba1480486081afb3ec730de5b48dfe344662043940a0b42cdf' + 'fcfb29005032125010bcf18ce2f177af7c84c74cff729de8f0cc3e4a552a59a4' # -- covolunablu-gaming patches -- - '136fd376e27fd8503f0ea2c7c3df645fea60a9c05286b53e2bceb7ff8c1d0201' - 'cb37801751ea51bc7e784331132f9390b61e477491f103bec3b48f1e751c79b7' - 'bbbbc90c25659c16f2697b509a15a3969bf0dd277e81b44718a8149e61b51dbc') + 'f6701a4b9ed60ad98396606a4c7db26c7197e76d00a28f5299d2567bf6d17d3d' +# 'cb37801751ea51bc7e784331132f9390b61e477491f103bec3b48f1e751c79b7' +# 'bbbbc90c25659c16f2697b509a15a3969bf0dd277e81b44718a8149e61b51dbc' + '695af5865c0048ccc2a458a151607cb609642ad295b9f562440f7cdec7dffae2' + 'a8183948f375ceb4ac4623531a97aa885b3e4403e50e02c4698af5aaade05bb8' + '2a8c8ed6607150a4ab25db3320b91d15d9693c55b7b01fbbb00d4b323b8a1230' + '91e604ce4fb59df365ad88219269a57bbf09811b0a7ff4833b3fab072ad5b038' +# '001157deded265983c100bd215bad4493de8a4e1e9ede95587018913187ab71a' +# '141ae54946f64596fb9bf4ecf1c885acdaf730aef9a4b2fe9699b026f8827685' +# '40d90f134900c9515a274dae011d4adebdc7f4cafe0a6a833cce55e6a86ee84a' +# '5ca3ad330fb7d792fca01a014280c70231d99de9149044569fc1f96ca0f8aaee' +# '937a01c0c02c05c0a33890ef5a6e3b9f6c7d61b3283d2b79145ae05bc1ae6c88' +# 'c97748f88974c6ffe2e0903ffca524104b22939cddf5cc92c2b064ea5ceab880' + 'c71f09b597b5f97895421dba2e7d76e4fb4338c6b18ed51f5a09e0775f749b4f' +) export KBUILD_BUILD_HOST=covolunablu export KBUILD_BUILD_USER=$pkgbase diff --git a/bfq-default.patch b/bfq-default.patch index 292050f2c69c..717f508cc911 100644 --- a/bfq-default.patch +++ b/bfq-default.patch @@ -1,10 +1,10 @@ diff --git a/block/elevator.c b/block/elevator.c -index 076ba7308e65..81f89095aa77 100644 +index 440699c28119..47fffc18978f 100644 --- a/block/elevator.c +++ b/block/elevator.c -@@ -623,15 +623,15 @@ static inline bool elv_support_iosched(struct request_queue *q) +@@ -616,8 +616,8 @@ static inline bool elv_support_iosched(struct request_queue *q) } - + /* - * For single queue devices, default to using mq-deadline. If we have multiple - * queues or mq-deadline is not available, default to "none". @@ -13,11 +13,12 @@ index 076ba7308e65..81f89095aa77 100644 */ static struct elevator_type *elevator_get_default(struct request_queue *q) { - if (q->nr_hw_queues != 1) +@@ -625,7 +625,7 @@ static struct elevator_type *elevator_get_default(struct request_queue *q) + !blk_mq_is_sbitmap_shared(q->tag_set->flags)) return NULL; - + - return elevator_get(q, "mq-deadline", false); + return elevator_get(q, "bfq", false); } - + /* @@ -1,11 +1,13 @@ # # Automatically generated file; DO NOT EDIT. -# Linux/x86 5.12.14-arch1 Kernel Configuration +# Linux/x86 5.13.4-arch1 Kernel Configuration # CONFIG_CC_VERSION_TEXT="gcc (GCC) 11.1.0" CONFIG_CC_IS_GCC=y CONFIG_GCC_VERSION=110100 CONFIG_CLANG_VERSION=0 +CONFIG_AS_IS_GNU=y +CONFIG_AS_VERSION=23601 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=23601 CONFIG_LLD_VERSION=0 @@ -101,6 +103,24 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y # end of Timers subsystem +CONFIG_BPF=y +CONFIG_HAVE_EBPF_JIT=y +CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y + +# +# BPF subsystem +# +CONFIG_BPF_SYSCALL=y +CONFIG_BPF_JIT=y +CONFIG_BPF_JIT_ALWAYS_ON=y +CONFIG_BPF_JIT_DEFAULT_ON=y +# CONFIG_BPF_UNPRIV_DEFAULT_OFF is not set +CONFIG_USERMODE_DRIVER=y +CONFIG_BPF_PRELOAD=y +CONFIG_BPF_PRELOAD_UMD=m +CONFIG_BPF_LSM=y +# end of BPF subsystem + # CONFIG_PREEMPT_NONE is not set # CONFIG_PREEMPT_VOLUNTARY is not set CONFIG_PREEMPT=y @@ -194,6 +214,7 @@ CONFIG_CGROUP_DEVICE=y CONFIG_CGROUP_CPUACCT=y CONFIG_CGROUP_PERF=y CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_MISC=y # CONFIG_CGROUP_DEBUG is not set CONFIG_SOCK_CGROUP_DATA=y CONFIG_NAMESPACES=y @@ -225,7 +246,6 @@ CONFIG_SYSCTL=y CONFIG_HAVE_UID16=y CONFIG_SYSCTL_EXCEPTION_TRACE=y CONFIG_HAVE_PCSPKR_PLATFORM=y -CONFIG_BPF=y # CONFIG_EXPERT is not set CONFIG_UID16=y CONFIG_MULTIUSER=y @@ -250,19 +270,12 @@ CONFIG_AIO=y CONFIG_IO_URING=y CONFIG_ADVISE_SYSCALLS=y CONFIG_HAVE_ARCH_USERFAULTFD_WP=y +CONFIG_HAVE_ARCH_USERFAULTFD_MINOR=y CONFIG_MEMBARRIER=y CONFIG_KALLSYMS=y CONFIG_KALLSYMS_ALL=y CONFIG_KALLSYMS_ABSOLUTE_PERCPU=y CONFIG_KALLSYMS_BASE_RELATIVE=y -CONFIG_BPF_LSM=y -CONFIG_BPF_SYSCALL=y -CONFIG_ARCH_WANT_DEFAULT_BPF_JIT=y -CONFIG_BPF_JIT_ALWAYS_ON=y -CONFIG_BPF_JIT_DEFAULT_ON=y -CONFIG_USERMODE_DRIVER=y -CONFIG_BPF_PRELOAD=y -CONFIG_BPF_PRELOAD_UMD=m CONFIG_USERFAULTFD=y CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y CONFIG_KCMP=y @@ -310,7 +323,6 @@ CONFIG_GENERIC_BUG_RELATIVE_POINTERS=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_ARCH_HAS_CPU_RELAX=y -CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_FILTER_PGPROT=y CONFIG_HAVE_SETUP_PER_CPU_AREA=y CONFIG_NEED_PER_CPU_EMBED_FIRST_CHUNK=y @@ -451,6 +463,7 @@ CONFIG_X86_PMEM_LEGACY_DEVICE=y CONFIG_X86_PMEM_LEGACY=m CONFIG_X86_CHECK_BIOS_CORRUPTION=y CONFIG_X86_BOOTPARAM_MEMORY_CORRUPTION_CHECK=y +CONFIG_X86_RESERVE_LOW=64 CONFIG_MTRR=y CONFIG_MTRR_SANITIZER=y CONFIG_MTRR_SANITIZER_ENABLE_DEFAULT=1 @@ -502,12 +515,8 @@ CONFIG_HAVE_LIVEPATCH=y # end of Processor type and features CONFIG_ARCH_HAS_ADD_PAGES=y -CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y -CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y +CONFIG_ARCH_MHP_MEMMAP_ON_MEMORY_ENABLE=y CONFIG_USE_PERCPU_NUMA_NODE_ID=y -CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y -CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y -CONFIG_ARCH_ENABLE_THP_MIGRATION=y # # Power management and ACPI options @@ -751,6 +760,7 @@ CONFIG_KVM_XFER_TO_GUEST_WORK=y CONFIG_VIRTUALIZATION=y CONFIG_KVM=m CONFIG_KVM_INTEL=m +CONFIG_X86_SGX_KVM=y CONFIG_KVM_AMD=m CONFIG_KVM_AMD_SEV=y CONFIG_KVM_XEN=y @@ -857,6 +867,8 @@ CONFIG_COMPAT_OLD_SIGACTION=y CONFIG_COMPAT_32BIT_TIME=y CONFIG_HAVE_ARCH_VMAP_STACK=y CONFIG_VMAP_STACK=y +CONFIG_HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET=y +# CONFIG_RANDOMIZE_KSTACK_OFFSET_DEFAULT is not set CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y CONFIG_STRICT_KERNEL_RWX=y CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y @@ -903,10 +915,12 @@ CONFIG_MODULE_SIG_ALL=y # CONFIG_MODULE_SIG_SHA384 is not set CONFIG_MODULE_SIG_SHA512=y CONFIG_MODULE_SIG_HASH="sha512" -CONFIG_MODULE_COMPRESS=y +# CONFIG_MODULE_COMPRESS_NONE is not set # CONFIG_MODULE_COMPRESS_GZIP is not set -CONFIG_MODULE_COMPRESS_XZ=y +# CONFIG_MODULE_COMPRESS_XZ is not set +CONFIG_MODULE_COMPRESS_ZSTD=y CONFIG_MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS=y +CONFIG_MODPROBE_PATH="/sbin/modprobe" CONFIG_MODULES_TREE_LOOKUP=y CONFIG_BLOCK=y CONFIG_BLK_RQ_ALLOC_TIME=y @@ -1015,19 +1029,24 @@ CONFIG_HAVE_FAST_GUP=y CONFIG_NUMA_KEEP_MEMINFO=y CONFIG_MEMORY_ISOLATION=y CONFIG_HAVE_BOOTMEM_INFO_NODE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG=y CONFIG_MEMORY_HOTPLUG_SPARSE=y CONFIG_MEMORY_HOTPLUG_DEFAULT_ONLINE=y +CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y CONFIG_MEMORY_HOTREMOVE=y +CONFIG_MHP_MEMMAP_ON_MEMORY=y CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_ARCH_ENABLE_SPLIT_PMD_PTLOCK=y CONFIG_MEMORY_BALLOON=y CONFIG_BALLOON_COMPACTION=y CONFIG_COMPACTION=y CONFIG_PAGE_REPORTING=y CONFIG_MIGRATION=y +CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION=y +CONFIG_ARCH_ENABLE_THP_MIGRATION=y CONFIG_CONTIG_ALLOC=y CONFIG_PHYS_ADDR_T_64BIT=y -CONFIG_BOUNCE=y CONFIG_VIRT_TO_BUS=y CONFIG_MMU_NOTIFIER=y CONFIG_KSM=y @@ -1045,6 +1064,7 @@ CONFIG_FRONTSWAP=y CONFIG_CMA=y # CONFIG_CMA_DEBUG is not set CONFIG_CMA_DEBUGFS=y +CONFIG_CMA_SYSFS=y CONFIG_CMA_AREAS=7 CONFIG_MEM_SOFT_DIRTY=y CONFIG_ZSWAP=y @@ -1068,6 +1088,7 @@ CONFIG_ZSMALLOC=y CONFIG_GENERIC_EARLY_IOREMAP=y # CONFIG_DEFERRED_STRUCT_PAGE_INIT is not set CONFIG_IDLE_PAGE_TRACKING=y +CONFIG_ARCH_HAS_CACHE_LINE_SIZE=y CONFIG_ARCH_HAS_PTE_DEVMAP=y CONFIG_ZONE_DEVICE=y CONFIG_DEV_PAGEMAP_OPS=y @@ -1230,8 +1251,7 @@ CONFIG_NETFILTER_NETLINK_QUEUE=m CONFIG_NETFILTER_NETLINK_LOG=m CONFIG_NETFILTER_NETLINK_OSF=m CONFIG_NF_CONNTRACK=m -CONFIG_NF_LOG_COMMON=m -CONFIG_NF_LOG_NETDEV=m +CONFIG_NF_LOG_SYSLOG=m CONFIG_NETFILTER_CONNCOUNT=m CONFIG_NF_CONNTRACK_MARK=y CONFIG_NF_CONNTRACK_SECMARK=y @@ -1305,6 +1325,7 @@ CONFIG_NFT_REJECT_NETDEV=m CONFIG_NF_FLOW_TABLE_INET=m CONFIG_NF_FLOW_TABLE=m CONFIG_NETFILTER_XTABLES=m +CONFIG_NETFILTER_XTABLES_COMPAT=y # # Xtables combined modules @@ -1545,7 +1566,6 @@ CONFIG_NF_DEFRAG_IPV6=m CONFIG_NF_TABLES_BRIDGE=m CONFIG_NFT_BRIDGE_META=m CONFIG_NFT_BRIDGE_REJECT=m -CONFIG_NF_LOG_BRIDGE=m CONFIG_NF_CONNTRACK_BRIDGE=m CONFIG_BRIDGE_NF_EBTABLES=m CONFIG_BRIDGE_EBT_BROUTE=m @@ -1607,12 +1627,12 @@ CONFIG_BRIDGE_IGMP_SNOOPING=y CONFIG_BRIDGE_VLAN_FILTERING=y CONFIG_BRIDGE_MRP=y CONFIG_BRIDGE_CFM=y -CONFIG_HAVE_NET_DSA=y CONFIG_NET_DSA=m CONFIG_NET_DSA_TAG_8021Q=m CONFIG_NET_DSA_TAG_AR9331=m CONFIG_NET_DSA_TAG_BRCM_COMMON=m CONFIG_NET_DSA_TAG_BRCM=m +CONFIG_NET_DSA_TAG_BRCM_LEGACY=m CONFIG_NET_DSA_TAG_BRCM_PREPEND=m CONFIG_NET_DSA_TAG_HELLCREEK=m CONFIG_NET_DSA_TAG_GSWIP=m @@ -1800,6 +1820,7 @@ CONFIG_QRTR_TUN=m CONFIG_QRTR_MHI=m CONFIG_NET_NCSI=y CONFIG_NCSI_OEM_CMD_GET_MAC=y +CONFIG_PCPU_DEV_REFCNT=y CONFIG_RPS=y CONFIG_RFS_ACCEL=y CONFIG_SOCK_RX_QUEUE_MAPPING=y @@ -1808,7 +1829,6 @@ CONFIG_CGROUP_NET_PRIO=y CONFIG_CGROUP_NET_CLASSID=y CONFIG_NET_RX_BUSY_POLL=y CONFIG_BQL=y -CONFIG_BPF_JIT=y CONFIG_BPF_STREAM_PARSER=y CONFIG_NET_FLOW_LIMIT=y @@ -1900,6 +1920,7 @@ CONFIG_CAN_MCP251XFD=m CONFIG_CAN_8DEV_USB=m CONFIG_CAN_EMS_USB=m CONFIG_CAN_ESD_USB2=m +CONFIG_CAN_ETAS_ES58X=m CONFIG_CAN_GS_USB=m CONFIG_CAN_KVASER_USB=m CONFIG_CAN_MCBA_USB=m @@ -1924,6 +1945,7 @@ CONFIG_BT_LE=y CONFIG_BT_6LOWPAN=m CONFIG_BT_LEDS=y CONFIG_BT_MSFTEXT=y +CONFIG_BT_AOSPEXT=y CONFIG_BT_DEBUGFS=y # CONFIG_BT_SELFTEST is not set @@ -1967,6 +1989,7 @@ CONFIG_BT_ATH3K=m CONFIG_BT_MTKSDIO=m CONFIG_BT_MTKUART=m CONFIG_BT_HCIRSI=m +CONFIG_BT_VIRTIO=m # end of Bluetooth device drivers CONFIG_AF_RXRPC=m @@ -2075,12 +2098,12 @@ CONFIG_LWTUNNEL_BPF=y CONFIG_DST_CACHE=y CONFIG_GRO_CELLS=y CONFIG_SOCK_VALIDATE_XMIT=y +CONFIG_NET_SELFTESTS=m CONFIG_NET_SOCK_MSG=y CONFIG_NET_DEVLINK=y CONFIG_PAGE_POOL=y CONFIG_FAILOVER=m CONFIG_ETHTOOL_NETLINK=y -CONFIG_HAVE_EBPF_JIT=y # # Device Drivers @@ -2229,6 +2252,7 @@ CONFIG_REGMAP_W1=m CONFIG_REGMAP_MMIO=y CONFIG_REGMAP_IRQ=y CONFIG_REGMAP_SOUNDWIRE=m +CONFIG_REGMAP_SOUNDWIRE_MBQ=m CONFIG_REGMAP_SCCB=m CONFIG_REGMAP_SPI_AVMM=m CONFIG_DMA_SHARED_BUFFER=y @@ -2274,7 +2298,6 @@ CONFIG_MTD_BLOCK=m # CONFIG_SSFDC is not set # CONFIG_SM_FTL is not set # CONFIG_MTD_OOPS is not set -CONFIG_MTD_PSTORE=m # CONFIG_MTD_SWAP is not set # CONFIG_MTD_PARTITIONED_MASTER is not set @@ -2410,7 +2433,6 @@ CONFIG_ZRAM_DEF_COMP_LZORLE=y CONFIG_ZRAM_DEF_COMP="lzo-rle" CONFIG_ZRAM_WRITEBACK=y # CONFIG_ZRAM_MEMORY_TRACKING is not set -CONFIG_BLK_DEV_UMEM=m CONFIG_BLK_DEV_LOOP=m CONFIG_BLK_DEV_LOOP_MIN_COUNT=0 CONFIG_BLK_DEV_CRYPTOLOOP=m @@ -2480,10 +2502,10 @@ CONFIG_DS1682=m CONFIG_VMWARE_BALLOON=m CONFIG_LATTICE_ECP3_CONFIG=m # CONFIG_SRAM is not set +CONFIG_DW_XDATA_PCIE=m CONFIG_PCI_ENDPOINT_TEST=m CONFIG_XILINX_SDFEC=m CONFIG_MISC_RTSX=m -CONFIG_PVPANIC=m CONFIG_C2PORT=m CONFIG_C2PORT_DURAMAR_2150=m @@ -2527,6 +2549,9 @@ CONFIG_MISC_RTSX_PCI=m CONFIG_MISC_RTSX_USB=m CONFIG_HABANA_AI=m CONFIG_UACCE=m +CONFIG_PVPANIC=y +CONFIG_PVPANIC_MMIO=m +CONFIG_PVPANIC_PCI=m # end of Misc devices CONFIG_HAVE_IDE=y @@ -2963,6 +2988,7 @@ CONFIG_NET_DSA_MICROCHIP_KSZ9477_I2C=m CONFIG_NET_DSA_MICROCHIP_KSZ9477_SPI=m CONFIG_NET_DSA_MICROCHIP_KSZ8795=m CONFIG_NET_DSA_MICROCHIP_KSZ8795_SPI=m +CONFIG_NET_DSA_MICROCHIP_KSZ8863_SMI=m CONFIG_NET_DSA_MV88E6XXX=m CONFIG_NET_DSA_MV88E6XXX_PTP=y CONFIG_NET_DSA_MSCC_SEVILLE=m @@ -3125,6 +3151,8 @@ CONFIG_I40EVF=m CONFIG_ICE=m CONFIG_FM10K=m CONFIG_IGC=m +CONFIG_NET_VENDOR_MICROSOFT=y +CONFIG_MICROSOFT_MANA=m CONFIG_JME=m CONFIG_NET_VENDOR_MARVELL=y CONFIG_MVMDIO=m @@ -3151,6 +3179,7 @@ CONFIG_MLX5_MPFS=y CONFIG_MLX5_ESWITCH=y CONFIG_MLX5_CLS_ACT=y CONFIG_MLX5_TC_CT=y +CONFIG_MLX5_TC_SAMPLE=y CONFIG_MLX5_CORE_EN_DCB=y CONFIG_MLX5_CORE_IPOIB=y CONFIG_MLX5_FPGA_IPSEC=y @@ -3309,7 +3338,6 @@ CONFIG_NET_VENDOR_XIRCOM=y CONFIG_PCMCIA_XIRC2PS=m CONFIG_FDDI=m CONFIG_DEFXX=m -CONFIG_DEFXX_MMIO=y CONFIG_SKFP=m # CONFIG_HIPPI is not set CONFIG_NET_SB1000=m @@ -3342,11 +3370,13 @@ CONFIG_INTEL_XWAY_PHY=m CONFIG_LSI_ET1011C_PHY=m CONFIG_MARVELL_PHY=m CONFIG_MARVELL_10G_PHY=m +CONFIG_MARVELL_88X2222_PHY=m CONFIG_MICREL_PHY=m CONFIG_MICROCHIP_PHY=m CONFIG_MICROCHIP_T1_PHY=m CONFIG_MICROSEMI_PHY=m CONFIG_NATIONAL_PHY=m +CONFIG_NXP_C45_TJA11XX_PHY=m CONFIG_NXP_TJA11XX_PHY=m CONFIG_AT803X_PHY=m CONFIG_QSEMI_PHY=m @@ -3777,6 +3807,14 @@ CONFIG_IEEE802154_CA8210=m # CONFIG_IEEE802154_CA8210_DEBUGFS is not set CONFIG_IEEE802154_MCR20A=m CONFIG_IEEE802154_HWSIM=m + +# +# Wireless WAN +# +CONFIG_WWAN=y +CONFIG_MHI_WWAN_CTRL=m +# end of Wireless WAN + CONFIG_XEN_NETDEV_FRONTEND=m CONFIG_XEN_NETDEV_BACKEND=m CONFIG_VMXNET3=m @@ -3939,7 +3977,6 @@ CONFIG_TABLET_USB_KBTAB=m CONFIG_TABLET_USB_PEGASUS=m CONFIG_TABLET_SERIAL_WACOM4=m CONFIG_INPUT_TOUCHSCREEN=y -CONFIG_TOUCHSCREEN_PROPERTIES=y CONFIG_TOUCHSCREEN_88PM860X=m CONFIG_TOUCHSCREEN_ADS7846=m CONFIG_TOUCHSCREEN_AD7877=m @@ -3971,7 +4008,9 @@ CONFIG_TOUCHSCREEN_EXC3000=m CONFIG_TOUCHSCREEN_FUJITSU=m CONFIG_TOUCHSCREEN_GOODIX=m CONFIG_TOUCHSCREEN_HIDEEP=m +CONFIG_TOUCHSCREEN_HYCON_HY46XX=m CONFIG_TOUCHSCREEN_ILI210X=m +CONFIG_TOUCHSCREEN_ILITEK=m CONFIG_TOUCHSCREEN_S6SY761=m CONFIG_TOUCHSCREEN_GUNZE=m CONFIG_TOUCHSCREEN_EKTF2127=m @@ -3983,6 +4022,7 @@ CONFIG_TOUCHSCREEN_MAX11801=m CONFIG_TOUCHSCREEN_MCS5000=m CONFIG_TOUCHSCREEN_MMS114=m CONFIG_TOUCHSCREEN_MELFAS_MIP4=m +CONFIG_TOUCHSCREEN_MSG2638=m CONFIG_TOUCHSCREEN_MTOUCH=m CONFIG_TOUCHSCREEN_INEXIO=m CONFIG_TOUCHSCREEN_MK712=m @@ -4048,6 +4088,7 @@ CONFIG_INPUT_AD714X=m CONFIG_INPUT_AD714X_I2C=m CONFIG_INPUT_AD714X_SPI=m CONFIG_INPUT_ARIZONA_HAPTICS=m +CONFIG_INPUT_ATC260X_ONKEY=m CONFIG_INPUT_BMA150=m CONFIG_INPUT_E3X0_BUTTON=m CONFIG_INPUT_PCSPKR=m @@ -4091,6 +4132,7 @@ CONFIG_INPUT_ADXL34X_I2C=m CONFIG_INPUT_ADXL34X_SPI=m CONFIG_INPUT_IMS_PCU=m CONFIG_INPUT_IQS269A=m +CONFIG_INPUT_IQS626A=m CONFIG_INPUT_CMA3000=m CONFIG_INPUT_CMA3000_I2C=m CONFIG_INPUT_XEN_KBDDEV_FRONTEND=m @@ -4216,19 +4258,13 @@ CONFIG_SERIAL_SPRD=m CONFIG_SERIAL_MCTRL_GPIO=y CONFIG_SERIAL_NONSTANDARD=y -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -CONFIG_CYZ_INTR=y CONFIG_MOXA_INTELLIO=m CONFIG_MOXA_SMARTIO=m CONFIG_SYNCLINK_GT=m -CONFIG_ISI=m CONFIG_N_HDLC=m CONFIG_N_GSM=m CONFIG_NOZOMI=m CONFIG_NULL_TTY=m -CONFIG_TRACE_ROUTER=m -CONFIG_TRACE_SINK=m CONFIG_HVC_DRIVER=y CONFIG_HVC_IRQ=y CONFIG_HVC_XEN=y @@ -4271,7 +4307,6 @@ CONFIG_IPWIRELESS=m CONFIG_MWAVE=m CONFIG_DEVMEM=y -# CONFIG_DEVKMEM is not set CONFIG_NVRAM=y CONFIG_RAW_DRIVER=m CONFIG_MAX_RAW_DEVS=8192 @@ -4388,6 +4423,7 @@ CONFIG_I2C_XILINX=m # CONFIG_I2C_DIOLAN_U2C=m CONFIG_I2C_DLN2=m +CONFIG_I2C_CP2615=m CONFIG_I2C_PARPORT=m CONFIG_I2C_ROBOTFUZZ_OSIF=m CONFIG_I2C_TAOS_EVM=m @@ -4420,6 +4456,8 @@ CONFIG_SPI_MEM=y # SPI Master Controller Drivers # CONFIG_SPI_ALTERA=m +CONFIG_SPI_ALTERA_CORE=m +CONFIG_SPI_ALTERA_DFL=m CONFIG_SPI_AXI_SPI_ENGINE=m CONFIG_SPI_BITBANG=m CONFIG_SPI_BUTTERFLY=m @@ -4684,6 +4722,7 @@ CONFIG_W1_SLAVE_DS28E17=m # end of 1-wire Slaves CONFIG_POWER_RESET=y +CONFIG_POWER_RESET_ATC260X=m CONFIG_POWER_RESET_MT6323=y CONFIG_POWER_RESET_RESTART=y CONFIG_POWER_SUPPLY=y @@ -4751,11 +4790,14 @@ CONFIG_CHARGER_BQ256XX=m CONFIG_CHARGER_SMB347=m CONFIG_CHARGER_TPS65090=m CONFIG_BATTERY_GAUGE_LTC2941=m +CONFIG_BATTERY_GOLDFISH=m CONFIG_BATTERY_RT5033=m CONFIG_CHARGER_RT9455=m CONFIG_CHARGER_CROS_USBPD=m CONFIG_CHARGER_BD99954=m CONFIG_CHARGER_WILCO=m +CONFIG_BATTERY_SURFACE=m +CONFIG_CHARGER_SURFACE=m CONFIG_HWMON=y CONFIG_HWMON_VID=m # CONFIG_HWMON_DEBUG_CHIP is not set @@ -4789,7 +4831,6 @@ CONFIG_SENSORS_AXI_FAN_CONTROL=m CONFIG_SENSORS_K8TEMP=m CONFIG_SENSORS_K10TEMP=m CONFIG_SENSORS_FAM15H_POWER=m -CONFIG_SENSORS_AMD_ENERGY=m CONFIG_SENSORS_APPLESMC=m CONFIG_SENSORS_ASB100=m CONFIG_SENSORS_ASPEED=m @@ -4880,15 +4921,19 @@ CONFIG_SENSORS_NCT6775=m CONFIG_SENSORS_NCT7802=m CONFIG_SENSORS_NCT7904=m CONFIG_SENSORS_NPCM7XX=m +CONFIG_SENSORS_NZXT_KRAKEN2=m CONFIG_SENSORS_PCF8591=m CONFIG_PMBUS=m CONFIG_SENSORS_PMBUS=m CONFIG_SENSORS_ADM1266=m CONFIG_SENSORS_ADM1275=m CONFIG_SENSORS_BEL_PFE=m +CONFIG_SENSORS_BPA_RS600=m +CONFIG_SENSORS_FSP_3Y=m CONFIG_SENSORS_IBM_CFFPS=m CONFIG_SENSORS_INSPUR_IPSPS=m CONFIG_SENSORS_IR35221=m +CONFIG_SENSORS_IR36021=m CONFIG_SENSORS_IR38064=m CONFIG_SENSORS_IRPS5401=m CONFIG_SENSORS_ISL68137=m @@ -4896,6 +4941,7 @@ CONFIG_SENSORS_LM25066=m CONFIG_SENSORS_LTC2978=m # CONFIG_SENSORS_LTC2978_REGULATOR is not set CONFIG_SENSORS_LTC3815=m +CONFIG_SENSORS_MAX15301=m CONFIG_SENSORS_MAX16064=m CONFIG_SENSORS_MAX16601=m CONFIG_SENSORS_MAX20730=m @@ -4907,6 +4953,7 @@ CONFIG_SENSORS_MP2975=m CONFIG_SENSORS_PM6764TR=m CONFIG_SENSORS_PXE1610=m CONFIG_SENSORS_Q54SJ108A2=m +CONFIG_SENSORS_STPDDC60=m CONFIG_SENSORS_TPS40422=m CONFIG_SENSORS_TPS53679=m CONFIG_SENSORS_UCD9000=m @@ -5009,6 +5056,7 @@ CONFIG_PROC_THERMAL_MMIO_RAPL=m CONFIG_INTEL_BXT_PMIC_THERMAL=m CONFIG_INTEL_PCH_THERMAL=m +CONFIG_INTEL_TCC_COOLING=m # end of Intel thermal drivers CONFIG_GENERIC_ADC_THERMAL=m @@ -5207,9 +5255,6 @@ CONFIG_MFD_SI476X_CORE=m CONFIG_MFD_SM501=m CONFIG_MFD_SM501_GPIO=y CONFIG_MFD_SKY81452=m -CONFIG_ABX500_CORE=y -CONFIG_AB3100_CORE=y -CONFIG_AB3100_OTP=y CONFIG_MFD_SYSCON=y CONFIG_MFD_TI_AM335X_TSCADC=m CONFIG_MFD_LP3943=m @@ -5252,6 +5297,8 @@ CONFIG_MFD_WM8350=y CONFIG_MFD_WM8350_I2C=y CONFIG_MFD_WM8994=m CONFIG_MFD_WCD934X=m +CONFIG_MFD_ATC260X=m +CONFIG_MFD_ATC260X_I2C=m CONFIG_RAVE_SP_CORE=m CONFIG_MFD_INTEL_M10_BMC=m # end of Multifunction device drivers @@ -5270,6 +5317,7 @@ CONFIG_REGULATOR_AAT2870=m CONFIG_REGULATOR_ARIZONA_LDO1=m CONFIG_REGULATOR_ARIZONA_MICSUPP=m CONFIG_REGULATOR_AS3711=m +CONFIG_REGULATOR_ATC260X=m CONFIG_REGULATOR_AXP20X=m CONFIG_REGULATOR_BCM590XX=m CONFIG_REGULATOR_BD9571MWV=m @@ -6165,7 +6213,6 @@ CONFIG_DRM_AMDGPU=m CONFIG_DRM_AMDGPU_SI=y CONFIG_DRM_AMDGPU_CIK=y CONFIG_DRM_AMDGPU_USERPTR=y -# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set # # ACP (Audio CoProcessor) Configuration @@ -6180,6 +6227,7 @@ CONFIG_DRM_AMD_DC=y CONFIG_DRM_AMD_DC_DCN=y CONFIG_DRM_AMD_DC_HDCP=y CONFIG_DRM_AMD_DC_SI=y +CONFIG_DRM_AMD_SECURE_DISPLAY=y # end of Display Engine Configuration CONFIG_HSA_AMD=y @@ -6198,6 +6246,7 @@ CONFIG_DRM_I915_COMPRESS_ERROR=y CONFIG_DRM_I915_USERPTR=y CONFIG_DRM_I915_GVT=y CONFIG_DRM_I915_GVT_KVMGT=m +CONFIG_DRM_I915_REQUEST_TIMEOUT=20000 CONFIG_DRM_I915_FENCE_TIMEOUT=10000 CONFIG_DRM_I915_USERFAULT_AUTOSUSPEND=250 CONFIG_DRM_I915_HEARTBEAT_INTERVAL=2500 @@ -6210,7 +6259,6 @@ CONFIG_DRM_VKMS=m CONFIG_DRM_VMWGFX=m CONFIG_DRM_VMWGFX_FBCON=y CONFIG_DRM_GMA500=m -CONFIG_DRM_GMA600=y CONFIG_DRM_UDL=m CONFIG_DRM_AST=m CONFIG_DRM_MGAG200=m @@ -6249,6 +6297,7 @@ CONFIG_TINYDRM_ST7735R=m CONFIG_DRM_XEN=y CONFIG_DRM_XEN_FRONTEND=m CONFIG_DRM_VBOXVIDEO=m +CONFIG_DRM_GUD=m # CONFIG_DRM_LEGACY is not set CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y @@ -6423,6 +6472,7 @@ CONFIG_SND_DEBUG=y # CONFIG_SND_JACK_INJECTION_DEBUG is not set CONFIG_SND_VMASTER=y CONFIG_SND_DMA_SGBUF=y +CONFIG_SND_CTL_LED=m CONFIG_SND_SEQUENCER=m CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_SEQUENCER_OSS=m @@ -6628,6 +6678,7 @@ CONFIG_SND_DESIGNWARE_PCM=y # CONFIG_SND_SOC_FSL_ESAI is not set # CONFIG_SND_SOC_FSL_MICFIL is not set CONFIG_SND_SOC_FSL_XCVR=m +CONFIG_SND_SOC_FSL_RPMSG=m # CONFIG_SND_SOC_IMX_AUDMUX is not set # end of SoC Audio for Freescale CPUs @@ -6857,8 +6908,10 @@ CONFIG_SND_SOC_RT286=m CONFIG_SND_SOC_RT298=m CONFIG_SND_SOC_RT1011=m CONFIG_SND_SOC_RT1015=m +CONFIG_SND_SOC_RT1015P=m CONFIG_SND_SOC_RT1308=m CONFIG_SND_SOC_RT1308_SDW=m +CONFIG_SND_SOC_RT1316_SDW=m CONFIG_SND_SOC_RT5514=m CONFIG_SND_SOC_RT5514_SPI=m CONFIG_SND_SOC_RT5616=m @@ -6879,8 +6932,10 @@ CONFIG_SND_SOC_RT700=m CONFIG_SND_SOC_RT700_SDW=m CONFIG_SND_SOC_RT711=m CONFIG_SND_SOC_RT711_SDW=m +CONFIG_SND_SOC_RT711_SDCA_SDW=m CONFIG_SND_SOC_RT715=m CONFIG_SND_SOC_RT715_SDW=m +CONFIG_SND_SOC_RT715_SDCA_SDW=m CONFIG_SND_SOC_SGTL5000=m CONFIG_SND_SOC_SI476X=m CONFIG_SND_SOC_SIGMADSP=m @@ -6915,6 +6970,8 @@ CONFIG_SND_SOC_TLV320AIC32X4=m CONFIG_SND_SOC_TLV320AIC32X4_I2C=m CONFIG_SND_SOC_TLV320AIC32X4_SPI=m CONFIG_SND_SOC_TLV320AIC3X=m +CONFIG_SND_SOC_TLV320AIC3X_I2C=m +CONFIG_SND_SOC_TLV320AIC3X_SPI=m CONFIG_SND_SOC_TLV320ADCX140=m CONFIG_SND_SOC_TS3A227E=m CONFIG_SND_SOC_TSCS42XX=m @@ -6973,6 +7030,7 @@ CONFIG_SND_X86=y CONFIG_HDMI_LPE_AUDIO=m CONFIG_SND_SYNTH_EMUX=m CONFIG_SND_XEN_FRONTEND=m +CONFIG_SND_VIRTIO=m CONFIG_AC97_BUS=m # @@ -7015,6 +7073,7 @@ CONFIG_HID_ELAN=m CONFIG_HID_ELECOM=m CONFIG_HID_ELO=m CONFIG_HID_EZKEY=m +CONFIG_HID_FT260=m CONFIG_HID_GEMBIRD=m CONFIG_HID_GFRM=m CONFIG_HID_GLORIOUS=m @@ -7072,6 +7131,7 @@ CONFIG_HID_RETRODE=m CONFIG_HID_ROCCAT=m CONFIG_HID_SAITEK=m CONFIG_HID_SAMSUNG=m +CONFIG_HID_SEMITEK=m CONFIG_HID_SONY=m CONFIG_SONY_FF=y CONFIG_HID_SPEEDLINK=m @@ -7131,6 +7191,15 @@ CONFIG_INTEL_ISH_FIRMWARE_DOWNLOADER=m # CONFIG_AMD_SFH_HID=m # end of AMD SFH HID Support + +# +# Surface System Aggregator Module HID support +# +CONFIG_SURFACE_HID=m +CONFIG_SURFACE_KBD=m +# end of Surface System Aggregator Module HID support + +CONFIG_SURFACE_HID_CORE=m # end of HID support CONFIG_USB_OHCI_LITTLE_ENDIAN=y @@ -7519,8 +7588,8 @@ CONFIG_TYPEC_WCOVE=m CONFIG_TYPEC_UCSI=m CONFIG_UCSI_CCG=m CONFIG_UCSI_ACPI=m -CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_TPS6598X=m +CONFIG_TYPEC_HD3SS3220=m CONFIG_TYPEC_STUSB160X=m # @@ -7681,11 +7750,6 @@ CONFIG_LEDS_TRIGGER_NETDEV=m CONFIG_LEDS_TRIGGER_PATTERN=m CONFIG_LEDS_TRIGGER_AUDIO=m CONFIG_LEDS_TRIGGER_TTY=m - -# -# LED Blink -# -CONFIG_LEDS_BLINK=y CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y @@ -7769,7 +7833,7 @@ CONFIG_EDAC_SBRIDGE=m CONFIG_EDAC_SKX=m CONFIG_EDAC_I10NM=m CONFIG_EDAC_PND2=m -CONFIG_EDAC_IGEN6=m +# CONFIG_EDAC_IGEN6 is not set CONFIG_RTC_LIB=y CONFIG_RTC_MC146818_LIB=y CONFIG_RTC_CLASS=y @@ -7909,6 +7973,7 @@ CONFIG_RTC_DRV_MT6397=m # HID Sensor RTC drivers # CONFIG_RTC_DRV_HID_SENSOR_TIME=m +CONFIG_RTC_DRV_GOLDFISH=m CONFIG_RTC_DRV_WILCO_EC=m CONFIG_DMADEVICES=y # CONFIG_DMADEVICES_DEBUG is not set @@ -7923,6 +7988,7 @@ CONFIG_ALTERA_MSGDMA=m CONFIG_INTEL_IDMA64=m CONFIG_INTEL_IDXD=m CONFIG_INTEL_IDXD_SVM=y +CONFIG_INTEL_IDXD_PERFMON=y CONFIG_INTEL_IOATDMA=m CONFIG_PLX_DMA=m CONFIG_QCOM_HIDMA_MGMT=m @@ -7988,6 +8054,7 @@ CONFIG_UIO_NETX=m CONFIG_UIO_PRUSS=m CONFIG_UIO_MF624=m CONFIG_UIO_HV_GENERIC=m +CONFIG_UIO_DFL=m CONFIG_VFIO_IOMMU_TYPE1=m CONFIG_VFIO_VIRQFD=m CONFIG_VFIO=m @@ -8005,6 +8072,7 @@ CONFIG_VBOXGUEST=m CONFIG_NITRO_ENCLAVES=m CONFIG_ACRN_HSM=m CONFIG_VIRTIO=y +CONFIG_ARCH_HAS_RESTRICTED_VIRTIO_MEMORY_ACCESS=y CONFIG_VIRTIO_PCI_LIB=m CONFIG_VIRTIO_MENU=y CONFIG_VIRTIO_PCI=m @@ -8020,9 +8088,11 @@ CONFIG_VIRTIO_DMA_SHARED_BUFFER=m CONFIG_VDPA=m CONFIG_VDPA_SIM=m CONFIG_VDPA_SIM_NET=m +CONFIG_VDPA_SIM_BLOCK=m CONFIG_IFCVF=m CONFIG_MLX5_VDPA=y CONFIG_MLX5_VDPA_NET=m +CONFIG_VP_VDPA=m CONFIG_VHOST_IOTLB=m CONFIG_VHOST_RING=m CONFIG_VHOST=m @@ -8078,9 +8148,9 @@ CONFIG_XEN_UNPOPULATED_ALLOC=y # end of Xen driver support # CONFIG_GREYBUS is not set +# CONFIG_COMEDI is not set CONFIG_STAGING=y CONFIG_PRISM2_USB=m -# CONFIG_COMEDI is not set CONFIG_RTL8192U=m CONFIG_RTLLIB=m CONFIG_RTLLIB_CRYPTO_CCMP=m @@ -8124,7 +8194,6 @@ CONFIG_ADT7316_I2C=m # # Capacitance to digital converters # -CONFIG_AD7150=m CONFIG_AD7746=m # end of Capacitance to digital converters @@ -8189,19 +8258,10 @@ CONFIG_UNISYS_VISORHBA=m # CONFIG_FB_TFT is not set CONFIG_MOST_COMPONENTS=m CONFIG_MOST_NET=m -CONFIG_MOST_SOUND=m CONFIG_MOST_VIDEO=m CONFIG_MOST_I2C=m CONFIG_KS7010=m CONFIG_PI433=m - -# -# Gasket devices -# -CONFIG_STAGING_GASKET_FRAMEWORK=m -CONFIG_STAGING_APEX_DRIVER=m -# end of Gasket devices - CONFIG_FIELDBUS_DEV=m CONFIG_KPC2000=y CONFIG_KPC2000_CORE=m @@ -8209,11 +8269,6 @@ CONFIG_KPC2000_SPI=m CONFIG_KPC2000_I2C=m CONFIG_KPC2000_DMA=m CONFIG_QLGE=m -CONFIG_WIMAX=m -CONFIG_WIMAX_DEBUG_LEVEL=8 -CONFIG_WIMAX_I2400M=m -CONFIG_WIMAX_I2400M_USB=m -CONFIG_WIMAX_I2400M_DEBUG_LEVEL=8 CONFIG_WFX=m CONFIG_X86_PLATFORM_DEVICES=y CONFIG_ACPI_WMI=m @@ -8224,10 +8279,12 @@ CONFIG_INTEL_WMI_THUNDERBOLT=m CONFIG_MXM_WMI=m CONFIG_PEAQ_WMI=m CONFIG_XIAOMI_WMI=m +CONFIG_GIGABYTE_WMI=m CONFIG_ACERHDF=m CONFIG_ACER_WIRELESS=m CONFIG_ACER_WMI=m CONFIG_AMD_PMC=m +CONFIG_ADV_SWBUTTON=m CONFIG_APPLE_GMUX=m CONFIG_ASUS_LAPTOP=m CONFIG_ASUS_WIRELESS=m @@ -8353,8 +8410,11 @@ CONFIG_SURFACE_3_BUTTON=m CONFIG_SURFACE_3_POWER_OPREGION=m CONFIG_SURFACE_ACPI_NOTIFY=m CONFIG_SURFACE_AGGREGATOR_CDEV=m +CONFIG_SURFACE_AGGREGATOR_REGISTRY=m +CONFIG_SURFACE_DTX=m CONFIG_SURFACE_GPE=m CONFIG_SURFACE_HOTPLUG=m +CONFIG_SURFACE_PLATFORM_PROFILE=m CONFIG_SURFACE_PRO3_BUTTON=m CONFIG_SURFACE_AGGREGATOR=m CONFIG_SURFACE_AGGREGATOR_BUS=y @@ -8505,7 +8565,6 @@ CONFIG_EXTCON=y # Extcon Device Drivers # CONFIG_EXTCON_ADC_JACK=m -CONFIG_EXTCON_ARIZONA=m CONFIG_EXTCON_AXP288=m CONFIG_EXTCON_FSA9480=m CONFIG_EXTCON_GPIO=m @@ -8556,6 +8615,8 @@ CONFIG_BMA400_SPI=m CONFIG_BMC150_ACCEL=m CONFIG_BMC150_ACCEL_I2C=m CONFIG_BMC150_ACCEL_SPI=m +CONFIG_BMI088_ACCEL=m +CONFIG_BMI088_ACCEL_SPI=m CONFIG_DA280=m CONFIG_DA311=m CONFIG_DMARD09=m @@ -8646,6 +8707,7 @@ CONFIG_TI_ADC128S052=m CONFIG_TI_ADC161S626=m CONFIG_TI_ADS1015=m CONFIG_TI_ADS7950=m +CONFIG_TI_ADS131E08=m CONFIG_TI_AM335X_ADC=m CONFIG_TI_TLC4541=m CONFIG_TWL4030_MADC=m @@ -8667,6 +8729,12 @@ CONFIG_HMC425=m # end of Amplifiers # +# Capacitance to digital converters +# +CONFIG_AD7150=m +# end of Capacitance to digital converters + +# # Chemical Sensors # CONFIG_ATLAS_PH_SENSOR=m @@ -8699,6 +8767,11 @@ CONFIG_HID_SENSOR_IIO_TRIGGER=m CONFIG_IIO_MS_SENSORS_I2C=m # +# IIO SCMI Sensors +# +# end of IIO SCMI Sensors + +# # SSP Sensor Common # CONFIG_IIO_SSP_SENSORS_COMMONS=m @@ -9023,6 +9096,7 @@ CONFIG_AS3935=m # # Proximity and distance sensors # +CONFIG_CROS_EC_MKBP_PROXIMITY=m CONFIG_ISL29501=m CONFIG_LIDAR_LITE_V2=m CONFIG_MB1232=m @@ -9097,7 +9171,6 @@ CONFIG_IPACK_BUS=m CONFIG_BOARD_TPCI200=m CONFIG_SERIAL_IPOCTAL=m CONFIG_RESET_CONTROLLER=y -CONFIG_RESET_BRCMSTB_RESCAL=y CONFIG_RESET_TI_SYSCON=m # @@ -9230,9 +9303,11 @@ CONFIG_SLIMBUS=m CONFIG_SLIM_QCOM_CTRL=m CONFIG_INTERCONNECT=y CONFIG_COUNTER=m +CONFIG_INTERRUPT_CNT=m CONFIG_MOST=m CONFIG_MOST_USB_HDM=m CONFIG_MOST_CDEV=m +CONFIG_MOST_SND=m # end of Device Drivers # @@ -9343,6 +9418,8 @@ CONFIG_OVERLAY_FS_METACOPY=y # # Caches # +CONFIG_NETFS_SUPPORT=m +CONFIG_NETFS_STATS=y CONFIG_FSCACHE=m CONFIG_FSCACHE_STATS=y # CONFIG_FSCACHE_HISTOGRAM is not set @@ -9482,11 +9559,6 @@ CONFIG_PSTORE_COMPRESS_DEFAULT="zstd" # CONFIG_PSTORE_PMSG is not set # CONFIG_PSTORE_FTRACE is not set CONFIG_PSTORE_RAM=m -CONFIG_PSTORE_ZONE=m -CONFIG_PSTORE_BLK=m -CONFIG_PSTORE_BLK_BLKDEV="" -CONFIG_PSTORE_BLK_KMSG_SIZE=64 -CONFIG_PSTORE_BLK_MAX_REASON=2 # CONFIG_SYSV_FS is not set CONFIG_UFS_FS=m # CONFIG_UFS_FS_WRITE is not set @@ -9497,7 +9569,6 @@ CONFIG_EROFS_FS_XATTR=y CONFIG_EROFS_FS_POSIX_ACL=y CONFIG_EROFS_FS_SECURITY=y CONFIG_EROFS_FS_ZIP=y -CONFIG_EROFS_FS_CLUSTER_PAGE_LIMIT=2 CONFIG_VBOXSF_FS=m CONFIG_NETWORK_FILESYSTEMS=y CONFIG_NFS_FS=m @@ -9536,7 +9607,7 @@ CONFIG_LOCKD=m CONFIG_LOCKD_V4=y CONFIG_NFS_ACL_SUPPORT=m CONFIG_NFS_COMMON=y -CONFIG_NFS_V4_2_SSC_HELPER=m +CONFIG_NFS_V4_2_SSC_HELPER=y CONFIG_SUNRPC=m CONFIG_SUNRPC_GSS=m CONFIG_SUNRPC_BACKCHANNEL=y @@ -9687,6 +9758,7 @@ CONFIG_SECURITY_LOCKDOWN_LSM=y CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY is not set # CONFIG_LOCK_DOWN_KERNEL_FORCE_CONFIDENTIALITY is not set +CONFIG_SECURITY_LANDLOCK=y # CONFIG_INTEGRITY is not set # CONFIG_IMA_SECURE_AND_OR_TRUSTED_BOOT is not set # CONFIG_DEFAULT_SECURITY_SELINUX is not set @@ -9694,7 +9766,7 @@ CONFIG_LOCK_DOWN_KERNEL_FORCE_NONE=y # CONFIG_DEFAULT_SECURITY_TOMOYO is not set # CONFIG_DEFAULT_SECURITY_APPARMOR is not set CONFIG_DEFAULT_SECURITY_DAC=y -CONFIG_LSM="lockdown,yama" +CONFIG_LSM="landlock,lockdown,yama,bpf" # # Kernel hardening options @@ -9764,6 +9836,7 @@ CONFIG_CRYPTO_RSA=y CONFIG_CRYPTO_DH=y CONFIG_CRYPTO_ECC=m CONFIG_CRYPTO_ECDH=m +CONFIG_CRYPTO_ECDSA=m CONFIG_CRYPTO_ECRDSA=m CONFIG_CRYPTO_SM2=m CONFIG_CRYPTO_CURVE25519=m @@ -10022,7 +10095,7 @@ CONFIG_ZLIB_DEFLATE=y CONFIG_LZO_COMPRESS=y CONFIG_LZO_DECOMPRESS=y CONFIG_LZ4_COMPRESS=y -CONFIG_LZ4HC_COMPRESS=y +CONFIG_LZ4HC_COMPRESS=m CONFIG_LZ4_DECOMPRESS=y CONFIG_ZSTD_COMPRESS=y CONFIG_ZSTD_DECOMPRESS=y @@ -10124,6 +10197,7 @@ CONFIG_OBJAGG=m # end of Library routines CONFIG_PLDMFW=y +CONFIG_ASN1_ENCODER=m # # Kernel hacking @@ -10154,6 +10228,8 @@ CONFIG_DEBUG_INFO=y # CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT is not set CONFIG_DEBUG_INFO_DWARF4=y CONFIG_DEBUG_INFO_BTF=y +CONFIG_PAHOLE_HAS_SPLIT_BTF=y +CONFIG_DEBUG_INFO_BTF_MODULES=y # CONFIG_GDB_SCRIPTS is not set CONFIG_FRAME_WARN=2048 CONFIG_STRIP_ASM_SYMS=y @@ -10435,6 +10511,7 @@ CONFIG_RUNTIME_TESTING_MENU=y # CONFIG_TEST_LIST_SORT is not set # CONFIG_TEST_MIN_HEAP is not set # CONFIG_TEST_SORT is not set +# CONFIG_TEST_DIV64 is not set # CONFIG_KPROBES_SANITY_TEST is not set # CONFIG_BACKTRACE_SELF_TEST is not set # CONFIG_RBTREE_TEST is not set @@ -10475,6 +10552,7 @@ CONFIG_ASYNC_RAID6_TEST=m # CONFIG_TEST_HMM is not set # CONFIG_TEST_FREE_PAGES is not set # CONFIG_TEST_FPU is not set +CONFIG_ARCH_USE_MEMTEST=y # CONFIG_MEMTEST is not set # CONFIG_HYPERV_TESTING is not set # end of Kernel Testing and Coverage |