diff --git a/blacklist.conf b/blacklist.conf index 2d74791..8e96dcb 100644 --- a/blacklist.conf +++ b/blacklist.conf @@ -827,3 +827,4 @@ dc306186a130c6d9feb0aabc1c71b8ed1674a3bf # does not fix an actual bug dc2ab23b992c9d5dab93b9bf01b10b10465e537e # does not fix an actual bug 9097fc793f74ef9c677f8c4aed0c24f6f07f0133 # s390 kABI breakage ed0192bc644f3553d64a5cb461bdd0b1fbae3fdf # does not fix an actual bug +03cab65a07e083b6c1010fbc8f9b817e9aca75d9 # clang builds diff --git a/patches.suse/futex-Resend-potentially-swallowed-owner-death-notif.patch b/patches.suse/futex-Resend-potentially-swallowed-owner-death-notif.patch new file mode 100644 index 0000000..81015bb --- /dev/null +++ b/patches.suse/futex-Resend-potentially-swallowed-owner-death-notif.patch @@ -0,0 +1,103 @@ +From 90d758896787048fa3d4209309d4800f3920e66f Mon Sep 17 00:00:00 2001 +From: Alexey Izbyshev +Date: Sat, 12 Nov 2022 00:54:39 +0300 +Subject: [PATCH] futex: Resend potentially swallowed owner death notification +Git-commit: 90d758896787048fa3d4209309d4800f3920e66f +Patch-mainline: v6.2-rc1 +References: git-fixes + +Commit ca16d5bee598 ("futex: Prevent robust futex exit race") addressed +two cases when tasks waiting on a robust non-PI futex remained blocked +despite the futex not being owned anymore: + +* if the owner died after writing zero to the futex word, but before + waking up a waiter + +* if a task waiting on the futex was woken up, but died before updating + the futex word (effectively swallowing the notification without acting + on it) + +In the second case, the task could be woken up either by the previous +owner (after the futex word was reset to zero) or by the kernel (after +the OWNER_DIED bit was set and the TID part of the futex word was reset +to zero) if the previous owner died without the resetting the futex. + +Because the referenced commit wakes up a potential waiter only if the +whole futex word is zero, the latter subcase remains unaddressed. + +Fix this by looking only at the TID part of the futex when deciding +whether a wake up is needed. + +Fixes: ca16d5bee598 ("futex: Prevent robust futex exit race") +Signed-off-by: Alexey Izbyshev +Signed-off-by: Thomas Gleixner +Acked-by: Peter Zijlstra (Intel) +Link: https://lore.kernel.org/r/20221111215439.248185-1-izbyshev@ispras.ru +Signed-off-by: Jiri Wiesner +--- + kernel/futex/core.c | 26 +++++++++++++++++--------- + 1 file changed, 17 insertions(+), 9 deletions(-) + +diff --git a/kernel/futex/core.c b/kernel/futex/core.c +index b22ef1efe751..514e4582b863 100644 +--- a/kernel/futex/core.c ++++ b/kernel/futex/core.c +@@ -638,6 +638,7 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, + bool pi, bool pending_op) + { + u32 uval, nval, mval; ++ pid_t owner; + int err; + + /* Futex address must be 32bit aligned */ +@@ -659,6 +660,10 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, + * 2. A woken up waiter is killed before it can acquire the + * futex in user space. + * ++ * In the second case, the wake up notification could be generated ++ * by the unlock path in user space after setting the futex value ++ * to zero or by the kernel after setting the OWNER_DIED bit below. ++ * + * In both cases the TID validation below prevents a wakeup of + * potential waiters which can cause these waiters to block + * forever. +@@ -667,24 +672,27 @@ static int handle_futex_death(u32 __user *uaddr, struct task_struct *curr, + * + * 1) task->robust_list->list_op_pending != NULL + * @pending_op == true +- * 2) User space futex value == 0 ++ * 2) The owner part of user space futex value == 0 + * 3) Regular futex: @pi == false + * + * If these conditions are met, it is safe to attempt waking up a + * potential waiter without touching the user space futex value and +- * trying to set the OWNER_DIED bit. The user space futex value is +- * uncontended and the rest of the user space mutex state is +- * consistent, so a woken waiter will just take over the +- * uncontended futex. Setting the OWNER_DIED bit would create +- * inconsistent state and malfunction of the user space owner died +- * handling. ++ * trying to set the OWNER_DIED bit. If the futex value is zero, ++ * the rest of the user space mutex state is consistent, so a woken ++ * waiter will just take over the uncontended futex. Setting the ++ * OWNER_DIED bit would create inconsistent state and malfunction ++ * of the user space owner died handling. Otherwise, the OWNER_DIED ++ * bit is already set, and the woken waiter is expected to deal with ++ * this. + */ +- if (pending_op && !pi && !uval) { ++ owner = uval & FUTEX_TID_MASK; ++ ++ if (pending_op && !pi && !owner) { + futex_wake(uaddr, 1, 1, FUTEX_BITSET_MATCH_ANY); + return 0; + } + +- if ((uval & FUTEX_TID_MASK) != task_pid_vnr(curr)) ++ if (owner != task_pid_vnr(curr)) + return 0; + + /* +-- +2.35.3 + diff --git a/patches.suse/locking-rwsem-Add-__always_inline-annotation-to-__do.patch b/patches.suse/locking-rwsem-Add-__always_inline-annotation-to-__do.patch new file mode 100644 index 0000000..c4aaebe --- /dev/null +++ b/patches.suse/locking-rwsem-Add-__always_inline-annotation-to-__do.patch @@ -0,0 +1,69 @@ +From 92cc5d00a431e96e5a49c0b97e5ad4fa7536bd4b Mon Sep 17 00:00:00 2001 +From: John Stultz +Date: Wed, 3 May 2023 02:33:51 +0000 +Subject: [PATCH] locking/rwsem: Add __always_inline annotation to + __down_read_common() and inlined callers +Git-commit: 92cc5d00a431e96e5a49c0b97e5ad4fa7536bd4b +Patch-mainline: v6.4-rc2 +References: git-fixes + +Apparently despite it being marked inline, the compiler +may not inline __down_read_common() which makes it difficult +to identify the cause of lock contention, as the blocked +function in traceevents will always be listed as +__down_read_common(). + +So this patch adds __always_inline annotation to the common +function (as well as the inlined helper callers) to force it to +be inlined so the blocking function will be listed (via Wchan) +in traceevents. + +Fixes: c995e638ccbb ("locking/rwsem: Fold __down_{read,write}*()") +Reported-by: Tim Murray +Signed-off-by: John Stultz +Signed-off-by: Peter Zijlstra (Intel) +Reviewed-by: Waiman Long +Cc: stable@vger.kernel.org +Link: https://lkml.kernel.org/r/20230503023351.2832796-1-jstultz@google.com +Signed-off-by: Jiri Wiesner +--- + kernel/locking/rwsem.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c +index acb5a50309a1..9eabd585ce7a 100644 +--- a/kernel/locking/rwsem.c ++++ b/kernel/locking/rwsem.c +@@ -1240,7 +1240,7 @@ static struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *sem) + /* + * lock for reading + */ +-static inline int __down_read_common(struct rw_semaphore *sem, int state) ++static __always_inline int __down_read_common(struct rw_semaphore *sem, int state) + { + int ret = 0; + long count; +@@ -1258,17 +1258,17 @@ static inline int __down_read_common(struct rw_semaphore *sem, int state) + return ret; + } + +-static inline void __down_read(struct rw_semaphore *sem) ++static __always_inline void __down_read(struct rw_semaphore *sem) + { + __down_read_common(sem, TASK_UNINTERRUPTIBLE); + } + +-static inline int __down_read_interruptible(struct rw_semaphore *sem) ++static __always_inline int __down_read_interruptible(struct rw_semaphore *sem) + { + return __down_read_common(sem, TASK_INTERRUPTIBLE); + } + +-static inline int __down_read_killable(struct rw_semaphore *sem) ++static __always_inline int __down_read_killable(struct rw_semaphore *sem) + { + return __down_read_common(sem, TASK_KILLABLE); + } +-- +2.35.3 + diff --git a/patches.suse/rtmutex-Ensure-that-the-top-waiter-is-always-woken-u.patch b/patches.suse/rtmutex-Ensure-that-the-top-waiter-is-always-woken-u.patch new file mode 100644 index 0000000..f8c9f0b --- /dev/null +++ b/patches.suse/rtmutex-Ensure-that-the-top-waiter-is-always-woken-u.patch @@ -0,0 +1,124 @@ +From db370a8b9f67ae5f17e3d5482493294467784504 Mon Sep 17 00:00:00 2001 +From: Wander Lairson Costa +Date: Thu, 2 Feb 2023 09:30:20 -0300 +Subject: [PATCH] rtmutex: Ensure that the top waiter is always woken up +Git-commit: db370a8b9f67ae5f17e3d5482493294467784504 +Patch-mainline: v6.2-rc8 +References: git-fixes + +Let L1 and L2 be two spinlocks. + +Let T1 be a task holding L1 and blocked on L2. T1, currently, is the top +waiter of L2. + +Let T2 be the task holding L2. + +Let T3 be a task trying to acquire L1. + +The following events will lead to a state in which the wait queue of L2 +isn't empty, but no task actually holds the lock. + +T1 T2 T3 +== == == + + spin_lock(L1) + | raw_spin_lock(L1->wait_lock) + | rtlock_slowlock_locked(L1) + | | task_blocks_on_rt_mutex(L1, T3) + | | | orig_waiter->lock = L1 + | | | orig_waiter->task = T3 + | | | raw_spin_unlock(L1->wait_lock) + | | | rt_mutex_adjust_prio_chain(T1, L1, L2, orig_waiter, T3) + spin_unlock(L2) | | | | + | rt_mutex_slowunlock(L2) | | | | + | | raw_spin_lock(L2->wait_lock) | | | | + | | wakeup(T1) | | | | + | | raw_spin_unlock(L2->wait_lock) | | | | + | | | | waiter = T1->pi_blocked_on + | | | | waiter == rt_mutex_top_waiter(L2) + | | | | waiter->task == T1 + | | | | raw_spin_lock(L2->wait_lock) + | | | | dequeue(L2, waiter) + | | | | update_prio(waiter, T1) + | | | | enqueue(L2, waiter) + | | | | waiter != rt_mutex_top_waiter(L2) + | | | | L2->owner == NULL + | | | | wakeup(T1) + | | | | raw_spin_unlock(L2->wait_lock) +T1 wakes up +T1 != top_waiter(L2) +schedule_rtlock() + +If the deadline of T1 is updated before the call to update_prio(), and the +new deadline is greater than the deadline of the second top waiter, then +after the requeue, T1 is no longer the top waiter, and the wrong task is +woken up which will then go back to sleep because it is not the top waiter. + +This can be reproduced in PREEMPT_RT with stress-ng: + +while true; do + stress-ng --sched deadline --sched-period 1000000000 \ + --sched-runtime 800000000 --sched-deadline \ + 1000000000 --mmapfork 23 -t 20 +done + +A similar issue was pointed out by Thomas versus the cases where the top +waiter drops out early due to a signal or timeout, which is a general issue +for all regular rtmutex use cases, e.g. futex. + +The problematic code is in rt_mutex_adjust_prio_chain(): + + // Save the top waiter before dequeue/enqueue + prerequeue_top_waiter = rt_mutex_top_waiter(lock); + + rt_mutex_dequeue(lock, waiter); + waiter_update_prio(waiter, task); + rt_mutex_enqueue(lock, waiter); + + // Lock has no owner? + if (!rt_mutex_owner(lock)) { + // Top waiter changed + ----> if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) + ----> wake_up_state(waiter->task, waiter->wake_state); + +This only takes the case into account where @waiter is the new top waiter +due to the requeue operation. + +But it fails to handle the case where @waiter is not longer the top +waiter due to the requeue operation. + +Ensure that the new top waiter is woken up so in all cases so it can take +over the ownerless lock. + +[ tglx: Amend changelog, add Fixes tag ] + +Fixes: c014ef69b3ac ("locking/rtmutex: Add wake_state to rt_mutex_waiter") +Signed-off-by: Wander Lairson Costa +Signed-off-by: Thomas Gleixner +Cc: stable@vger.kernel.org +Link: https://lore.kernel.org/r/20230117172649.52465-1-wander@redhat.com +Link: https://lore.kernel.org/r/20230202123020.14844-1-wander@redhat.com +Signed-off-by: Jiri Wiesner +--- + kernel/locking/rtmutex.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/locking/rtmutex.c b/kernel/locking/rtmutex.c +index 010cf4e6d0b8..728f434de2bb 100644 +--- a/kernel/locking/rtmutex.c ++++ b/kernel/locking/rtmutex.c +@@ -901,8 +901,9 @@ static int __sched rt_mutex_adjust_prio_chain(struct task_struct *task, + * then we need to wake the new top waiter up to try + * to get the lock. + */ +- if (prerequeue_top_waiter != rt_mutex_top_waiter(lock)) +- wake_up_state(waiter->task, waiter->wake_state); ++ top_waiter = rt_mutex_top_waiter(lock); ++ if (prerequeue_top_waiter != top_waiter) ++ wake_up_state(top_waiter->task, top_waiter->wake_state); + raw_spin_unlock_irq(&lock->wait_lock); + return 0; + } +-- +2.35.3 + diff --git a/series.conf b/series.conf index b163b96..d1ef8fa 100644 --- a/series.conf +++ b/series.conf @@ -17664,6 +17664,7 @@ patches.suse/thermal-core-fix-some-possible-name-leaks-in-error-p.patch patches.suse/0001-EDAC-mc_sysfs-Increase-legacy-channel-support-to-12.patch patches.suse/x86-MCE-AMD-Clear-DFR-errors-found-in-THR-handler.patch + patches.suse/futex-Resend-potentially-swallowed-owner-death-notif.patch patches.suse/perf-Fix-possible-memleak-in-pmu_dev_alloc.patch patches.suse/perf-x86-intel-uncore-Generalize-IIO-topology-support.patch patches.suse/perf-x86-intel-uncore-Introduce-UPI-topology-type.patch @@ -18785,6 +18786,7 @@ patches.suse/pinctrl-intel-Restore-the-pins-that-used-to-be-in-Di.patch patches.suse/clk-ingenic-jz4760-Update-M-N-OD-calculation-algorit.patch patches.suse/ACPI-NFIT-fix-a-potential-deadlock-during-NFIT-teard.patch + patches.suse/rtmutex-Ensure-that-the-top-waiter-is-always-woken-u.patch patches.suse/spi-dw-Fix-wrong-FIFO-level-setting-for-long-xfers.patch patches.suse/Fix-page-corruption-caused-by-racy-check-in-__free_pages.patch patches.suse/powerpc-kexec_file-fix-implicit-decl-error.patch @@ -20107,6 +20109,7 @@ patches.suse/drm-amdgpu-disable-sdma-ecc-irq-only-when-sdma-RAS-i.patch patches.suse/drm-amdgpu-gfx-disable-gfx9-cp_ecc_error_irq-only-wh.patch patches.suse/fbdev-arcfb-Fix-error-handling-in-arcfb_probe.patch + patches.suse/locking-rwsem-Add-__always_inline-annotation-to-__do.patch patches.suse/ARM-9296-1-HP-Jornada-7XX-fix-kernel-doc-warnings.patch patches.suse/tpm-tpm_tis-Disable-interrupts-for-more-Lenovo-devic.patch patches.suse/selftests-sgx-Add-test_encl.elf-to-TEST_FILES.patch