@@ -57,7 +57,7 @@ void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
task->blocked_on = waiter;
}
-void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
+void 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 debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter);
task->blocked_on = NULL;
- INIT_LIST_HEAD(&waiter->list);
+ list_del_init(&waiter->list);
waiter->task = NULL;
}
@@ -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 debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
+extern void 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,
@@ -172,16 +172,6 @@ static inline bool __mutex_waiter_is_first(struct mutex *lock, struct mutex_wait
return list_first_entry(&lock->wait_list, struct mutex_waiter, list) == waiter;
}
-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
@@ -868,7 +858,9 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
acquired:
__set_current_state(TASK_RUNNING);
- __mutex_remove_waiter(lock, &waiter);
+ mutex_remove_waiter(lock, &waiter, current);
+ if (likely(list_empty(&lock->wait_list)))
+ __mutex_clear_flag(lock, MUTEX_FLAGS);
debug_mutex_free_waiter(&waiter);
@@ -885,7 +877,7 @@ __mutex_lock_common(struct mutex *lock, long state, unsigned int subclass,
err:
__set_current_state(TASK_RUNNING);
- __mutex_remove_waiter(lock, &waiter);
+ mutex_remove_waiter(lock, &waiter, current);
err_early_backoff:
spin_unlock(&lock->wait_lock);
debug_mutex_free_waiter(&waiter);
@@ -10,10 +10,12 @@
* !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)
This reverts commit 2e1eb7b6e1e0e4bd988b0bbcbd96e2fee205885b, it seems to depend on some additional changes to locking and we have reports of strange corruption happening in various cases. Not really something that can be pinpointed but a chance that something related to locking is causing this. Signed-off-by: Stefan Bader <stefan.bader@canonical.com> --- kernel/locking/mutex-debug.c | 4 ++-- kernel/locking/mutex-debug.h | 2 +- kernel/locking/mutex.c | 16 ++++------------ kernel/locking/mutex.h | 4 +++- 4 files changed, 10 insertions(+), 16 deletions(-)