[PATCH] fix altsysrq deadlock

From: Jason Baron
Date: Tue Oct 26 2004 - 12:29:12 EST



hi,

This patch fixes a deadlock in the handle_sysrq function. The handle_sysrq
function is called in both process as well as interrupt context. The
__sysrq_lock_table() function does not disable interrupts when taking the
sysrq_key_table_lock. Thus, it is fairly easy to to do a keyboard
sys-altrq-foo, while a 'echo foo > /proc/sysrq-trigger' is running and
cause a deadlock. It can be annoying to have the machine lockup exactly
when you are trying to debug something else.

Usually a spin_lock_irqsave would be used. However, I don't think that is
appropriate here because some of the altsysrq functions can take a while
to run.

Thus, the patch below simply uses a spin_trylock and on failure does not
spin if we are in interrupt context. A trylock in all cases would be ok
too, but this patch preserves existing behavior as much as possible. An
altsyrq that produces no output might seem troublesome, but it is
primarily used as a debugging tool, so trying it again seems reasonable.

Please apply.

-Jason

--- linux/drivers/char/sysrq.c.orig Tue Oct 26 12:49:59 2004
+++ linux/drivers/char/sysrq.c Tue Oct 26 12:54:51 2004
@@ -291,6 +291,8 @@ void __sysrq_lock_table (void) { spin_lo

void __sysrq_unlock_table (void) { spin_unlock(&sysrq_key_table_lock); }

+#define __sysrq_trylock_table() spin_trylock(&sysrq_key_table_lock)
+
/*
* get and put functions for the table, exposed to modules.
*/
@@ -324,7 +326,13 @@ void __handle_sysrq(int key, struct pt_r
int orig_log_level;
int i, j;

- __sysrq_lock_table();
+ if(!__sysrq_trylock_table()) {
+ if(in_interrupt())
+ return;
+ else
+ __sysrq_lock_table();
+ }
+
orig_log_level = console_loglevel;
console_loglevel = 7;
printk(KERN_INFO "SysRq : ");


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