Line data Source code
1 : /* 2 : * kernel/mutex-debug.c 3 : * 4 : * Debugging code for mutexes 5 : * 6 : * Started by Ingo Molnar: 7 : * 8 : * Copyright (C) 2004, 2005, 2006 Red Hat, Inc., Ingo Molnar <mingo@redhat.com> 9 : * 10 : * lock debugging, locking tree, deadlock detection started by: 11 : * 12 : * Copyright (C) 2004, LynuxWorks, Inc., Igor Manyilov, Bill Huey 13 : * Released under the General Public License (GPL). 14 : */ 15 : #include <linux/mutex.h> 16 : #include <linux/delay.h> 17 : #include <linux/export.h> 18 : #include <linux/poison.h> 19 : #include <linux/sched.h> 20 : #include <linux/spinlock.h> 21 : #include <linux/kallsyms.h> 22 : #include <linux/interrupt.h> 23 : #include <linux/debug_locks.h> 24 : 25 : #include "mutex-debug.h" 26 : 27 : /* 28 : * Must be called with lock->wait_lock held. 29 : */ 30 23 : void debug_mutex_lock_common(struct mutex *lock, struct mutex_waiter *waiter) 31 : { 32 23 : memset(waiter, MUTEX_DEBUG_INIT, sizeof(*waiter)); 33 23 : waiter->magic = waiter; 34 23 : INIT_LIST_HEAD(&waiter->list); 35 23 : } 36 : 37 154 : void debug_mutex_wake_waiter(struct mutex *lock, struct mutex_waiter *waiter) 38 : { 39 308 : lockdep_assert_held(&lock->wait_lock); 40 154 : DEBUG_LOCKS_WARN_ON(list_empty(&lock->wait_list)); 41 154 : DEBUG_LOCKS_WARN_ON(waiter->magic != waiter); 42 154 : DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list)); 43 154 : } 44 : 45 23 : void debug_mutex_free_waiter(struct mutex_waiter *waiter) 46 : { 47 23 : DEBUG_LOCKS_WARN_ON(!list_empty(&waiter->list)); 48 23 : memset(waiter, MUTEX_DEBUG_FREE, sizeof(*waiter)); 49 23 : } 50 : 51 23 : void debug_mutex_add_waiter(struct mutex *lock, struct mutex_waiter *waiter, 52 : struct task_struct *task) 53 : { 54 46 : lockdep_assert_held(&lock->wait_lock); 55 : 56 : /* Mark the current thread as blocked on the lock: */ 57 23 : task->blocked_on = waiter; 58 23 : } 59 : 60 23 : void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter, 61 : struct task_struct *task) 62 : { 63 23 : DEBUG_LOCKS_WARN_ON(list_empty(&waiter->list)); 64 23 : DEBUG_LOCKS_WARN_ON(waiter->task != task); 65 23 : DEBUG_LOCKS_WARN_ON(task->blocked_on != waiter); 66 23 : task->blocked_on = NULL; 67 : 68 23 : list_del_init(&waiter->list); 69 23 : waiter->task = NULL; 70 23 : } 71 : 72 154 : void debug_mutex_unlock(struct mutex *lock) 73 : { 74 154 : if (likely(debug_locks)) { 75 154 : DEBUG_LOCKS_WARN_ON(lock->magic != lock); 76 154 : DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next); 77 : } 78 154 : } 79 : 80 75540 : void debug_mutex_init(struct mutex *lock, const char *name, 81 : struct lock_class_key *key) 82 : { 83 : #ifdef CONFIG_DEBUG_LOCK_ALLOC 84 : /* 85 : * Make sure we are not reinitializing a held lock: 86 : */ 87 75540 : debug_check_no_locks_freed((void *)lock, sizeof(*lock)); 88 75541 : lockdep_init_map_wait(&lock->dep_map, name, key, 0, LD_WAIT_SLEEP); 89 : #endif 90 75542 : lock->magic = lock; 91 75542 : } 92 : 93 : /*** 94 : * mutex_destroy - mark a mutex unusable 95 : * @lock: the mutex to be destroyed 96 : * 97 : * This function marks the mutex uninitialized, and any subsequent 98 : * use of the mutex is forbidden. The mutex must not be locked when 99 : * this function is called. 100 : */ 101 68 : void mutex_destroy(struct mutex *lock) 102 : { 103 68 : DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock)); 104 68 : lock->magic = NULL; 105 68 : } 106 : 107 : EXPORT_SYMBOL_GPL(mutex_destroy);