powerpc/pseries: correctly track irq state in default idle
diff mbox series

Message ID 20190910225244.25056-1-nathanl@linux.ibm.com
State New
Headers show
  • powerpc/pseries: correctly track irq state in default idle
Related show


Context Check Description
snowpatch_ozlabs/checkpatch success total: 0 errors, 0 warnings, 0 checks, 9 lines checked
snowpatch_ozlabs/build-pmac32 success Build succeeded
snowpatch_ozlabs/build-ppc64e success Build succeeded
snowpatch_ozlabs/build-ppc64be success Build succeeded
snowpatch_ozlabs/build-ppc64le success Build succeeded
snowpatch_ozlabs/apply_patch success Successfully applied on branch next (c317052c95bef1f977b023158e5aa929215f443d)

Commit Message

Nathan Lynch Sept. 10, 2019, 10:52 p.m. UTC
prep_irq_for_idle() is intended to be called before entering
H_CEDE (and it is used by the pseries cpuidle driver). However the
default pseries idle routine does not call it, leading to mismanaged
lazy irq state when the cpuidle driver isn't in use. Manifestations of
this include:

* Dropped IPIs in the time immediately after a cpu comes
  online (before it has installed the cpuidle handler), making the
  online operation block indefinitely waiting for the new cpu to

* Hitting this WARN_ON in arch_local_irq_restore():
	 * We should already be hard disabled here. We had bugs
	 * where that wasn't the case so let's dbl check it and
	 * warn if we are wrong. Only do that when IRQ tracing
	 * is enabled as mfmsr() can be costly.
	if (WARN_ON_ONCE(mfmsr() & MSR_EE))

Call prep_irq_for_idle() from pseries_lpar_idle() and honor its

Fixes: 363edbe2614a ("powerpc: Default arch idle could cede processor on pseries")
Signed-off-by: Nathan Lynch <nathanl@linux.ibm.com>
 arch/powerpc/platforms/pseries/setup.c | 3 +++
 1 file changed, 3 insertions(+)

diff mbox series

diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index b955d54628ff..f8adcd0e4589 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -321,6 +321,9 @@  static void pseries_lpar_idle(void)
 	 * low power mode by ceding processor to hypervisor
+	if (!prep_irq_for_idle())
+		return;
 	/* Indicate to hypervisor that we are idle. */
 	get_lppaca()->idle = 1;