aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRik van Riel <riel@redhat.com>2008-04-29 03:59:21 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:03 -0400
commit5045bcae0fb466a1dbb6af0036e56901fd7aafb7 (patch)
tree3ad84c429ff74ec0f541cc7cf05ab3788114022f
parent6e574195b75543bc6a6240306313988b1952470c (diff)
sysrq: add show-backtrace-on-all-cpus function
SysRQ-P is not always useful on SMP systems, since it usually ends up showing the backtrace of a CPU that is doing just fine, instead of the backtrace of the CPU that is having problems. This patch adds SysRQ show-all-cpus(L), which shows the backtrace of every active CPU in the system. It skips idle CPUs because some SMP systems are just too large and we already know what the backtrace of the idle task looks like. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: Rik van Riel <riel@redhat.com> Randy Dunlap <randy.dunlap@oracle.com> Cc: <lwoodman@redhat.com> Cc: Ingo Molnar <mingo@elte.hu> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/sysrq.txt2
-rw-r--r--drivers/char/sysrq.c46
2 files changed, 48 insertions, 0 deletions
diff --git a/Documentation/sysrq.txt b/Documentation/sysrq.txt
index 10c8f6922ef..5ce0952aa06 100644
--- a/Documentation/sysrq.txt
+++ b/Documentation/sysrq.txt
@@ -85,6 +85,8 @@ On all - write a character to /proc/sysrq-trigger. e.g.:
85'k' - Secure Access Key (SAK) Kills all programs on the current virtual 85'k' - Secure Access Key (SAK) Kills all programs on the current virtual
86 console. NOTE: See important comments below in SAK section. 86 console. NOTE: See important comments below in SAK section.
87 87
88'l' - Shows a stack backtrace for all active CPUs.
89
88'm' - Will dump current memory info to your console. 90'm' - Will dump current memory info to your console.
89 91
90'n' - Used to make RT tasks nice-able 92'n' - Used to make RT tasks nice-able
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 1ade193c912..9e9bad8bdcf 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -196,6 +196,48 @@ static struct sysrq_key_op sysrq_showlocks_op = {
196#define sysrq_showlocks_op (*(struct sysrq_key_op *)0) 196#define sysrq_showlocks_op (*(struct sysrq_key_op *)0)
197#endif 197#endif
198 198
199#ifdef CONFIG_SMP
200static DEFINE_SPINLOCK(show_lock);
201
202static void showacpu(void *dummy)
203{
204 unsigned long flags;
205
206 /* Idle CPUs have no interesting backtrace. */
207 if (idle_cpu(smp_processor_id()))
208 return;
209
210 spin_lock_irqsave(&show_lock, flags);
211 printk(KERN_INFO "CPU%d:\n", smp_processor_id());
212 show_stack(NULL, NULL);
213 spin_unlock_irqrestore(&show_lock, flags);
214}
215
216static void sysrq_showregs_othercpus(struct work_struct *dummy)
217{
218 smp_call_function(showacpu, NULL, 0, 0);
219}
220
221static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
222
223static void sysrq_handle_showallcpus(int key, struct tty_struct *tty)
224{
225 struct pt_regs *regs = get_irq_regs();
226 if (regs) {
227 printk(KERN_INFO "CPU%d:\n", smp_processor_id());
228 show_regs(regs);
229 }
230 schedule_work(&sysrq_showallcpus);
231}
232
233static struct sysrq_key_op sysrq_showallcpus_op = {
234 .handler = sysrq_handle_showallcpus,
235 .help_msg = "aLlcpus",
236 .action_msg = "Show backtrace of all active CPUs",
237 .enable_mask = SYSRQ_ENABLE_DUMP,
238};
239#endif
240
199static void sysrq_handle_showregs(int key, struct tty_struct *tty) 241static void sysrq_handle_showregs(int key, struct tty_struct *tty)
200{ 242{
201 struct pt_regs *regs = get_irq_regs(); 243 struct pt_regs *regs = get_irq_regs();
@@ -340,7 +382,11 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
340 &sysrq_kill_op, /* i */ 382 &sysrq_kill_op, /* i */
341 NULL, /* j */ 383 NULL, /* j */
342 &sysrq_SAK_op, /* k */ 384 &sysrq_SAK_op, /* k */
385#ifdef CONFIG_SMP
386 &sysrq_showallcpus_op, /* l */
387#else
343 NULL, /* l */ 388 NULL, /* l */
389#endif
344 &sysrq_showmem_op, /* m */ 390 &sysrq_showmem_op, /* m */
345 &sysrq_unrt_op, /* n */ 391 &sysrq_unrt_op, /* n */
346 /* o: This will often be registered as 'Off' at init time */ 392 /* o: This will often be registered as 'Off' at init time */