locking/mutex: Initialize mutex::magic even when LOCKDEP=n When DEBUG_MUTEXES=y and LOCKDEP=n, mutex_lock() still checks on ->magic, hence debug_mutex_init() should be called in mutex_init_generic() as well. While we are at it, decouple LOCKDEP logic from debug_mutex_init(), because in this way debug_mutex_init() only needs one parameter, and we now have mutex_init_lockep() for LOCKDEP=y scenarios. Reported-by: Stephen Rothwell <sfr@canb.auug.org.au> Closes: https://lore.kernel.org/lkml/20251117202214.4f710f02@canb.auug.org.au/ Reported-by: Nathan Chancellor <nathan@kernel.org> Closes: https://lore.kernel.org/lkml/20251121215819.GA1374726@ax162/ Fixes: 3572e2edc7b6 ("locking/mutex: Redo __mutex_init()") Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c index 949103f..2c6b02d 100644 --- a/kernel/locking/mutex-debug.c +++ b/kernel/locking/mutex-debug.c
@@ -78,16 +78,8 @@ void debug_mutex_unlock(struct mutex *lock) } } -void debug_mutex_init(struct mutex *lock, const char *name, - struct lock_class_key *key) +void debug_mutex_init(struct mutex *lock) { -#ifdef CONFIG_DEBUG_LOCK_ALLOC - /* - * Make sure we are not reinitializing a held lock: - */ - debug_check_no_locks_freed((void *)lock, sizeof(*lock)); - lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP); -#endif lock->magic = lock; }
diff --git a/kernel/locking/mutex.c b/kernel/locking/mutex.c index f3bb352..2a1d165 100644 --- a/kernel/locking/mutex.c +++ b/kernel/locking/mutex.c
@@ -51,6 +51,7 @@ static void __mutex_init_generic(struct mutex *lock) #ifdef CONFIG_MUTEX_SPIN_ON_OWNER osq_lock_init(&lock->osq); #endif + debug_mutex_init(lock); } static inline struct task_struct *__owner_task(unsigned long owner) @@ -173,7 +174,12 @@ static __always_inline bool __mutex_unlock_fast(struct mutex *lock) void mutex_init_lockep(struct mutex *lock, const char *name, struct lock_class_key *key) { __mutex_init_generic(lock); - debug_mutex_init(lock, name, key); + + /* + * Make sure we are not reinitializing a held lock: + */ + debug_check_no_locks_freed((void *)lock, sizeof(*lock)); + lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP); } EXPORT_SYMBOL(mutex_init_lockep); #endif /* !CONFIG_DEBUG_LOCK_ALLOC */
diff --git a/kernel/locking/mutex.h b/kernel/locking/mutex.h index 2e8080a..9ad4da8 100644 --- a/kernel/locking/mutex.h +++ b/kernel/locking/mutex.h
@@ -59,8 +59,7 @@ extern void debug_mutex_add_waiter(struct mutex *lock, 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, - struct lock_class_key *key); +extern void debug_mutex_init(struct mutex *lock); #else /* CONFIG_DEBUG_MUTEXES */ # define debug_mutex_lock_common(lock, waiter) do { } while (0) # define debug_mutex_wake_waiter(lock, waiter) do { } while (0) @@ -68,6 +67,6 @@ extern void debug_mutex_init(struct mutex *lock, const char *name, # 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) +# define debug_mutex_init(lock) do { } while (0) #endif /* !CONFIG_DEBUG_MUTEXES */ #endif /* CONFIG_PREEMPT_RT */