sparc asyncd deadlock prone

Andrea Arcangeli (andrea@suse.de)
Sat, 16 Oct 1999 22:54:27 +0200 (CEST)


Looking at linux-2.3.22/arch/sparc/mm/asyncd.c and
linux-2.3.22/arch/sparc64/mm/asyncd.c I found this piece of code (it's
the same in both the two files):

while (1) {
unsigned flags;

save_flags(flags); cli();

while (!async_queue) {
spin_lock_irq(&current->sigmask_lock);
flush_signals(current);
spin_unlock_irq(&current->sigmask_lock);
interruptible_sleep_on(&asyncd_wait);
}

restore_flags(flags);

run_async_queue();
}

I think the above is prone to deadlock. This because it's not safe to
re-enable irq locally (with spin_unlock_irq) while we still hold the
global_irq_lock from the global_cli(). This because any irq that may
interrupt us while we have irq enabled will spin on the global_irq_lock
that is hold by us...

Calling interruptible_sleep_on() there instead is safe as schedule will
release the global irq lock _before_ reenabling interrupts locally (but it
won't acquire the global_irq_lock later).

If the cli() was necessary than the spin_*lock_irq() should be replaced
with spin_*lock() and a cli() should be used after the
interruptible_sleep_on() call.

Andrea

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/