From: Greg Kroah-Hartman Date: Thu, 11 Feb 2021 14:21:56 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v4.19.176~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=492d68f5c01d0d05f0434a00dd02815c8ec22bde;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: futex-change-locking-rules.patch futex-cure-exit-race.patch futex-ensure-the-correct-return-value-from-futex_lock_pi.patch --- diff --git a/queue-4.9/futex-change-locking-rules.patch b/queue-4.9/futex-change-locking-rules.patch new file mode 100644 index 00000000000..3619bf21dd3 --- /dev/null +++ b/queue-4.9/futex-change-locking-rules.patch @@ -0,0 +1,320 @@ +From foo@baz Thu Feb 11 03:21:16 PM CET 2021 +From: Lee Jones +Date: Thu, 11 Feb 2021 09:26:59 +0000 +Subject: futex: Change locking rules +To: stable@vger.kernel.org +Cc: zhengyejian@foxmail.com, Peter Zijlstra , juri.lelli@arm.com, bigeasy@linutronix.de, xlpang@redhat.com, rostedt@goodmis.org, mathieu.desnoyers@efficios.com, jdesfossez@efficios.com, dvhart@infradead.org, bristot@redhat.com, Thomas Gleixner , Lee Jones +Message-ID: <20210211092700.11772-3-lee.jones@linaro.org> + +From: Peter Zijlstra + +Currently futex-pi relies on hb->lock to serialize everything. But hb->lock +creates another set of problems, especially priority inversions on RT where +hb->lock becomes a rt_mutex itself. + +The rt_mutex::wait_lock is the most obvious protection for keeping the +futex user space value and the kernel internal pi_state in sync. + +Rework and document the locking so rt_mutex::wait_lock is held accross all +operations which modify the user space value and the pi state. + +This allows to invoke rt_mutex_unlock() (including deboost) without holding +hb->lock as a next step. + +Nothing yet relies on the new locking rules. + +Signed-off-by: Peter Zijlstra (Intel) +Cc: juri.lelli@arm.com +Cc: bigeasy@linutronix.de +Cc: xlpang@redhat.com +Cc: rostedt@goodmis.org +Cc: mathieu.desnoyers@efficios.com +Cc: jdesfossez@efficios.com +Cc: dvhart@infradead.org +Cc: bristot@redhat.com +Link: http://lkml.kernel.org/r/20170322104151.751993333@infradead.org +Signed-off-by: Thomas Gleixner +[Lee: Back-ported in support of a previous futex back-port attempt] +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 112 insertions(+), 26 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1019,6 +1019,39 @@ static void exit_pi_state_list(struct ta + * [10] There is no transient state which leaves owner and user space + * TID out of sync. Except one error case where the kernel is denied + * write access to the user address, see fixup_pi_state_owner(). ++ * ++ * ++ * Serialization and lifetime rules: ++ * ++ * hb->lock: ++ * ++ * hb -> futex_q, relation ++ * futex_q -> pi_state, relation ++ * ++ * (cannot be raw because hb can contain arbitrary amount ++ * of futex_q's) ++ * ++ * pi_mutex->wait_lock: ++ * ++ * {uval, pi_state} ++ * ++ * (and pi_mutex 'obviously') ++ * ++ * p->pi_lock: ++ * ++ * p->pi_state_list -> pi_state->list, relation ++ * ++ * pi_state->refcount: ++ * ++ * pi_state lifetime ++ * ++ * ++ * Lock order: ++ * ++ * hb->lock ++ * pi_mutex->wait_lock ++ * p->pi_lock ++ * + */ + + /* +@@ -1026,10 +1059,12 @@ static void exit_pi_state_list(struct ta + * the pi_state against the user space value. If correct, attach to + * it. + */ +-static int attach_to_pi_state(u32 uval, struct futex_pi_state *pi_state, ++static int attach_to_pi_state(u32 __user *uaddr, u32 uval, ++ struct futex_pi_state *pi_state, + struct futex_pi_state **ps) + { + pid_t pid = uval & FUTEX_TID_MASK; ++ int ret, uval2; + + /* + * Userspace might have messed up non-PI and PI futexes [3] +@@ -1037,9 +1072,34 @@ static int attach_to_pi_state(u32 uval, + if (unlikely(!pi_state)) + return -EINVAL; + ++ /* ++ * We get here with hb->lock held, and having found a ++ * futex_top_waiter(). This means that futex_lock_pi() of said futex_q ++ * has dropped the hb->lock in between queue_me() and unqueue_me_pi(), ++ * which in turn means that futex_lock_pi() still has a reference on ++ * our pi_state. ++ */ + WARN_ON(!atomic_read(&pi_state->refcount)); + + /* ++ * Now that we have a pi_state, we can acquire wait_lock ++ * and do the state validation. ++ */ ++ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); ++ ++ /* ++ * Since {uval, pi_state} is serialized by wait_lock, and our current ++ * uval was read without holding it, it can have changed. Verify it ++ * still is what we expect it to be, otherwise retry the entire ++ * operation. ++ */ ++ if (get_futex_value_locked(&uval2, uaddr)) ++ goto out_efault; ++ ++ if (uval != uval2) ++ goto out_eagain; ++ ++ /* + * Handle the owner died case: + */ + if (uval & FUTEX_OWNER_DIED) { +@@ -1054,11 +1114,11 @@ static int attach_to_pi_state(u32 uval, + * is not 0. Inconsistent state. [5] + */ + if (pid) +- return -EINVAL; ++ goto out_einval; + /* + * Take a ref on the state and return success. [4] + */ +- goto out_state; ++ goto out_attach; + } + + /* +@@ -1070,14 +1130,14 @@ static int attach_to_pi_state(u32 uval, + * Take a ref on the state and return success. [6] + */ + if (!pid) +- goto out_state; ++ goto out_attach; + } else { + /* + * If the owner died bit is not set, then the pi_state + * must have an owner. [7] + */ + if (!pi_state->owner) +- return -EINVAL; ++ goto out_einval; + } + + /* +@@ -1086,11 +1146,29 @@ static int attach_to_pi_state(u32 uval, + * user space TID. [9/10] + */ + if (pid != task_pid_vnr(pi_state->owner)) +- return -EINVAL; +-out_state: ++ goto out_einval; ++ ++out_attach: + atomic_inc(&pi_state->refcount); ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + *ps = pi_state; + return 0; ++ ++out_einval: ++ ret = -EINVAL; ++ goto out_error; ++ ++out_eagain: ++ ret = -EAGAIN; ++ goto out_error; ++ ++out_efault: ++ ret = -EFAULT; ++ goto out_error; ++ ++out_error: ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); ++ return ret; + } + + /** +@@ -1183,6 +1261,9 @@ static int attach_to_pi_owner(u32 uval, + + /* + * No existing pi state. First waiter. [2] ++ * ++ * This creates pi_state, we have hb->lock held, this means nothing can ++ * observe this state, wait_lock is irrelevant. + */ + pi_state = alloc_pi_state(); + +@@ -1207,7 +1288,8 @@ static int attach_to_pi_owner(u32 uval, + return 0; + } + +-static int lookup_pi_state(u32 uval, struct futex_hash_bucket *hb, ++static int lookup_pi_state(u32 __user *uaddr, u32 uval, ++ struct futex_hash_bucket *hb, + union futex_key *key, struct futex_pi_state **ps, + struct task_struct **exiting) + { +@@ -1218,7 +1300,7 @@ static int lookup_pi_state(u32 uval, str + * attach to the pi_state when the validation succeeds. + */ + if (match) +- return attach_to_pi_state(uval, match->pi_state, ps); ++ return attach_to_pi_state(uaddr, uval, match->pi_state, ps); + + /* + * We are the first waiter - try to look up the owner based on +@@ -1237,7 +1319,7 @@ static int lock_pi_update_atomic(u32 __u + if (unlikely(cmpxchg_futex_value_locked(&curval, uaddr, uval, newval))) + return -EFAULT; + +- /*If user space value changed, let the caller retry */ ++ /* If user space value changed, let the caller retry */ + return curval != uval ? -EAGAIN : 0; + } + +@@ -1301,7 +1383,7 @@ static int futex_lock_pi_atomic(u32 __us + */ + match = futex_top_waiter(hb, key); + if (match) +- return attach_to_pi_state(uval, match->pi_state, ps); ++ return attach_to_pi_state(uaddr, uval, match->pi_state, ps); + + /* + * No waiter and user TID is 0. We are here because the +@@ -1441,6 +1523,7 @@ static int wake_futex_pi(u32 __user *uad + + if (cmpxchg_futex_value_locked(&curval, uaddr, uval, newval)) { + ret = -EFAULT; ++ + } else if (curval != uval) { + /* + * If a unconditional UNLOCK_PI operation (user space did not +@@ -1977,7 +2060,7 @@ retry_private: + * If that call succeeds then we have pi_state and an + * initial refcount on it. + */ +- ret = lookup_pi_state(ret, hb2, &key2, ++ ret = lookup_pi_state(uaddr2, ret, hb2, &key2, + &pi_state, &exiting); + } + +@@ -2282,7 +2365,6 @@ static int __fixup_pi_state_owner(u32 __ + int err = 0; + + oldowner = pi_state->owner; +- + /* Owner died? */ + if (!pi_state->owner) + newtid |= FUTEX_OWNER_DIED; +@@ -2305,11 +2387,10 @@ static int __fixup_pi_state_owner(u32 __ + * because we can fault here. Imagine swapped out pages or a fork + * that marked all the anonymous memory readonly for cow. + * +- * Modifying pi_state _before_ the user space value would +- * leave the pi_state in an inconsistent state when we fault +- * here, because we need to drop the hash bucket lock to +- * handle the fault. This might be observed in the PID check +- * in lookup_pi_state. ++ * Modifying pi_state _before_ the user space value would leave the ++ * pi_state in an inconsistent state when we fault here, because we ++ * need to drop the locks to handle the fault. This might be observed ++ * in the PID check in lookup_pi_state. + */ + retry: + if (!argowner) { +@@ -2367,21 +2448,26 @@ retry: + return argowner == current; + + /* +- * To handle the page fault we need to drop the hash bucket +- * lock here. That gives the other task (either the highest priority +- * waiter itself or the task which stole the rtmutex) the +- * chance to try the fixup of the pi_state. So once we are +- * back from handling the fault we need to check the pi_state +- * after reacquiring the hash bucket lock and before trying to +- * do another fixup. When the fixup has been done already we +- * simply return. ++ * To handle the page fault we need to drop the locks here. That gives ++ * the other task (either the highest priority waiter itself or the ++ * task which stole the rtmutex) the chance to try the fixup of the ++ * pi_state. So once we are back from handling the fault we need to ++ * check the pi_state after reacquiring the locks and before trying to ++ * do another fixup. When the fixup has been done already we simply ++ * return. ++ * ++ * Note: we hold both hb->lock and pi_mutex->wait_lock. We can safely ++ * drop hb->lock since the caller owns the hb -> futex_q relation. ++ * Dropping the pi_mutex->wait_lock requires the state revalidate. + */ + handle_fault: ++ raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock); + spin_unlock(q->lock_ptr); + + err = fault_in_user_writeable(uaddr); + + spin_lock(q->lock_ptr); ++ raw_spin_lock_irq(&pi_state->pi_mutex.wait_lock); + + /* + * Check if someone else fixed it for us: diff --git a/queue-4.9/futex-cure-exit-race.patch b/queue-4.9/futex-cure-exit-race.patch new file mode 100644 index 00000000000..a41a0b1e4ba --- /dev/null +++ b/queue-4.9/futex-cure-exit-race.patch @@ -0,0 +1,187 @@ +From foo@baz Thu Feb 11 03:21:16 PM CET 2021 +From: Lee Jones +Date: Thu, 11 Feb 2021 09:27:00 +0000 +Subject: futex: Cure exit race +To: stable@vger.kernel.org +Cc: zhengyejian@foxmail.com, Thomas Gleixner , Stefan Liebler , Peter Zijlstra , Heiko Carstens , Darren Hart , Ingo Molnar , Sasha Levin , Sudip Mukherjee , Greg Kroah-Hartman , Lee Jones +Message-ID: <20210211092700.11772-4-lee.jones@linaro.org> + +From: Thomas Gleixner + +commit da791a667536bf8322042e38ca85d55a78d3c273 upstream. + +Stefan reported, that the glibc tst-robustpi4 test case fails +occasionally. That case creates the following race between +sys_exit() and sys_futex_lock_pi(): + + CPU0 CPU1 + + sys_exit() sys_futex() + do_exit() futex_lock_pi() + exit_signals(tsk) No waiters: + tsk->flags |= PF_EXITING; *uaddr == 0x00000PID + mm_release(tsk) Set waiter bit + exit_robust_list(tsk) { *uaddr = 0x80000PID; + Set owner died attach_to_pi_owner() { + *uaddr = 0xC0000000; tsk = get_task(PID); + } if (!tsk->flags & PF_EXITING) { + ... attach(); + tsk->flags |= PF_EXITPIDONE; } else { + if (!(tsk->flags & PF_EXITPIDONE)) + return -EAGAIN; + return -ESRCH; <--- FAIL + } + +ESRCH is returned all the way to user space, which triggers the glibc test +case assert. Returning ESRCH unconditionally is wrong here because the user +space value has been changed by the exiting task to 0xC0000000, i.e. the +FUTEX_OWNER_DIED bit is set and the futex PID value has been cleared. This +is a valid state and the kernel has to handle it, i.e. taking the futex. + +Cure it by rereading the user space value when PF_EXITING and PF_EXITPIDONE +is set in the task which 'owns' the futex. If the value has changed, let +the kernel retry the operation, which includes all regular sanity checks +and correctly handles the FUTEX_OWNER_DIED case. + +If it hasn't changed, then return ESRCH as there is no way to distinguish +this case from malfunctioning user space. This happens when the exiting +task did not have a robust list, the robust list was corrupted or the user +space value in the futex was simply bogus. + +Reported-by: Stefan Liebler +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra +Cc: Heiko Carstens +Cc: Darren Hart +Cc: Ingo Molnar +Cc: Sasha Levin +Cc: stable@vger.kernel.org +Link: https://bugzilla.kernel.org/show_bug.cgi?id=200467 +Link: https://lkml.kernel.org/r/20181210152311.986181245@linutronix.de +Signed-off-by: Sudip Mukherjee +Signed-off-by: Greg Kroah-Hartman +[Lee: Required to satisfy functional dependency from futex back-port. + Re-add the missing handle_exit_race() parts from: + 3d4775df0a89 ("futex: Replace PF_EXITPIDONE with a state")] +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 65 insertions(+), 6 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -1201,11 +1201,67 @@ static void wait_for_owner_exiting(int r + put_task_struct(exiting); + } + ++static int handle_exit_race(u32 __user *uaddr, u32 uval, ++ struct task_struct *tsk) ++{ ++ u32 uval2; ++ ++ /* ++ * If the futex exit state is not yet FUTEX_STATE_DEAD, wait ++ * for it to finish. ++ */ ++ if (tsk && tsk->futex_state != FUTEX_STATE_DEAD) ++ return -EAGAIN; ++ ++ /* ++ * Reread the user space value to handle the following situation: ++ * ++ * CPU0 CPU1 ++ * ++ * sys_exit() sys_futex() ++ * do_exit() futex_lock_pi() ++ * futex_lock_pi_atomic() ++ * exit_signals(tsk) No waiters: ++ * tsk->flags |= PF_EXITING; *uaddr == 0x00000PID ++ * mm_release(tsk) Set waiter bit ++ * exit_robust_list(tsk) { *uaddr = 0x80000PID; ++ * Set owner died attach_to_pi_owner() { ++ * *uaddr = 0xC0000000; tsk = get_task(PID); ++ * } if (!tsk->flags & PF_EXITING) { ++ * ... attach(); ++ * tsk->futex_state = } else { ++ * FUTEX_STATE_DEAD; if (tsk->futex_state != ++ * FUTEX_STATE_DEAD) ++ * return -EAGAIN; ++ * return -ESRCH; <--- FAIL ++ * } ++ * ++ * Returning ESRCH unconditionally is wrong here because the ++ * user space value has been changed by the exiting task. ++ * ++ * The same logic applies to the case where the exiting task is ++ * already gone. ++ */ ++ if (get_futex_value_locked(&uval2, uaddr)) ++ return -EFAULT; ++ ++ /* If the user space value has changed, try again. */ ++ if (uval2 != uval) ++ return -EAGAIN; ++ ++ /* ++ * The exiting task did not have a robust list, the robust list was ++ * corrupted or the user space value in *uaddr is simply bogus. ++ * Give up and tell user space. ++ */ ++ return -ESRCH; ++} ++ + /* + * Lookup the task for the TID provided from user space and attach to + * it after doing proper sanity checks. + */ +-static int attach_to_pi_owner(u32 uval, union futex_key *key, ++static int attach_to_pi_owner(u32 __user *uaddr, u32 uval, union futex_key *key, + struct futex_pi_state **ps, + struct task_struct **exiting) + { +@@ -1216,12 +1272,15 @@ static int attach_to_pi_owner(u32 uval, + /* + * We are the first waiter - try to look up the real owner and attach + * the new pi_state to it, but bail out when TID = 0 [1] ++ * ++ * The !pid check is paranoid. None of the call sites should end up ++ * with pid == 0, but better safe than sorry. Let the caller retry + */ + if (!pid) +- return -ESRCH; ++ return -EAGAIN; + p = futex_find_get_task(pid); + if (!p) +- return -ESRCH; ++ return handle_exit_race(uaddr, uval, NULL); + + if (unlikely(p->flags & PF_KTHREAD)) { + put_task_struct(p); +@@ -1240,7 +1299,7 @@ static int attach_to_pi_owner(u32 uval, + * FUTEX_STATE_DEAD, we know that the task has finished + * the cleanup: + */ +- int ret = (p->futex_state = FUTEX_STATE_DEAD) ? -ESRCH : -EAGAIN; ++ int ret = handle_exit_race(uaddr, uval, p); + + raw_spin_unlock_irq(&p->pi_lock); + /* +@@ -1306,7 +1365,7 @@ static int lookup_pi_state(u32 __user *u + * We are the first waiter - try to look up the owner based on + * @uval and attach to it. + */ +- return attach_to_pi_owner(uval, key, ps, exiting); ++ return attach_to_pi_owner(uaddr, uval, key, ps, exiting); + } + + static int lock_pi_update_atomic(u32 __user *uaddr, u32 uval, u32 newval) +@@ -1422,7 +1481,7 @@ static int futex_lock_pi_atomic(u32 __us + * attach to the owner. If that fails, no harm done, we only + * set the FUTEX_WAITERS bit in the user space variable. + */ +- return attach_to_pi_owner(uval, key, ps, exiting); ++ return attach_to_pi_owner(uaddr, newval, key, ps, exiting); + } + + /** diff --git a/queue-4.9/futex-ensure-the-correct-return-value-from-futex_lock_pi.patch b/queue-4.9/futex-ensure-the-correct-return-value-from-futex_lock_pi.patch new file mode 100644 index 00000000000..867439f5e59 --- /dev/null +++ b/queue-4.9/futex-ensure-the-correct-return-value-from-futex_lock_pi.patch @@ -0,0 +1,112 @@ +From foo@baz Thu Feb 11 03:21:16 PM CET 2021 +From: Lee Jones +Date: Thu, 11 Feb 2021 09:26:58 +0000 +Subject: futex: Ensure the correct return value from futex_lock_pi() +To: stable@vger.kernel.org +Cc: zhengyejian@foxmail.com, Thomas Gleixner , Peter Zijlstra , Greg Kroah-Hartman , Lee Jones +Message-ID: <20210211092700.11772-2-lee.jones@linaro.org> + +From: Thomas Gleixner + +commit 12bb3f7f1b03d5913b3f9d4236a488aa7774dfe9 upstream + +In case that futex_lock_pi() was aborted by a signal or a timeout and the +task returned without acquiring the rtmutex, but is the designated owner of +the futex due to a concurrent futex_unlock_pi() fixup_owner() is invoked to +establish consistent state. In that case it invokes fixup_pi_state_owner() +which in turn tries to acquire the rtmutex again. If that succeeds then it +does not propagate this success to fixup_owner() and futex_lock_pi() +returns -EINTR or -ETIMEOUT despite having the futex locked. + +Return success from fixup_pi_state_owner() in all cases where the current +task owns the rtmutex and therefore the futex and propagate it correctly +through fixup_owner(). Fixup the other callsite which does not expect a +positive return value. + +Fixes: c1e2f0eaf015 ("futex: Avoid violating the 10th rule of futex") +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Cc: stable@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +[Lee: Back-ported in support of a previous futex attempt] +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + kernel/futex.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/kernel/futex.c ++++ b/kernel/futex.c +@@ -2322,7 +2322,7 @@ retry: + } + + if (__rt_mutex_futex_trylock(&pi_state->pi_mutex)) { +- /* We got the lock after all, nothing to fix. */ ++ /* We got the lock. pi_state is correct. Tell caller. */ + return 1; + } + +@@ -2364,7 +2364,7 @@ retry: + */ + pi_state_update_owner(pi_state, newowner); + +- return 0; ++ return argowner == current; + + /* + * To handle the page fault we need to drop the hash bucket +@@ -2447,8 +2447,6 @@ static long futex_wait_restart(struct re + */ + static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked) + { +- int ret = 0; +- + if (locked) { + /* + * Got the lock. We might not be the anticipated owner if we +@@ -2459,8 +2457,8 @@ static int fixup_owner(u32 __user *uaddr + * stable state, anything else needs more attention. + */ + if (q->pi_state->owner != current) +- ret = fixup_pi_state_owner(uaddr, q, current); +- goto out; ++ return fixup_pi_state_owner(uaddr, q, current); ++ return 1; + } + + /* +@@ -2471,10 +2469,8 @@ static int fixup_owner(u32 __user *uaddr + * Another speculative read; pi_state->owner == current is unstable + * but needs our attention. + */ +- if (q->pi_state->owner == current) { +- ret = fixup_pi_state_owner(uaddr, q, NULL); +- goto out; +- } ++ if (q->pi_state->owner == current) ++ return fixup_pi_state_owner(uaddr, q, NULL); + + /* + * Paranoia check. If we did not take the lock, then we should not be +@@ -2483,8 +2479,7 @@ static int fixup_owner(u32 __user *uaddr + if (WARN_ON_ONCE(rt_mutex_owner(&q->pi_state->pi_mutex) == current)) + return fixup_pi_state_owner(uaddr, q, current); + +-out: +- return ret ? ret : locked; ++ return 0; + } + + /** +@@ -3106,6 +3101,11 @@ static int futex_wait_requeue_pi(u32 __u + */ + put_pi_state(q.pi_state); + spin_unlock(q.lock_ptr); ++ /* ++ * Adjust the return value. It's either -EFAULT or ++ * success (1) but the caller expects 0 for success. ++ */ ++ ret = ret < 0 ? ret : 0; + } + } else { + struct rt_mutex *pi_mutex; diff --git a/queue-4.9/series b/queue-4.9/series index 602e324f09a..f8872ad21d8 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -10,3 +10,6 @@ sunrpc-handle-0-length-opaque-xdr-object-data-proper.patch lib-string-add-strscpy_pad-function.patch include-trace-events-writeback.h-fix-wstringop-trunc.patch memcg-fix-a-crash-in-wb_workfn-when-a-device-disappe.patch +futex-ensure-the-correct-return-value-from-futex_lock_pi.patch +futex-change-locking-rules.patch +futex-cure-exit-race.patch