Skip to content

Commit

Permalink
sparc: implement watchdog_nmi_enable and watchdog_nmi_disable
Browse files Browse the repository at this point in the history
Implement functions watchdog_nmi_enable and watchdog_nmi_disable to
enable/disable nmi watchdog.  Sparc uses arch specific nmi watchdog
handler.  Currently, we do not have a way to enable/disable nmi watchdog
dynamically.  With these patches we can enable or disable arch specific
nmi watchdogs using proc or sysctl interface.

Example commands.
To enable: echo 1 >  /proc/sys/kernel/nmi_watchdog
To disable: echo 0 >  /proc/sys/kernel/nmi_watchdog

It can also achieved using the sysctl parameter kernel.nmi_watchdog

Link: http://lkml.kernel.org/r/1478034826-43888-4-git-send-email-babu.moger@oracle.com
Signed-off-by: Babu Moger <babu.moger@oracle.com>
Acked-by: Don Zickus <dzickus@redhat.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Kosina <jkosina@suse.cz>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Yaowei Bai <baiyaowei@cmss.chinamobile.com>
Cc: Aaron Tomlin <atomlin@redhat.com>
Cc: Ulrich Obergfell <uobergfe@redhat.com>
Cc: Tejun Heo <tj@kernel.org>
Cc: Hidehiro Kawai <hidehiro.kawai.ez@hitachi.com>
Cc: Josh Hunt <johunt@akamai.com>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Babu Moger authored and torvalds committed Dec 15, 2016
1 parent 73ce051 commit 7a5c8b5
Showing 1 changed file with 43 additions and 1 deletion.
44 changes: 43 additions & 1 deletion arch/sparc/kernel/nmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ static int panic_on_timeout;
*/
atomic_t nmi_active = ATOMIC_INIT(0); /* oprofile uses this */
EXPORT_SYMBOL(nmi_active);

static int nmi_init_done;
static unsigned int nmi_hz = HZ;
static DEFINE_PER_CPU(short, wd_enabled);
static int endflag __initdata;
Expand Down Expand Up @@ -153,6 +153,8 @@ static void report_broken_nmi(int cpu, int *prev_nmi_count)

void stop_nmi_watchdog(void *unused)
{
if (!__this_cpu_read(wd_enabled))
return;
pcr_ops->write_pcr(0, pcr_ops->pcr_nmi_disable);
__this_cpu_write(wd_enabled, 0);
atomic_dec(&nmi_active);
Expand Down Expand Up @@ -207,6 +209,9 @@ static int __init check_nmi_watchdog(void)

void start_nmi_watchdog(void *unused)
{
if (__this_cpu_read(wd_enabled))
return;

__this_cpu_write(wd_enabled, 1);
atomic_inc(&nmi_active);

Expand Down Expand Up @@ -259,6 +264,8 @@ int __init nmi_init(void)
}
}

nmi_init_done = 1;

return err;
}

Expand All @@ -270,3 +277,38 @@ static int __init setup_nmi_watchdog(char *str)
return 0;
}
__setup("nmi_watchdog=", setup_nmi_watchdog);

/*
* sparc specific NMI watchdog enable function.
* Enables watchdog if it is not enabled already.
*/
int watchdog_nmi_enable(unsigned int cpu)
{
if (atomic_read(&nmi_active) == -1) {
pr_warn("NMI watchdog cannot be enabled or disabled\n");
return -1;
}

/*
* watchdog thread could start even before nmi_init is called.
* Just Return in that case. Let nmi_init finish the init
* process first.
*/
if (!nmi_init_done)
return 0;

smp_call_function_single(cpu, start_nmi_watchdog, NULL, 1);

return 0;
}
/*
* sparc specific NMI watchdog disable function.
* Disables watchdog if it is not disabled already.
*/
void watchdog_nmi_disable(unsigned int cpu)
{
if (atomic_read(&nmi_active) == -1)
pr_warn_once("NMI watchdog cannot be enabled or disabled\n");
else
smp_call_function_single(cpu, stop_nmi_watchdog, NULL, 1);
}

0 comments on commit 7a5c8b5

Please sign in to comment.