From: Sasha Levin Date: Mon, 24 May 2021 00:40:13 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v4.4.270~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=b62ac42b6ae2160e12e2334a2c80ab7797868e7a;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/locking-mutex-clear-mutex_flags-if-wait_list-is-empt.patch b/queue-4.19/locking-mutex-clear-mutex_flags-if-wait_list-is-empt.patch new file mode 100644 index 00000000000..617ed369bf8 --- /dev/null +++ b/queue-4.19/locking-mutex-clear-mutex_flags-if-wait_list-is-empt.patch @@ -0,0 +1,136 @@ +From 8ec34f007b392032744ea14e9f6f68579c3601bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 17 May 2021 11:40:05 +0800 +Subject: locking/mutex: clear MUTEX_FLAGS if wait_list is empty due to signal + +From: Zqiang + +[ Upstream commit 3a010c493271f04578b133de977e0e5dd2848cea ] + +When a interruptible mutex locker is interrupted by a signal +without acquiring this lock and removed from the wait queue. +if the mutex isn't contended enough to have a waiter +put into the wait queue again, the setting of the WAITER +bit will force mutex locker to go into the slowpath to +acquire the lock every time, so if the wait queue is empty, +the WAITER bit need to be clear. + +Fixes: 040a0a371005 ("mutex: Add support for wound/wait style locks") +Suggested-by: Peter Zijlstra +Signed-off-by: Zqiang +Signed-off-by: Peter Zijlstra (Intel) +Link: https://lkml.kernel.org/r/20210517034005.30828-1-qiang.zhang@windriver.com +Signed-off-by: Sasha Levin +--- + kernel/locking/mutex-debug.c | 4 ++-- + kernel/locking/mutex-debug.h | 2 +- + kernel/locking/mutex.c | 18 +++++++++++++----- + kernel/locking/mutex.h | 4 +--- + 4 files changed, 17 insertions(+), 11 deletions(-) + +diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c +index 9aa713629387..839df4383799 100644 +--- a/kernel/locking/mutex-debug.c ++++ b/kernel/locking/mutex-debug.c +@@ -57,7 +57,7 @@ void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, + task->blocked_on = waiter; + } + +-void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, ++void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, + struct task_struct *task) + { + DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list)); +@@ -65,7 +65,7 @@ void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, + DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter); + task->blocked_on = NULL; + +- list_del_init(&waiter->list); ++ INIT_LIST_HEAD(&waiter->list); + waiter->task = NULL; + } + +diff --git a/kernel/locking/mutex-debug.h b/kernel/locking/mutex-debug.h +index 1edd3f45a4ec..53e631e1d76d 100644 +--- a/kernel/locking/mutex-debug.h ++++ b/kernel/locking/mutex-debug.h +@@ -22,7 +22,7 @@ extern void debug_mutex_free_waiter(struct mutex_waiter *waiter); + extern void debug_mutex_add_waiter(struct mutex *lock, + struct mutex_waiter *waiter, + struct task_struct *task); +-extern void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, ++extern void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, + struct task_struct *task); + extern void debug_mutex_unlock(struct mutex *lock); + extern void debug_mutex_init(struct mutex *lock, const char *name, +diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c +index b3da782cdfbd..354151fef06a 100644 +--- a/kernel/locking/mutex.c ++++ b/kernel/locking/mutex.c +@@ -177,7 +177,7 @@ static inline bool __mutex_waiter_is_first(struct mutex *lock, struct mutex_wait + * Add @waiter to a given location in the lock wait_list and set the + * FLAG_WAITERS flag if it's the first waiter. + */ +-static void __sched ++static void + __mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, + struct list_head *list) + { +@@ -188,6 +188,16 @@ __mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, + __mutex_set_flag(lock, MUTEX_FLAG_WAITERS); + } + ++static void ++__mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter) ++{ ++ list_del(&waiter->list); ++ if (likely(list_empty(&lock->wait_list))) ++ __mutex_clear_flag(lock, MUTEX_FLAGS); ++ ++ debug_mutex_remove_waiter(lock, waiter, current); ++} ++ + /* + * Give up ownership to a specific task, when @task = NULL, this is equivalent + * to a regular unlock. Sets PICKUP on a handoff, clears HANDOF, preserves +@@ -1040,9 +1050,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + __ww_mutex_check_waiters(lock, ww_ctx); + } + +- mutex_remove_waiter(lock, &waiter, current); +- if (likely(list_empty(&lock->wait_list))) +- __mutex_clear_flag(lock, MUTEX_FLAGS); ++ __mutex_remove_waiter(lock, &waiter); + + debug_mutex_free_waiter(&waiter); + +@@ -1059,7 +1067,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass, + + err: + __set_current_state(TASK_RUNNING); +- mutex_remove_waiter(lock, &waiter, current); ++ __mutex_remove_waiter(lock, &waiter); + err_early_kill: + spin_unlock(&lock->wait_lock); + debug_mutex_free_waiter(&waiter); +diff --git a/kernel/locking/mutex.h b/kernel/locking/mutex.h +index 1c2287d3fa71..f0c710b1d192 100644 +--- a/kernel/locking/mutex.h ++++ b/kernel/locking/mutex.h +@@ -10,12 +10,10 @@ + * !CONFIG_DEBUG_MUTEXES case. Most of them are NOPs: + */ + +-#define mutex_remove_waiter(lock, waiter, task) \ +- __list_del((waiter)->list.prev, (waiter)->list.next) +- + #define debug_mutex_wake_waiter(lock, waiter) do { } while (0) + #define debug_mutex_free_waiter(waiter) do { } while (0) + #define debug_mutex_add_waiter(lock, waiter, ti) do { } while (0) ++#define debug_mutex_remove_waiter(lock, waiter, ti) do { } while (0) + #define debug_mutex_unlock(lock) do { } while (0) + #define debug_mutex_init(lock, name, key) do { } while (0) + +-- +2.30.2 + diff --git a/queue-4.19/series b/queue-4.19/series index 3e778042c56..31edcd352a9 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -6,3 +6,4 @@ rdma-mlx5-recover-from-fatal-event-in-dual-port-mode.patch platform-x86-dell-smbios-wmi-fix-oops-on-rmmod-dell_.patch ptrace-make-ptrace-fail-if-the-tracee-changed-its-pi.patch nvmet-seset-ns-file-when-open-fails.patch +locking-mutex-clear-mutex_flags-if-wait_list-is-empt.patch