mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
mutex_init() invokes __mutex_init() providing the name of the lock and
a pointer to a the lock class. With LOCKDEP enabled this information is
useful but without LOCKDEP it not used at all. Passing the pointer
information of the lock class might be considered negligible but the
name of the lock is passed as well and the string is stored. This
information is wasting storage.
Split __mutex_init() into a _genereic() variant doing the initialisation
of the lock and a _lockdep() version which does _genereic() plus the
lockdep bits. Restrict the lockdep version to lockdep enabled builds
allowing the compiler to remove the unused parameter.
This results in the following size reduction:
text data bss dec filename
| 30237599 8161430 1176624 39575653 vmlinux.defconfig
| 30233269 8149142 1176560 39558971 vmlinux.defconfig.patched
-4.2KiB -12KiB
| 32455099 8471098 12934684 53860881 vmlinux.defconfig.lockdep
| 32455100 8471098 12934684 53860882 vmlinux.defconfig.patched.lockdep
| 27152407 7191822 2068040 36412269 vmlinux.defconfig.preempt_rt
| 27145937 7183630 2067976 36397543 vmlinux.defconfig.patched.preempt_rt
-6.3KiB -8KiB
| 29382020 7505742 13784608 50672370 vmlinux.defconfig.preempt_rt.lockdep
| 29376229 7505742 13784544 50666515 vmlinux.defconfig.patched.preempt_rt.lockdep
-5.6KiB
[peterz: folded fix from boqun]
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Boqun Feng <boqun.feng@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Waiman Long <longman@redhat.com>
Link: https://lkml.kernel.org/r/20251125145425.68319-1-boqun.feng@gmail.com
Link: https://patch.msgid.link/20251105142350.Tfeevs2N@linutronix.de
112 lines
2.8 KiB
C
112 lines
2.8 KiB
C
/*
|
|
* Debugging code for mutexes
|
|
*
|
|
* Started by Ingo Molnar:
|
|
*
|
|
* Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
|
|
*
|
|
* lock debugging, locking tree, deadlock detection started by:
|
|
*
|
|
* Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey
|
|
* Released under the General Public License (GPL).
|
|
*/
|
|
#include <linux/mutex.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/device.h>
|
|
#include <linux/export.h>
|
|
#include <linux/poison.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/spinlock.h>
|
|
#include <linux/kallsyms.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/debug_locks.h>
|
|
|
|
#include "mutex.h"
|
|
|
|
/*
|
|
* Must be called with lock->wait_lock held.
|
|
*/
|
|
void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
|
|
{
|
|
memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter));
|
|
waiter->magic = waiter;
|
|
INIT_LIST_HEAD(&waiter->list);
|
|
waiter->ww_ctx = MUTEX_POISON_WW_CTX;
|
|
}
|
|
|
|
void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter)
|
|
{
|
|
lockdep_assert_held(&lock->wait_lock);
|
|
DEBUG_LOCKS_WARN_ON(list_empty(&lock->wait_list));
|
|
DEBUG_LOCKS_WARN_ON(waiter->magic != waiter);
|
|
DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
|
|
}
|
|
|
|
void debug_mutex_free_waiter(struct mutex_waiter *waiter)
|
|
{
|
|
DEBUG_LOCKS_WARN_ON(!list_empty(&waiter->list));
|
|
memset(waiter, MUTEX_DEBUG_FREE, sizeof(*waiter));
|
|
}
|
|
|
|
void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
|
|
struct task_struct *task)
|
|
{
|
|
lockdep_assert_held(&lock->wait_lock);
|
|
|
|
/* Current thread can't be already blocked (since it's executing!) */
|
|
DEBUG_LOCKS_WARN_ON(__get_task_blocked_on(task));
|
|
}
|
|
|
|
void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
|
|
struct task_struct *task)
|
|
{
|
|
struct mutex *blocked_on = __get_task_blocked_on(task);
|
|
|
|
DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
|
|
DEBUG_LOCKS_WARN_ON(waiter->task != task);
|
|
DEBUG_LOCKS_WARN_ON(blocked_on && blocked_on != lock);
|
|
|
|
INIT_LIST_HEAD(&waiter->list);
|
|
waiter->task = NULL;
|
|
}
|
|
|
|
void debug_mutex_unlock(struct mutex *lock)
|
|
{
|
|
if (likely(debug_locks)) {
|
|
DEBUG_LOCKS_WARN_ON(lock->magic != lock);
|
|
DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
|
|
}
|
|
}
|
|
|
|
void debug_mutex_init(struct mutex *lock)
|
|
{
|
|
lock->magic = lock;
|
|
}
|
|
|
|
static void devm_mutex_release(void *res)
|
|
{
|
|
mutex_destroy(res);
|
|
}
|
|
|
|
int __devm_mutex_init(struct device *dev, struct mutex *lock)
|
|
{
|
|
return devm_add_action_or_reset(dev, devm_mutex_release, lock);
|
|
}
|
|
EXPORT_SYMBOL_GPL(__devm_mutex_init);
|
|
|
|
/***
|
|
* mutex_destroy - mark a mutex unusable
|
|
* @lock: the mutex to be destroyed
|
|
*
|
|
* This function marks the mutex uninitialized, and any subsequent
|
|
* use of the mutex is forbidden. The mutex must not be locked when
|
|
* this function is called.
|
|
*/
|
|
void mutex_destroy(struct mutex *lock)
|
|
{
|
|
DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock));
|
|
lock->magic = NULL;
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(mutex_destroy);
|