mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-19 05:04:20 +00:00
powerpc: allow soft-NMI watchdog to cover timer interrupts with large decrementers
Large decrementers (e.g., POWER9) can take a very long time to wrap, so when the timer iterrupt handler sets the decrementer to max so as to avoid taking another decrementer interrupt when hard enabling interrupts before running timers, it effectively disables the soft NMI coverage for timer interrupts. Fix this by using the traditional 31-bit value instead, which wraps after a few seconds. masked interrupt code does the same thing, and in normal operation neither of these paths would ever wrap even the 31 bit value. Note: the SMP watchdog should catch timer interrupt lockups, but it is preferable for the local soft-NMI to catch them, mainly to avoid the IPI. Signed-off-by: Nicholas Piggin <npiggin@gmail.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
3f984620f9
commit
a7cba02dec
1 changed files with 13 additions and 6 deletions
|
@ -578,22 +578,29 @@ void timer_interrupt(struct pt_regs *regs)
|
|||
struct pt_regs *old_regs;
|
||||
u64 now;
|
||||
|
||||
/* Ensure a positive value is written to the decrementer, or else
|
||||
* some CPUs will continue to take decrementer exceptions.
|
||||
*/
|
||||
set_dec(decrementer_max);
|
||||
|
||||
/* Some implementations of hotplug will get timer interrupts while
|
||||
* offline, just ignore these and we also need to set
|
||||
* decrementers_next_tb as MAX to make sure __check_irq_replay
|
||||
* don't replay timer interrupt when return, otherwise we'll trap
|
||||
* here infinitely :(
|
||||
*/
|
||||
if (!cpu_online(smp_processor_id())) {
|
||||
if (unlikely(!cpu_online(smp_processor_id()))) {
|
||||
*next_tb = ~(u64)0;
|
||||
set_dec(decrementer_max);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Ensure a positive value is written to the decrementer, or else
|
||||
* some CPUs will continue to take decrementer exceptions. When the
|
||||
* PPC_WATCHDOG (decrementer based) is configured, keep this at most
|
||||
* 31 bits, which is about 4 seconds on most systems, which gives
|
||||
* the watchdog a chance of catching timer interrupt hard lockups.
|
||||
*/
|
||||
if (IS_ENABLED(CONFIG_PPC_WATCHDOG))
|
||||
set_dec(0x7fffffff);
|
||||
else
|
||||
set_dec(decrementer_max);
|
||||
|
||||
/* Conditionally hard-enable interrupts now that the DEC has been
|
||||
* bumped to its maximum value
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue