Messages in this thread |  | | From | Keith Owens <> | Subject | Recursive deadlock on die_lock | Date | Sun, 14 Oct 2001 14:25:52 +1000 |
| |
Typical die() code.
spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
void die(const char * str, struct pt_regs * regs, long err) { console_verbose(); spin_lock_irq(&die_lock); bust_spinlocks(1); printk("%s: %04lx\n", str, err & 0xffff); show_registers(regs); bust_spinlocks(0); spin_unlock_irq(&die_lock); do_exit(SIGSEGV); }
If show_registers() fails (which it does far too often on IA64) then the system deadlocks trying to recursively obtain die_lock. Also die_lock is never used outside die(), it should be proc local. Suggested fix:
void die(const char * str, struct pt_regs * regs, long err) { static spinlock_t die_lock = SPIN_LOCK_UNLOCKED; static int die_lock_owner = -1, die_lock_owner_depth = 0;
if (die_lock_owner != smp_processor_id()) { console_verbose(); spin_lock_irq(&die_lock); die_lock_owner = smp_processor_id(); die_lock_owner_depth = 0; bust_spinlocks(1); }
if (++die_lock_owner_depth < 3) { printk("%s: %04lx\n", str, err & 0xffff); show_registers(regs); } else printk(KERN_ERR "Recursive die() failure, registers suppressed\n");
bust_spinlocks(0); die_lock_owner = -1; spin_unlock_irq(&die_lock); do_exit(SIGSEGV); }
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
|  |