Skip to content

Commit

Permalink
x86/UV: Add summary of cpu activity to UV NMI handler
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Mike Travis authored and Ingo Molnar committed Sep 24, 2013
1 parent 0d12ef0 commit 3c121d9
Showing 1 changed file with 44 additions and 4 deletions.
48 changes: 44 additions & 4 deletions arch/x86/platform/uv/uv_nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,19 @@ module_param_named(wait_count, uv_nmi_wait_count, int, 0644);
static int uv_nmi_retry_count = 500;
module_param_named(retry_count, uv_nmi_retry_count, int, 0644);

/*
* Valid NMI Actions:
* "dump" - dump process stack for each cpu
* "ips" - dump IP info for each cpu
*/
static char uv_nmi_action[8] = "dump";
module_param_string(action, uv_nmi_action, sizeof(uv_nmi_action), 0644);

static inline bool uv_nmi_action_is(const char *action)
{
return (strncmp(uv_nmi_action, action, strlen(action)) == 0);
}

/* Setup which NMI support is present in system */
static void uv_nmi_setup_mmrs(void)
{
Expand Down Expand Up @@ -367,13 +380,38 @@ static void uv_nmi_wait(int master)
atomic_read(&uv_nmi_cpus_in_nmi), num_online_cpus());
}

static void uv_nmi_dump_cpu_ip_hdr(void)
{
printk(KERN_DEFAULT
"\nUV: %4s %6s %-32s %s (Note: PID 0 not listed)\n",
"CPU", "PID", "COMMAND", "IP");
}

static void uv_nmi_dump_cpu_ip(int cpu, struct pt_regs *regs)
{
printk(KERN_DEFAULT "UV: %4d %6d %-32.32s ",
cpu, current->pid, current->comm);

printk_address(regs->ip, 1);
}

/* Dump this cpu's state */
static void uv_nmi_dump_state_cpu(int cpu, struct pt_regs *regs)
{
const char *dots = " ................................. ";

printk(KERN_DEFAULT "UV:%sNMI process trace for CPU %d\n", dots, cpu);
show_regs(regs);
if (uv_nmi_action_is("ips")) {
if (cpu == 0)
uv_nmi_dump_cpu_ip_hdr();

if (current->pid != 0)
uv_nmi_dump_cpu_ip(cpu, regs);

} else if (uv_nmi_action_is("dump")) {
printk(KERN_DEFAULT
"UV:%sNMI process trace for CPU %d\n", dots, cpu);
show_regs(regs);
}
atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_DUMP_DONE);
}

Expand Down Expand Up @@ -420,7 +458,8 @@ static void uv_nmi_dump_state(int cpu, struct pt_regs *regs, int master)
int ignored = 0;
int saved_console_loglevel = console_loglevel;

pr_alert("UV: tracing processes for %d CPUs from CPU %d\n",
pr_alert("UV: tracing %s for %d CPUs from CPU %d\n",
uv_nmi_action_is("ips") ? "IPs" : "processes",
atomic_read(&uv_nmi_cpus_in_nmi), cpu);

console_loglevel = uv_nmi_loglevel;
Expand Down Expand Up @@ -482,7 +521,8 @@ int uv_handle_nmi(unsigned int reason, struct pt_regs *regs)
uv_nmi_wait(master);

/* Dump state of each cpu */
uv_nmi_dump_state(cpu, regs, master);
if (uv_nmi_action_is("ips") || uv_nmi_action_is("dump"))
uv_nmi_dump_state(cpu, regs, master);

/* Clear per_cpu "in nmi" flag */
atomic_set(&uv_cpu_nmi.state, UV_NMI_STATE_OUT);
Expand Down

0 comments on commit 3c121d9

Please sign in to comment.