xref: /openbmc/linux/kernel/locking/mutex-debug.c (revision 7d2a6abe)
101768b42SPeter Zijlstra /*
201768b42SPeter Zijlstra  * Debugging code for mutexes
301768b42SPeter Zijlstra  *
401768b42SPeter Zijlstra  * Started by Ingo Molnar:
501768b42SPeter Zijlstra  *
601768b42SPeter Zijlstra  *  Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
701768b42SPeter Zijlstra  *
801768b42SPeter Zijlstra  * lock debugging, locking tree, deadlock detection started by:
901768b42SPeter Zijlstra  *
1001768b42SPeter Zijlstra  *  Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey
1101768b42SPeter Zijlstra  *  Released under the General Public License (GPL).
1201768b42SPeter Zijlstra  */
1301768b42SPeter Zijlstra #include <linux/mutex.h>
1401768b42SPeter Zijlstra #include <linux/delay.h>
15*7d2a6abeSGeorge Stark #include <linux/device.h>
1601768b42SPeter Zijlstra #include <linux/export.h>
1701768b42SPeter Zijlstra #include <linux/poison.h>
1801768b42SPeter Zijlstra #include <linux/sched.h>
1901768b42SPeter Zijlstra #include <linux/spinlock.h>
2001768b42SPeter Zijlstra #include <linux/kallsyms.h>
2101768b42SPeter Zijlstra #include <linux/interrupt.h>
2201768b42SPeter Zijlstra #include <linux/debug_locks.h>
2301768b42SPeter Zijlstra 
24a321fb90SThomas Gleixner #include "mutex.h"
2501768b42SPeter Zijlstra 
2601768b42SPeter Zijlstra /*
2701768b42SPeter Zijlstra  * Must be called with lock->wait_lock held.
2801768b42SPeter Zijlstra  */
debug_mutex_lock_common(struct mutex * lock,struct mutex_waiter * waiter)2901768b42SPeter Zijlstra void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter)
3001768b42SPeter Zijlstra {
3101768b42SPeter Zijlstra 	memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter));
3201768b42SPeter Zijlstra 	waiter->magic = waiter;
3301768b42SPeter Zijlstra 	INIT_LIST_HEAD(&waiter->list);
34c0afb0ffSPeter Zijlstra 	waiter->ww_ctx = MUTEX_POISON_WW_CTX;
3501768b42SPeter Zijlstra }
3601768b42SPeter Zijlstra 
debug_mutex_wake_waiter(struct mutex * lock,struct mutex_waiter * waiter)3701768b42SPeter Zijlstra void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter)
3801768b42SPeter Zijlstra {
3904547728SLance Roy 	lockdep_assert_held(&lock->wait_lock);
4001768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(list_empty(&lock->wait_list));
4101768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(waiter->magic != waiter);
4201768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
4301768b42SPeter Zijlstra }
4401768b42SPeter Zijlstra 
debug_mutex_free_waiter(struct mutex_waiter * waiter)4501768b42SPeter Zijlstra void debug_mutex_free_waiter(struct mutex_waiter *waiter)
4601768b42SPeter Zijlstra {
4701768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(!list_empty(&waiter->list));
4801768b42SPeter Zijlstra 	memset(waiter, MUTEX_DEBUG_FREE, sizeof(*waiter));
4901768b42SPeter Zijlstra }
5001768b42SPeter Zijlstra 
debug_mutex_add_waiter(struct mutex * lock,struct mutex_waiter * waiter,struct task_struct * task)5101768b42SPeter Zijlstra void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter,
526720a305SLinus Torvalds 			    struct task_struct *task)
5301768b42SPeter Zijlstra {
5404547728SLance Roy 	lockdep_assert_held(&lock->wait_lock);
5501768b42SPeter Zijlstra 
5601768b42SPeter Zijlstra 	/* Mark the current thread as blocked on the lock: */
576720a305SLinus Torvalds 	task->blocked_on = waiter;
5801768b42SPeter Zijlstra }
5901768b42SPeter Zijlstra 
debug_mutex_remove_waiter(struct mutex * lock,struct mutex_waiter * waiter,struct task_struct * task)603a010c49SZqiang void debug_mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
616720a305SLinus Torvalds 			 struct task_struct *task)
6201768b42SPeter Zijlstra {
6301768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list));
646720a305SLinus Torvalds 	DEBUG_LOCKS_WARN_ON(waiter->task != task);
656720a305SLinus Torvalds 	DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter);
666720a305SLinus Torvalds 	task->blocked_on = NULL;
6701768b42SPeter Zijlstra 
683a010c49SZqiang 	INIT_LIST_HEAD(&waiter->list);
6901768b42SPeter Zijlstra 	waiter->task = NULL;
7001768b42SPeter Zijlstra }
7101768b42SPeter Zijlstra 
debug_mutex_unlock(struct mutex * lock)7201768b42SPeter Zijlstra void debug_mutex_unlock(struct mutex *lock)
7301768b42SPeter Zijlstra {
74a227960fSPeter Zijlstra 	if (likely(debug_locks)) {
7501768b42SPeter Zijlstra 		DEBUG_LOCKS_WARN_ON(lock->magic != lock);
7601768b42SPeter Zijlstra 		DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
77a227960fSPeter Zijlstra 	}
7801768b42SPeter Zijlstra }
7901768b42SPeter Zijlstra 
debug_mutex_init(struct mutex * lock,const char * name,struct lock_class_key * key)8001768b42SPeter Zijlstra void debug_mutex_init(struct mutex *lock, const char *name,
8101768b42SPeter Zijlstra 		      struct lock_class_key *key)
8201768b42SPeter Zijlstra {
8301768b42SPeter Zijlstra #ifdef CONFIG_DEBUG_LOCK_ALLOC
8401768b42SPeter Zijlstra 	/*
8501768b42SPeter Zijlstra 	 * Make sure we are not reinitializing a held lock:
8601768b42SPeter Zijlstra 	 */
8701768b42SPeter Zijlstra 	debug_check_no_locks_freed((void *)lock, sizeof(*lock));
88de8f5e4fSPeter Zijlstra 	lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP);
8901768b42SPeter Zijlstra #endif
9001768b42SPeter Zijlstra 	lock->magic = lock;
9101768b42SPeter Zijlstra }
9201768b42SPeter Zijlstra 
devm_mutex_release(void * res)93*7d2a6abeSGeorge Stark static void devm_mutex_release(void *res)
94*7d2a6abeSGeorge Stark {
95*7d2a6abeSGeorge Stark 	mutex_destroy(res);
96*7d2a6abeSGeorge Stark }
97*7d2a6abeSGeorge Stark 
__devm_mutex_init(struct device * dev,struct mutex * lock)98*7d2a6abeSGeorge Stark int __devm_mutex_init(struct device *dev, struct mutex *lock)
99*7d2a6abeSGeorge Stark {
100*7d2a6abeSGeorge Stark 	return devm_add_action_or_reset(dev, devm_mutex_release, lock);
101*7d2a6abeSGeorge Stark }
102*7d2a6abeSGeorge Stark EXPORT_SYMBOL_GPL(__devm_mutex_init);
103*7d2a6abeSGeorge Stark 
10401768b42SPeter Zijlstra /***
10501768b42SPeter Zijlstra  * mutex_destroy - mark a mutex unusable
10601768b42SPeter Zijlstra  * @lock: the mutex to be destroyed
10701768b42SPeter Zijlstra  *
10801768b42SPeter Zijlstra  * This function marks the mutex uninitialized, and any subsequent
10901768b42SPeter Zijlstra  * use of the mutex is forbidden. The mutex must not be locked when
11001768b42SPeter Zijlstra  * this function is called.
11101768b42SPeter Zijlstra  */
mutex_destroy(struct mutex * lock)11201768b42SPeter Zijlstra void mutex_destroy(struct mutex *lock)
11301768b42SPeter Zijlstra {
11401768b42SPeter Zijlstra 	DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock));
11501768b42SPeter Zijlstra 	lock->magic = NULL;
11601768b42SPeter Zijlstra }
11701768b42SPeter Zijlstra 
11801768b42SPeter Zijlstra EXPORT_SYMBOL_GPL(mutex_destroy);
119