aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/platform
diff options
context:
space:
mode:
authorMike Travis <travis@sgi.com>2013-09-23 17:25:02 -0400
committerIngo Molnar <mingo@kernel.org>2013-09-24 03:02:03 -0400
commit3c121d9a21dc16ef030ad6ca3ebb159b5726fab9 (patch)
treee443837b79530e506b4591ab3e1bdd68fe643ec0 /arch/x86/platform
parent0d12ef0c900078cc1f4e78dff2245521aa5d0c89 (diff)
x86/UV: Add summary of cpu activity to UV NMI handler
The standard NMI handler dumps the states of all the cpus. This includes a full register dump and stack trace. This can be way more information than what is needed. This patch adds a "summary" dump that is basically a form of the "ps" command. It includes the symbolic IP address as well as the command field and basic process information. It is enabled when the nmi action is changed to "ips". Signed-off-by: Mike Travis <travis@sgi.com> Reviewed-by: Dimitri Sivanich <sivanich@sgi.com> Reviewed-by: Hedi Berriche <hedi@sgi.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@ghostprotocols.net> Cc: Jason Wessel <jason.wessel@windriver.com> Link: http://lkml.kernel.org/r/20130923212500.507922930@asylum.americas.sgi.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86/platform')
-rw-r--r--arch/x86/platform/uv/uv_nmi.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/arch/x86/platform/uv/uv_nmi.c b/arch/x86/platform/uv/uv_nmi.c
index fb02ea7d2b2d..4efcde1b9d54 100644
--- a/arch/x86/platform/uv/uv_nmi.c
+++ b/arch/x86/platform/uv/uv_nmi.c
@@ -139,6 +139,19 @@ module_param_named(wait_count, uv_nmi_wait_count, int, 0644);
139static int uv_nmi_retry_count = 500; 139static int uv_nmi_retry_count = 500;
140module_param_named(retry_count, uv_nmi_retry_count, int, 0644); 140module_param_named(retry_count, uv_nmi_retry_count, int, 0644);
141 141
142/*
143 * Valid NMI Actions:
144 * "dump" - dump process stack for each cpu
145 * "ips" - dump IP info for each cpu
146 */
147static char uv_nmi_action[8] = "dump";
148module_param_string(action, uv_nmi_action, sizeof(uv_nmi_action), 0644);
149
150static inline bool uv_nmi_action_is(const char *action)
151{
152 return (strncmp(uv_nmi_action, action, strlen(action)) == 0);
153}
154
142/* Setup which NMI support is present in system */ 155/* Setup which NMI support is present in system */
143static void uv_nmi_setup_mmrs(void) 156static void uv_nmi_setup_mmrs(void)
144{ 157{
@@ -367,13 +380,38 @@ static void uv_nmi_wait(int master)
367 atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus()); 380 atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus());
368} 381}
369 382
383static void uv_nmi_dump_cpu_ip_hdr(void)
384{
385 printk(KERN_DEFAULT
386 "\nUV: %4s %6s %-32s %s (Note: PID 0 not listed)\n",
387 "CPU", "PID", "COMMAND", "IP");
388}
389
390static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs)
391{
392 printk(KERN_DEFAULT "UV: %4d %6d %-32.32s ",
393 cpu, current->pid, current->comm);
394
395 printk_address(regs->ip, 1);
396}
397
370/* Dump this cpu's state */ 398/* Dump this cpu's state */
371static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs) 399static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs)
372{ 400{
373 const char *dots = " ................................. "; 401 const char *dots = " ................................. ";
374 402
375 printk(KERN_DEFAULT "UV:%sNMI process trace for CPU %d\n", dots, cpu); 403 if (uv_nmi_action_is("ips")) {
376 show_regs(regs); 404 if (cpu == 0)
405 uv_nmi_dump_cpu_ip_hdr();
406
407 if (current->pid != 0)
408 uv_nmi_dump_cpu_ip(cpu, regs);
409
410 } else if (uv_nmi_action_is("dump")) {
411 printk(KERN_DEFAULT
412 "UV:%sNMI process trace for CPU %d\n", dots, cpu);
413 show_regs(regs);
414 }
377 atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE); 415 atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE);
378} 416}
379 417
@@ -420,7 +458,8 @@ static void uv_nmi_dump_state(int cpu, struct pt_regs *regs, int master)
420 int ignored = 0; 458 int ignored = 0;
421 int saved_console_loglevel = console_loglevel; 459 int saved_console_loglevel = console_loglevel;
422 460
423 pr_alert("UV: tracing processes for %d CPUs from CPU %d\n", 461 pr_alert("UV: tracing %s for %d CPUs from CPU %d\n",
462 uv_nmi_action_is("ips") ? "IPs" : "processes",
424 atomic_read(&uv_nmi_cpus_in_nmi), cpu); 463 atomic_read(&uv_nmi_cpus_in_nmi), cpu);
425 464
426 console_loglevel = uv_nmi_loglevel; 465 console_loglevel = uv_nmi_loglevel;
@@ -482,7 +521,8 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
482 uv_nmi_wait(master); 521 uv_nmi_wait(master);
483 522
484 /* Dump state of each cpu */ 523 /* Dump state of each cpu */
485 uv_nmi_dump_state(cpu, regs, master); 524 if (uv_nmi_action_is("ips") || uv_nmi_action_is("dump"))
525 uv_nmi_dump_state(cpu, regs, master);
486 526
487 /* Clear per_cpu "in nmi" flag */ 527 /* Clear per_cpu "in nmi" flag */
488 atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_OUT); 528 atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_OUT);