101768b42SPeter Zijlstra /* 201768b42SPeter Zijlstra * kernel/mutex-debug.c 301768b42SPeter Zijlstra * 401768b42SPeter Zijlstra * Debugging code for mutexes 501768b42SPeter Zijlstra * 601768b42SPeter Zijlstra * Started by Ingo Molnar: 701768b42SPeter Zijlstra * 801768b42SPeter Zijlstra * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> 901768b42SPeter Zijlstra * 1001768b42SPeter Zijlstra * lock debugging, locking tree, deadlock detection started by: 1101768b42SPeter Zijlstra * 1201768b42SPeter Zijlstra * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey 1301768b42SPeter Zijlstra * Released under the General Public License (GPL). 1401768b42SPeter Zijlstra */ 1501768b42SPeter Zijlstra #include <linux/mutex.h> 1601768b42SPeter Zijlstra #include <linux/delay.h> 1701768b42SPeter Zijlstra #include <linux/export.h> 1801768b42SPeter Zijlstra #include <linux/poison.h> 1901768b42SPeter Zijlstra #include <linux/sched.h> 2001768b42SPeter Zijlstra #include <linux/spinlock.h> 2101768b42SPeter Zijlstra #include <linux/kallsyms.h> 2201768b42SPeter Zijlstra #include <linux/interrupt.h> 2301768b42SPeter Zijlstra #include <linux/debug_locks.h> 2401768b42SPeter Zijlstra 2501768b42SPeter Zijlstra #include "mutex-debug.h" 2601768b42SPeter Zijlstra 2701768b42SPeter Zijlstra /* 2801768b42SPeter Zijlstra * Must be called with lock->wait_lock held. 2901768b42SPeter Zijlstra */ 3001768b42SPeter Zijlstra void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter) 3101768b42SPeter Zijlstra { 3201768b42SPeter Zijlstra memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter)); 3301768b42SPeter Zijlstra waiter->magic = waiter; 3401768b42SPeter Zijlstra INIT_LIST_HEAD(&waiter->list); 3501768b42SPeter Zijlstra } 3601768b42SPeter Zijlstra 3701768b42SPeter Zijlstra void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter) 3801768b42SPeter Zijlstra { 39*04547728SLance 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 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 5101768b42SPeter Zijlstra void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, 526720a305SLinus Torvalds struct task_struct *task) 5301768b42SPeter Zijlstra { 54*04547728SLance 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 6001768b42SPeter Zijlstra void 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 6801768b42SPeter Zijlstra list_del_init(&waiter->list); 6901768b42SPeter Zijlstra waiter->task = NULL; 7001768b42SPeter Zijlstra } 7101768b42SPeter Zijlstra 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 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)); 8801768b42SPeter Zijlstra lockdep_init_map(&lock->dep_map, name, key, 0); 8901768b42SPeter Zijlstra #endif 9001768b42SPeter Zijlstra lock->magic = lock; 9101768b42SPeter Zijlstra } 9201768b42SPeter Zijlstra 9301768b42SPeter Zijlstra /*** 9401768b42SPeter Zijlstra * mutex_destroy - mark a mutex unusable 9501768b42SPeter Zijlstra * @lock: the mutex to be destroyed 9601768b42SPeter Zijlstra * 9701768b42SPeter Zijlstra * This function marks the mutex uninitialized, and any subsequent 9801768b42SPeter Zijlstra * use of the mutex is forbidden. The mutex must not be locked when 9901768b42SPeter Zijlstra * this function is called. 10001768b42SPeter Zijlstra */ 10101768b42SPeter Zijlstra void mutex_destroy(struct mutex *lock) 10201768b42SPeter Zijlstra { 10301768b42SPeter Zijlstra DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock)); 10401768b42SPeter Zijlstra lock->magic = NULL; 10501768b42SPeter Zijlstra } 10601768b42SPeter Zijlstra 10701768b42SPeter Zijlstra EXPORT_SYMBOL_GPL(mutex_destroy); 108