lkml.org 
[lkml]   [2001]   [Oct]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
From
SubjectRecursive deadlock on die_lock
Date
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/

\
 
 \ /
  Last update: 2005-03-22 13:08    [W:0.059 / U:4.596 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site