Skip to content

Commit 827556e

Browse files
committed
Revert "powerpc/64s/interrupt: Don't enable MSR[EE] in irq handlers unless perf is in use"
This reverts commit 0faf20a. This made all our ppc64le builds hard lockup / hang. Reported upstream. Link: https://lore.kernel.org/linuxppc-dev/CANiq72n_FmDx=r-o9J8gYc6LpwRL5EGmhM6Xzwv27Xc7h1TNDw@mail.gmail.com/ Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
1 parent 4e1f84f commit 827556e

File tree

4 files changed

+27
-67
lines changed

4 files changed

+27
-67
lines changed

arch/powerpc/include/asm/hw_irq.h

Lines changed: 10 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -345,54 +345,17 @@ static inline bool lazy_irq_pending_nocheck(void)
345345
bool power_pmu_wants_prompt_pmi(void);
346346

347347
/*
348-
* This is called by asynchronous interrupts to check whether to
349-
* conditionally re-enable hard interrupts after having cleared
350-
* the source of the interrupt. They are kept disabled if there
351-
* is a different soft-masked interrupt pending that requires hard
352-
* masking.
348+
* This is called by asynchronous interrupts to conditionally
349+
* re-enable hard interrupts after having cleared the source
350+
* of the interrupt. They are kept disabled if there is a different
351+
* soft-masked interrupt pending that requires hard masking.
353352
*/
354-
static inline bool should_hard_irq_enable(void)
353+
static inline void may_hard_irq_enable(void)
355354
{
356-
#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
357-
WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
358-
WARN_ON(mfmsr() & MSR_EE);
359-
#endif
360-
#ifdef CONFIG_PERF_EVENTS
361-
/*
362-
* If the PMU is not running, there is not much reason to enable
363-
* MSR[EE] in irq handlers because any interrupts would just be
364-
* soft-masked.
365-
*
366-
* TODO: Add test for 64e
367-
*/
368-
if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !power_pmu_wants_prompt_pmi())
369-
return false;
370-
371-
if (get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK)
372-
return false;
373-
374-
return true;
375-
#else
376-
return false;
377-
#endif
378-
}
379-
380-
/*
381-
* Do the hard enabling, only call this if should_hard_irq_enable is true.
382-
*/
383-
static inline void do_hard_irq_enable(void)
384-
{
385-
#ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG
386-
WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
387-
WARN_ON(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK);
388-
WARN_ON(mfmsr() & MSR_EE);
389-
#endif
390-
/*
391-
* This allows PMI interrupts (and watchdog soft-NMIs) through.
392-
* There is no other reason to enable this way.
393-
*/
394-
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
395-
__hard_irq_enable();
355+
if (!(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK)) {
356+
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
357+
__hard_irq_enable();
358+
}
396359
}
397360

398361
static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
@@ -473,7 +436,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
473436
return !(regs->msr & MSR_EE);
474437
}
475438

476-
static inline bool should_hard_irq_enable(void)
439+
static inline bool may_hard_irq_enable(void)
477440
{
478441
return false;
479442
}

arch/powerpc/kernel/dbell.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
2727

2828
ppc_msgsync();
2929

30-
if (should_hard_irq_enable())
31-
do_hard_irq_enable();
30+
may_hard_irq_enable();
3231

3332
kvmppc_clear_host_ipi(smp_processor_id());
3433
__this_cpu_inc(irq_stat.doorbell_irqs);

arch/powerpc/kernel/irq.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -745,8 +745,7 @@ void __do_irq(struct pt_regs *regs)
745745
irq = ppc_md.get_irq();
746746

747747
/* We can hard enable interrupts now to allow perf interrupts */
748-
if (should_hard_irq_enable())
749-
do_hard_irq_enable();
748+
may_hard_irq_enable();
750749

751750
/* And finally process it */
752751
if (unlikely(!irq))

arch/powerpc/kernel/time.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -609,23 +609,22 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
609609
return;
610610
}
611611

612-
/* Conditionally hard-enable interrupts. */
613-
if (should_hard_irq_enable()) {
614-
/*
615-
* Ensure a positive value is written to the decrementer, or
616-
* else some CPUs will continue to take decrementer exceptions.
617-
* When the PPC_WATCHDOG (decrementer based) is configured,
618-
* keep this at most 31 bits, which is about 4 seconds on most
619-
* systems, which gives the watchdog a chance of catching timer
620-
* interrupt hard lockups.
621-
*/
622-
if (IS_ENABLED(CONFIG_PPC_WATCHDOG))
623-
set_dec(0x7fffffff);
624-
else
625-
set_dec(decrementer_max);
612+
/* Ensure a positive value is written to the decrementer, or else
613+
* some CPUs will continue to take decrementer exceptions. When the
614+
* PPC_WATCHDOG (decrementer based) is configured, keep this at most
615+
* 31 bits, which is about 4 seconds on most systems, which gives
616+
* the watchdog a chance of catching timer interrupt hard lockups.
617+
*/
618+
if (IS_ENABLED(CONFIG_PPC_WATCHDOG))
619+
set_dec(0x7fffffff);
620+
else
621+
set_dec(decrementer_max);
622+
623+
/* Conditionally hard-enable interrupts now that the DEC has been
624+
* bumped to its maximum value
625+
*/
626+
may_hard_irq_enable();
626627

627-
do_hard_irq_enable();
628-
}
629628

630629
#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_PMAC)
631630
if (atomic_read(&ppc_n_lost_interrupts) != 0)

0 commit comments

Comments
 (0)