ia64/linux-2.6.18-xen.hg

annotate lib/spinlock_debug.c @ 740:bf8b1ee634e2

balloon: Fix the build by including <linux/init.h>

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