[PATCH/RFC] sysrq: updating console_loglevel

Randy.Dunlap
2005-09-26T04:43:58Z

Chris,
Here's a patch for you to try. It creates a safe method for
sysrq handlers to modify console_loglevel, which I suspect is
why you were not seeing messages on the serial console.

Please report back on your testing.
Thanks.
---

From: Randy Dunlap <rdunlap@xenotime.net>

Some sysrq handlers modify the console_loglevel variable,
but when they do so, some of their own messages may be lost
(not logged, esp. on serial console).

This patch introduces a way for console_loglevel to be
modified safely by the sysrq handlers. The new value is not
set until the sysrq handler complets and returns.

Signed-off-by: Randy Dunlap <rdunlap@xenotime.net>
---

drivers/char/sysrq.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)

diff -Naurp linux-2613-rc2/drivers/char/sysrq.c~fix_loglevel linux-2613-rc2/drivers/char/sysrq.c
--- linux-2613-rc2/drivers/char/sysrq.c~fix_loglevel 2005-07-09 13:55:01.000000000 -0700
+++ linux-2613-rc2/drivers/char/sysrq.c 2005-09-25 21:31:12.000000000 -0700
@@ -41,6 +41,7 @@

/* Whether we react on sysrq keys or just ignore them */
int sysrq_enabled = 1;
+static int next_log_level;

/* Loglevel sysrq handler */
static void sysrq_handle_loglevel(int key, struct pt_regs *pt_regs,
@@ -50,7 +51,7 @@ static void sysrq_handle_loglevel(int ke
i = key - '0';
console_loglevel = 7;
printk("Loglevel set to %d\n", i);
- console_loglevel = i;
+ next_log_level = i;
}
static struct sysrq_key_op sysrq_loglevel_op = {
.handler = sysrq_handle_loglevel,
@@ -217,7 +218,7 @@ static void sysrq_handle_term(int key, s
struct tty_struct *tty)
{
send_sig_all(SIGTERM);
- console_loglevel = 8;
+ next_log_level = 8;
}
static struct sysrq_key_op sysrq_term_op = {
.handler = sysrq_handle_term,
@@ -248,7 +249,7 @@ static void sysrq_handle_kill(int key, s
struct tty_struct *tty)
{
send_sig_all(SIGKILL);
- console_loglevel = 8;
+ next_log_level = 8;
}
static struct sysrq_key_op sysrq_kill_op = {
.handler = sysrq_handle_kill,
@@ -371,12 +372,11 @@ void __sysrq_put_key_op (int key, struct
void __handle_sysrq(int key, struct pt_regs *pt_regs, struct tty_struct *tty, int check_mask)
{
struct sysrq_key_op *op_p;
- int orig_log_level;
int i, j;
unsigned long flags;

spin_lock_irqsave(&sysrq_key_table_lock, flags);
- orig_log_level = console_loglevel;
+ next_log_level = console_loglevel;
console_loglevel = 7;
printk(KERN_INFO "SysRq : ");

@@ -387,8 +387,10 @@ void __handle_sysrq(int key, struct pt_r
if (!check_mask || sysrq_enabled == 1 ||
(sysrq_enabled & op_p->enable_mask)) {
printk ("%s\n", op_p->action_msg);
- console_loglevel = orig_log_level;
+ /* handlers may change console_loglevel,
+ * but now they do this by setting <next_log_level> */
op_p->handler(key, pt_regs, tty);
+ console_loglevel = next_log_level;
}
else
printk("This sysrq operation is disabled.\n");
@@ -402,7 +404,7 @@ void __handle_sysrq(int key, struct pt_r
printk ("%s ", sysrq_key_table[i]->help_msg);
}
printk ("\n");
- console_loglevel = orig_log_level;
+ console_loglevel = next_log_level;
}
spin_unlock_irqrestore(&sysrq_key_table_lock, flags);
}