diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/sysrq.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c index 1ade193c9128..9e9bad8bdcf4 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 | ||
200 | static DEFINE_SPINLOCK(show_lock); | ||
201 | |||
202 | static 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 | |||
216 | static void sysrq_showregs_othercpus(struct work_struct *dummy) | ||
217 | { | ||
218 | smp_call_function(showacpu, NULL, 0, 0); | ||
219 | } | ||
220 | |||
221 | static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); | ||
222 | |||
223 | static 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 | |||
233 | static 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 | |||
199 | static void sysrq_handle_showregs(int key, struct tty_struct *tty) | 241 | static 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 */ |