powerpc/watchdog: Make use of watchdog_nmi_probe()
The rework of the core hotplug code triggers the WARN_ON in start_wd_cpu() on powerpc because it is called multiple times for the boot CPU. The first call is via: start_wd_on_cpu+0x80/0x2f0 watchdog_nmi_reconfigure+0x124/0x170 softlockup_reconfigure_threads+0x110/0x130 lockup_detector_init+0xbc/0xe0 kernel_init_freeable+0x18c/0x37c kernel_init+0x2c/0x160 ret_from_kernel_thread+0x5c/0xbc And then again via the CPU hotplug registration: start_wd_on_cpu+0x80/0x2f0 cpuhp_invoke_callback+0x194/0x620 cpuhp_thread_fun+0x7c/0x1b0 smpboot_thread_fn+0x290/0x2a0 kthread+0x168/0x1b0 ret_from_kernel_thread+0x5c/0xbc This can be avoided by setting up the cpu hotplug state with nocalls and move the initialization to the watchdog_nmi_probe() function. That initializes the hotplug callbacks without invoking the callback and the following core initialization function then configures the watchdog for the online CPUs (in this case CPU0) via softlockup_reconfigure_threads(). Reported-and-tested-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Acked-by: Michael Ellerman <mpe@ellerman.id.au> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: linuxppc-dev@lists.ozlabs.org
This commit is contained in:
parent
e31d6883f2
commit
34ddaa3e5c
@ -373,22 +373,21 @@ void watchdog_nmi_start(void)
|
||||
}
|
||||
|
||||
/*
|
||||
* This runs after lockup_detector_init() which sets up watchdog_cpumask.
|
||||
* Invoked from core watchdog init.
|
||||
*/
|
||||
static int __init powerpc_watchdog_init(void)
|
||||
int __init watchdog_nmi_probe(void)
|
||||
{
|
||||
int err;
|
||||
|
||||
watchdog_calc_timeouts();
|
||||
|
||||
err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/watchdog:online",
|
||||
start_wd_on_cpu, stop_wd_on_cpu);
|
||||
if (err < 0)
|
||||
err = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
|
||||
"powerpc/watchdog:online",
|
||||
start_wd_on_cpu, stop_wd_on_cpu);
|
||||
if (err < 0) {
|
||||
pr_warn("Watchdog could not be initialized");
|
||||
|
||||
return err;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(powerpc_watchdog_init);
|
||||
|
||||
static void handle_backtrace_ipi(struct pt_regs *regs)
|
||||
{
|
||||
|
@ -111,6 +111,7 @@ static inline int hardlockup_detector_perf_init(void) { return 0; }
|
||||
|
||||
void watchdog_nmi_stop(void);
|
||||
void watchdog_nmi_start(void);
|
||||
int watchdog_nmi_probe(void);
|
||||
|
||||
/**
|
||||
* touch_nmi_watchdog - restart NMI watchdog timeout.
|
||||
|
@ -608,7 +608,6 @@ static inline int watchdog_park_threads(void) { return 0; }
|
||||
static inline void watchdog_unpark_threads(void) { }
|
||||
static inline int watchdog_enable_all_cpus(void) { return 0; }
|
||||
static inline void watchdog_disable_all_cpus(void) { }
|
||||
static inline void softlockup_init_threads(void) { }
|
||||
static void softlockup_reconfigure_threads(void)
|
||||
{
|
||||
cpus_read_lock();
|
||||
@ -617,6 +616,10 @@ static void softlockup_reconfigure_threads(void)
|
||||
watchdog_nmi_start();
|
||||
cpus_read_unlock();
|
||||
}
|
||||
static inline void softlockup_init_threads(void)
|
||||
{
|
||||
softlockup_reconfigure_threads();
|
||||
}
|
||||
#endif /* !CONFIG_SOFTLOCKUP_DETECTOR */
|
||||
|
||||
static void __lockup_detector_cleanup(void)
|
||||
|
Loading…
Reference in New Issue
Block a user