at v2.6.16 6.0 kB view raw
1/* 2 * Copyright 2005, Red Hat, Inc., Ingo Molnar 3 * Released under the General Public License (GPL). 4 * 5 * This file contains the spinlock/rwlock implementations for 6 * DEBUG_SPINLOCK. 7 */ 8 9#include <linux/config.h> 10#include <linux/spinlock.h> 11#include <linux/interrupt.h> 12#include <linux/delay.h> 13 14static void spin_bug(spinlock_t *lock, const char *msg) 15{ 16 static long print_once = 1; 17 struct task_struct *owner = NULL; 18 19 if (xchg(&print_once, 0)) { 20 if (lock->owner && lock->owner != SPINLOCK_OWNER_INIT) 21 owner = lock->owner; 22 printk(KERN_EMERG "BUG: spinlock %s on CPU#%d, %s/%d\n", 23 msg, raw_smp_processor_id(), 24 current->comm, current->pid); 25 printk(KERN_EMERG " lock: %p, .magic: %08x, .owner: %s/%d, " 26 ".owner_cpu: %d\n", 27 lock, lock->magic, 28 owner ? owner->comm : "<none>", 29 owner ? owner->pid : -1, 30 lock->owner_cpu); 31 dump_stack(); 32#ifdef CONFIG_SMP 33 /* 34 * We cannot continue on SMP: 35 */ 36// panic("bad locking"); 37#endif 38 } 39} 40 41#define SPIN_BUG_ON(cond, lock, msg) if (unlikely(cond)) spin_bug(lock, msg) 42 43static inline void debug_spin_lock_before(spinlock_t *lock) 44{ 45 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); 46 SPIN_BUG_ON(lock->owner == current, lock, "recursion"); 47 SPIN_BUG_ON(lock->owner_cpu == raw_smp_processor_id(), 48 lock, "cpu recursion"); 49} 50 51static inline void debug_spin_lock_after(spinlock_t *lock) 52{ 53 lock->owner_cpu = raw_smp_processor_id(); 54 lock->owner = current; 55} 56 57static inline void debug_spin_unlock(spinlock_t *lock) 58{ 59 SPIN_BUG_ON(lock->magic != SPINLOCK_MAGIC, lock, "bad magic"); 60 SPIN_BUG_ON(!spin_is_locked(lock), lock, "already unlocked"); 61 SPIN_BUG_ON(lock->owner != current, lock, "wrong owner"); 62 SPIN_BUG_ON(lock->owner_cpu != raw_smp_processor_id(), 63 lock, "wrong CPU"); 64 lock->owner = SPINLOCK_OWNER_INIT; 65 lock->owner_cpu = -1; 66} 67 68static void __spin_lock_debug(spinlock_t *lock) 69{ 70 int print_once = 1; 71 u64 i; 72 73 for (;;) { 74 for (i = 0; i < loops_per_jiffy * HZ; i++) { 75 if (__raw_spin_trylock(&lock->raw_lock)) 76 return; 77 __delay(1); 78 } 79 /* lockup suspected: */ 80 if (print_once) { 81 print_once = 0; 82 printk(KERN_EMERG "BUG: spinlock lockup on CPU#%d, " 83 "%s/%d, %p\n", 84 raw_smp_processor_id(), current->comm, 85 current->pid, lock); 86 dump_stack(); 87 } 88 } 89} 90 91void _raw_spin_lock(spinlock_t *lock) 92{ 93 debug_spin_lock_before(lock); 94 if (unlikely(!__raw_spin_trylock(&lock->raw_lock))) 95 __spin_lock_debug(lock); 96 debug_spin_lock_after(lock); 97} 98 99int _raw_spin_trylock(spinlock_t *lock) 100{ 101 int ret = __raw_spin_trylock(&lock->raw_lock); 102 103 if (ret) 104 debug_spin_lock_after(lock); 105#ifndef CONFIG_SMP 106 /* 107 * Must not happen on UP: 108 */ 109 SPIN_BUG_ON(!ret, lock, "trylock failure on UP"); 110#endif 111 return ret; 112} 113 114void _raw_spin_unlock(spinlock_t *lock) 115{ 116 debug_spin_unlock(lock); 117 __raw_spin_unlock(&lock->raw_lock); 118} 119 120static void rwlock_bug(rwlock_t *lock, const char *msg) 121{ 122 static long print_once = 1; 123 124 if (xchg(&print_once, 0)) { 125 printk(KERN_EMERG "BUG: rwlock %s on CPU#%d, %s/%d, %p\n", 126 msg, raw_smp_processor_id(), current->comm, 127 current->pid, lock); 128 dump_stack(); 129#ifdef CONFIG_SMP 130 /* 131 * We cannot continue on SMP: 132 */ 133 panic("bad locking"); 134#endif 135 } 136} 137 138#define RWLOCK_BUG_ON(cond, lock, msg) if (unlikely(cond)) rwlock_bug(lock, msg) 139 140static void __read_lock_debug(rwlock_t *lock) 141{ 142 int print_once = 1; 143 u64 i; 144 145 for (;;) { 146 for (i = 0; i < loops_per_jiffy * HZ; i++) { 147 if (__raw_read_trylock(&lock->raw_lock)) 148 return; 149 __delay(1); 150 } 151 /* lockup suspected: */ 152 if (print_once) { 153 print_once = 0; 154 printk(KERN_EMERG "BUG: read-lock lockup on CPU#%d, " 155 "%s/%d, %p\n", 156 raw_smp_processor_id(), current->comm, 157 current->pid, lock); 158 dump_stack(); 159 } 160 } 161} 162 163void _raw_read_lock(rwlock_t *lock) 164{ 165 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 166 if (unlikely(!__raw_read_trylock(&lock->raw_lock))) 167 __read_lock_debug(lock); 168} 169 170int _raw_read_trylock(rwlock_t *lock) 171{ 172 int ret = __raw_read_trylock(&lock->raw_lock); 173 174#ifndef CONFIG_SMP 175 /* 176 * Must not happen on UP: 177 */ 178 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP"); 179#endif 180 return ret; 181} 182 183void _raw_read_unlock(rwlock_t *lock) 184{ 185 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 186 __raw_read_unlock(&lock->raw_lock); 187} 188 189static inline void debug_write_lock_before(rwlock_t *lock) 190{ 191 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 192 RWLOCK_BUG_ON(lock->owner == current, lock, "recursion"); 193 RWLOCK_BUG_ON(lock->owner_cpu == raw_smp_processor_id(), 194 lock, "cpu recursion"); 195} 196 197static inline void debug_write_lock_after(rwlock_t *lock) 198{ 199 lock->owner_cpu = raw_smp_processor_id(); 200 lock->owner = current; 201} 202 203static inline void debug_write_unlock(rwlock_t *lock) 204{ 205 RWLOCK_BUG_ON(lock->magic != RWLOCK_MAGIC, lock, "bad magic"); 206 RWLOCK_BUG_ON(lock->owner != current, lock, "wrong owner"); 207 RWLOCK_BUG_ON(lock->owner_cpu != raw_smp_processor_id(), 208 lock, "wrong CPU"); 209 lock->owner = SPINLOCK_OWNER_INIT; 210 lock->owner_cpu = -1; 211} 212 213static void __write_lock_debug(rwlock_t *lock) 214{ 215 int print_once = 1; 216 u64 i; 217 218 for (;;) { 219 for (i = 0; i < loops_per_jiffy * HZ; i++) { 220 if (__raw_write_trylock(&lock->raw_lock)) 221 return; 222 __delay(1); 223 } 224 /* lockup suspected: */ 225 if (print_once) { 226 print_once = 0; 227 printk(KERN_EMERG "BUG: write-lock lockup on CPU#%d, " 228 "%s/%d, %p\n", 229 raw_smp_processor_id(), current->comm, 230 current->pid, lock); 231 dump_stack(); 232 } 233 } 234} 235 236void _raw_write_lock(rwlock_t *lock) 237{ 238 debug_write_lock_before(lock); 239 if (unlikely(!__raw_write_trylock(&lock->raw_lock))) 240 __write_lock_debug(lock); 241 debug_write_lock_after(lock); 242} 243 244int _raw_write_trylock(rwlock_t *lock) 245{ 246 int ret = __raw_write_trylock(&lock->raw_lock); 247 248 if (ret) 249 debug_write_lock_after(lock); 250#ifndef CONFIG_SMP 251 /* 252 * Must not happen on UP: 253 */ 254 RWLOCK_BUG_ON(!ret, lock, "trylock failure on UP"); 255#endif 256 return ret; 257} 258 259void _raw_write_unlock(rwlock_t *lock) 260{ 261 debug_write_unlock(lock); 262 __raw_write_unlock(&lock->raw_lock); 263}