/* * debugging spinlocks for parisc * * Adapted from the ppc version */ #include #include #include #include #include #include #include #ifdef CONFIG_DEBUG_SPINLOCK #undef INIT_STUCK #define INIT_STUCK 200000000 /*0xffffffff*/ #define __spin_trylock(x) (__ldcw(&(x)->lock) != 0) void spin_lock(spinlock_t *lock) { int cpu = smp_processor_id(); unsigned int stuck = INIT_STUCK; while (!__spin_trylock(lock)) { while ((unsigned volatile long)lock->lock == 0) { if (!--stuck) { printk("spin_lock(%p) CPU#%d NIP %p" " holder: cpu %ld pc %08lX\n", lock, cpu, __builtin_return_address(0), lock->owner_cpu,lock->owner_pc); stuck = INIT_STUCK; /* steal the lock */ /*xchg_u32((void *)&lock->lock,0);*/ } } } lock->owner_pc = (unsigned long)__builtin_return_address(0); lock->owner_cpu = cpu; } int spin_trylock(spinlock_t *lock) { if (!__spin_trylock(lock)) return 0; lock->owner_cpu = smp_processor_id(); lock->owner_pc = (unsigned long)__builtin_return_address(0); return 1; } void spin_unlock(spinlock_t *lp) { if ( lp->lock ) printk("spin_unlock(%p): no lock cpu %d curr PC %p %s/%d\n", lp, smp_processor_id(), __builtin_return_address(0), current->comm, current->pid); if ( lp->owner_cpu != smp_processor_id() ) printk("spin_unlock(%p): cpu %d trying clear of cpu %d pc %lx val %x\n", lp, smp_processor_id(), (int)lp->owner_cpu, lp->owner_pc,lp->lock); lp->owner_pc = lp->owner_cpu = 0; wmb(); lp->lock = 1; } #endif