[SPARC64]: Make debugging spinlocks usable again.

When the spinlock routines were moved out of line into
kernel/spinlock.c this made it so that the debugging
spinlocks record lock acquisition program counts in the
kernel/spinlock.c functions not in their callers.
This makes the debugging info kind of useless.

So record the correct caller's program counter and
now this feature is useful once more.

Signed-off-by: David S. Miller <davem@davemloft.net>

+37 -64
-23
arch/sparc64/kernel/sparc64_ksyms.c
··· 99 99 extern void dump_thread(struct pt_regs *, struct user *); 100 100 extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs); 101 101 102 - #if defined(CONFIG_SMP) && defined(CONFIG_DEBUG_SPINLOCK) 103 - extern void _do_spin_lock (spinlock_t *lock, char *str); 104 - extern void _do_spin_unlock (spinlock_t *lock); 105 - extern int _spin_trylock (spinlock_t *lock); 106 - extern void _do_read_lock(rwlock_t *rw, char *str); 107 - extern void _do_read_unlock(rwlock_t *rw, char *str); 108 - extern void _do_write_lock(rwlock_t *rw, char *str); 109 - extern void _do_write_unlock(rwlock_t *rw); 110 - extern int _do_write_trylock(rwlock_t *rw, char *str); 111 - #endif 112 - 113 102 extern unsigned long phys_base; 114 103 extern unsigned long pfn_base; 115 104 ··· 140 151 /* CPU online map and active count. */ 141 152 EXPORT_SYMBOL(cpu_online_map); 142 153 EXPORT_SYMBOL(phys_cpu_present_map); 143 - 144 - /* Spinlock debugging library, optional. */ 145 - #ifdef CONFIG_DEBUG_SPINLOCK 146 - EXPORT_SYMBOL(_do_spin_lock); 147 - EXPORT_SYMBOL(_do_spin_unlock); 148 - EXPORT_SYMBOL(_spin_trylock); 149 - EXPORT_SYMBOL(_do_read_lock); 150 - EXPORT_SYMBOL(_do_read_unlock); 151 - EXPORT_SYMBOL(_do_write_lock); 152 - EXPORT_SYMBOL(_do_write_unlock); 153 - EXPORT_SYMBOL(_do_write_trylock); 154 - #endif 155 154 156 155 EXPORT_SYMBOL(smp_call_function); 157 156 #endif /* CONFIG_SMP */
+14 -26
arch/sparc64/lib/debuglocks.c
··· 12 12 13 13 #ifdef CONFIG_SMP 14 14 15 - #define GET_CALLER(PC) __asm__ __volatile__("mov %%i7, %0" : "=r" (PC)) 16 - 17 15 static inline void show (char *str, spinlock_t *lock, unsigned long caller) 18 16 { 19 17 int cpu = smp_processor_id(); ··· 49 51 #undef INIT_STUCK 50 52 #define INIT_STUCK 100000000 51 53 52 - void _do_spin_lock(spinlock_t *lock, char *str) 54 + void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller) 53 55 { 54 - unsigned long caller, val; 56 + unsigned long val; 55 57 int stuck = INIT_STUCK; 56 58 int cpu = get_cpu(); 57 59 int shown = 0; 58 60 59 - GET_CALLER(caller); 60 61 again: 61 62 __asm__ __volatile__("ldstub [%1], %0" 62 63 : "=r" (val) ··· 81 84 put_cpu(); 82 85 } 83 86 84 - int _do_spin_trylock(spinlock_t *lock) 87 + int _do_spin_trylock(spinlock_t *lock, unsigned long caller) 85 88 { 86 - unsigned long val, caller; 89 + unsigned long val; 87 90 int cpu = get_cpu(); 88 91 89 - GET_CALLER(caller); 90 92 __asm__ __volatile__("ldstub [%1], %0" 91 93 : "=r" (val) 92 94 : "r" (&(lock->lock)) ··· 114 118 115 119 /* Keep INIT_STUCK the same... */ 116 120 117 - void _do_read_lock (rwlock_t *rw, char *str) 121 + void _do_read_lock(rwlock_t *rw, char *str, unsigned long caller) 118 122 { 119 - unsigned long caller, val; 123 + unsigned long val; 120 124 int stuck = INIT_STUCK; 121 125 int cpu = get_cpu(); 122 126 int shown = 0; 123 127 124 - GET_CALLER(caller); 125 128 wlock_again: 126 129 /* Wait for any writer to go away. */ 127 130 while (((long)(rw->lock)) < 0) { ··· 152 157 put_cpu(); 153 158 } 154 159 155 - void _do_read_unlock (rwlock_t *rw, char *str) 160 + void _do_read_unlock(rwlock_t *rw, char *str, unsigned long caller) 156 161 { 157 - unsigned long caller, val; 162 + unsigned long val; 158 163 int stuck = INIT_STUCK; 159 164 int cpu = get_cpu(); 160 165 int shown = 0; 161 - 162 - GET_CALLER(caller); 163 166 164 167 /* Drop our identity _first_. */ 165 168 rw->reader_pc[cpu] = 0; ··· 186 193 put_cpu(); 187 194 } 188 195 189 - void _do_write_lock (rwlock_t *rw, char *str) 196 + void _do_write_lock(rwlock_t *rw, char *str, unsigned long caller) 190 197 { 191 - unsigned long caller, val; 198 + unsigned long val; 192 199 int stuck = INIT_STUCK; 193 200 int cpu = get_cpu(); 194 201 int shown = 0; 195 202 196 - GET_CALLER(caller); 197 203 wlock_again: 198 204 /* Spin while there is another writer. */ 199 205 while (((long)rw->lock) < 0) { ··· 270 278 put_cpu(); 271 279 } 272 280 273 - void _do_write_unlock(rwlock_t *rw) 281 + void _do_write_unlock(rwlock_t *rw, unsigned long caller) 274 282 { 275 - unsigned long caller, val; 283 + unsigned long val; 276 284 int stuck = INIT_STUCK; 277 285 int shown = 0; 278 - 279 - GET_CALLER(caller); 280 286 281 287 /* Drop our identity _first_ */ 282 288 rw->writer_pc = 0; ··· 303 313 } 304 314 } 305 315 306 - int _do_write_trylock (rwlock_t *rw, char *str) 316 + int _do_write_trylock(rwlock_t *rw, char *str, unsigned long caller) 307 317 { 308 - unsigned long caller, val; 318 + unsigned long val; 309 319 int cpu = get_cpu(); 310 - 311 - GET_CALLER(caller); 312 320 313 321 /* Try to acuire the write bit. */ 314 322 __asm__ __volatile__(
+23 -15
include/asm-sparc64/spinlock.h
··· 132 132 membar("#LoadLoad"); \ 133 133 } while((__lock)->lock) 134 134 135 - extern void _do_spin_lock (spinlock_t *lock, char *str); 136 - extern void _do_spin_unlock (spinlock_t *lock); 137 - extern int _do_spin_trylock (spinlock_t *lock); 135 + extern void _do_spin_lock(spinlock_t *lock, char *str, unsigned long caller); 136 + extern void _do_spin_unlock(spinlock_t *lock); 137 + extern int _do_spin_trylock(spinlock_t *lock, unsigned long caller); 138 138 139 - #define _raw_spin_trylock(lp) _do_spin_trylock(lp) 140 - #define _raw_spin_lock(lock) _do_spin_lock(lock, "spin_lock") 139 + #define _raw_spin_trylock(lp) \ 140 + _do_spin_trylock(lp, (unsigned long) __builtin_return_address(0)) 141 + #define _raw_spin_lock(lock) \ 142 + _do_spin_lock(lock, "spin_lock", \ 143 + (unsigned long) __builtin_return_address(0)) 141 144 #define _raw_spin_unlock(lock) _do_spin_unlock(lock) 142 145 #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) 143 146 ··· 282 279 #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0, 0xff, { } } 283 280 #define rwlock_init(lp) do { *(lp) = RW_LOCK_UNLOCKED; } while(0) 284 281 285 - extern void _do_read_lock(rwlock_t *rw, char *str); 286 - extern void _do_read_unlock(rwlock_t *rw, char *str); 287 - extern void _do_write_lock(rwlock_t *rw, char *str); 288 - extern void _do_write_unlock(rwlock_t *rw); 289 - extern int _do_write_trylock(rwlock_t *rw, char *str); 282 + extern void _do_read_lock(rwlock_t *rw, char *str, unsigned long caller); 283 + extern void _do_read_unlock(rwlock_t *rw, char *str, unsigned long caller); 284 + extern void _do_write_lock(rwlock_t *rw, char *str, unsigned long caller); 285 + extern void _do_write_unlock(rwlock_t *rw, unsigned long caller); 286 + extern int _do_write_trylock(rwlock_t *rw, char *str, unsigned long caller); 290 287 291 288 #define _raw_read_lock(lock) \ 292 289 do { unsigned long flags; \ 293 290 local_irq_save(flags); \ 294 - _do_read_lock(lock, "read_lock"); \ 291 + _do_read_lock(lock, "read_lock", \ 292 + (unsigned long) __builtin_return_address(0)); \ 295 293 local_irq_restore(flags); \ 296 294 } while(0) 297 295 298 296 #define _raw_read_unlock(lock) \ 299 297 do { unsigned long flags; \ 300 298 local_irq_save(flags); \ 301 - _do_read_unlock(lock, "read_unlock"); \ 299 + _do_read_unlock(lock, "read_unlock", \ 300 + (unsigned long) __builtin_return_address(0)); \ 302 301 local_irq_restore(flags); \ 303 302 } while(0) 304 303 305 304 #define _raw_write_lock(lock) \ 306 305 do { unsigned long flags; \ 307 306 local_irq_save(flags); \ 308 - _do_write_lock(lock, "write_lock"); \ 307 + _do_write_lock(lock, "write_lock", \ 308 + (unsigned long) __builtin_return_address(0)); \ 309 309 local_irq_restore(flags); \ 310 310 } while(0) 311 311 312 312 #define _raw_write_unlock(lock) \ 313 313 do { unsigned long flags; \ 314 314 local_irq_save(flags); \ 315 - _do_write_unlock(lock); \ 315 + _do_write_unlock(lock, \ 316 + (unsigned long) __builtin_return_address(0)); \ 316 317 local_irq_restore(flags); \ 317 318 } while(0) 318 319 ··· 324 317 ({ unsigned long flags; \ 325 318 int val; \ 326 319 local_irq_save(flags); \ 327 - val = _do_write_trylock(lock, "write_trylock"); \ 320 + val = _do_write_trylock(lock, "write_trylock", \ 321 + (unsigned long) __builtin_return_address(0)); \ 328 322 local_irq_restore(flags); \ 329 323 val; \ 330 324 })