All of lore.kernel.org
 help / color / mirror / Atom feed
From: Nicholas Piggin <npiggin@gmail.com>
To: linuxppc-dev@lists.ozlabs.org
Cc: Nicholas Piggin <npiggin@gmail.com>,
	"Gautham R . Shenoy" <ego@linux.vnet.ibm.com>,
	"Shreyas B . Prabhu" <shreyas@linux.vnet.ibm.com>
Subject: [PATCH 02/14] powerpc/64s: idle hotplug lazy-irq simplification
Date: Mon, 12 Jun 2017 09:58:23 +1000	[thread overview]
Message-ID: <20170611235835.7400-3-npiggin@gmail.com> (raw)
In-Reply-To: <20170611235835.7400-1-npiggin@gmail.com>

Rather than concern ourselves with any soft-mask logic in the CPU
hotplug handler, just hard disable interrupts. This ensures there
are no lazy-irqs pending, which means we can call directly to idle
instruction in order to sleep.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/platforms/powernv/idle.c | 23 +++++++++++++++--------
 arch/powerpc/platforms/powernv/smp.c  | 29 ++++++++++++++---------------
 2 files changed, 29 insertions(+), 23 deletions(-)

diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c
index f875879ff1eb..f188d84d9c59 100644
--- a/arch/powerpc/platforms/powernv/idle.c
+++ b/arch/powerpc/platforms/powernv/idle.c
@@ -352,25 +352,31 @@ void power9_idle(void)
 /*
  * pnv_cpu_offline: A function that puts the CPU into the deepest
  * available platform idle state on a CPU-Offline.
+ * interrupts hard disabled and no lazy irq pending.
  */
 unsigned long pnv_cpu_offline(unsigned int cpu)
 {
 	unsigned long srr1;
-
 	u32 idle_states = pnv_get_supported_cpuidle_states();
 
+	ppc64_runlatch_off();
+
 	if (cpu_has_feature(CPU_FTR_ARCH_300) && deepest_stop_found) {
-		srr1 = __power9_idle_type(pnv_deepest_stop_psscr_val,
-					pnv_deepest_stop_psscr_mask);
+		unsigned long psscr;
+
+		psscr = mfspr(SPRN_PSSCR);
+		psscr = (psscr & ~pnv_deepest_stop_psscr_mask) |
+						pnv_deepest_stop_psscr_val;
+		srr1 = power9_idle_stop(psscr);
+
 	} else if (idle_states & OPAL_PM_WINKLE_ENABLED) {
-		srr1 = __power7_idle_type(PNV_THREAD_WINKLE);
+		srr1 = power7_idle_insn(PNV_THREAD_WINKLE);
 	} else if ((idle_states & OPAL_PM_SLEEP_ENABLED) ||
 		   (idle_states & OPAL_PM_SLEEP_ENABLED_ER1)) {
-		srr1 = __power7_idle_type(PNV_THREAD_SLEEP);
+		srr1 = power7_idle_insn(PNV_THREAD_SLEEP);
 	} else if (idle_states & OPAL_PM_NAP_ENABLED) {
-		srr1 = __power7_idle_type(PNV_THREAD_NAP);
+		srr1 = power7_idle_insn(PNV_THREAD_NAP);
 	} else {
-		ppc64_runlatch_off();
 		/* This is the fallback method. We emulate snooze */
 		while (!generic_check_cpu_restart(cpu)) {
 			HMT_low();
@@ -378,9 +384,10 @@ unsigned long pnv_cpu_offline(unsigned int cpu)
 		}
 		srr1 = 0;
 		HMT_medium();
-		ppc64_runlatch_on();
 	}
 
+	ppc64_runlatch_on();
+
 	return srr1;
 }
 #endif
diff --git a/arch/powerpc/platforms/powernv/smp.c b/arch/powerpc/platforms/powernv/smp.c
index f8752795decf..c04c87adad94 100644
--- a/arch/powerpc/platforms/powernv/smp.c
+++ b/arch/powerpc/platforms/powernv/smp.c
@@ -144,7 +144,14 @@ static void pnv_smp_cpu_kill_self(void)
 	unsigned long srr1, wmask;
 
 	/* Standard hot unplug procedure */
-	local_irq_disable();
+	/*
+	 * This hard disables local interurpts, ensuring we have no lazy
+	 * irqs pending.
+	 */
+	WARN_ON(irqs_disabled());
+	hard_irq_disable();
+	WARN_ON(lazy_irq_pending());
+
 	idle_task_exit();
 	current->active_mm = NULL; /* for sanity */
 	cpu = smp_processor_id();
@@ -162,16 +169,6 @@ static void pnv_smp_cpu_kill_self(void)
 	 */
 	mtspr(SPRN_LPCR, mfspr(SPRN_LPCR) & ~(u64)LPCR_PECE1);
 
-	/*
-	 * Hard-disable interrupts, and then clear irq_happened flags
-	 * that we can safely ignore while off-line, since they
-	 * are for things for which we do no processing when off-line
-	 * (or in the case of HMI, all the processing we need to do
-	 * is done in lower-level real-mode code).
-	 */
-	hard_irq_disable();
-	local_paca->irq_happened &= ~(PACA_IRQ_DEC | PACA_IRQ_HMI);
-
 	while (!generic_check_cpu_restart(cpu)) {
 		/*
 		 * Clear IPI flag, since we don't handle IPIs while
@@ -184,6 +181,8 @@ static void pnv_smp_cpu_kill_self(void)
 
 		srr1 = pnv_cpu_offline(cpu);
 
+		WARN_ON(lazy_irq_pending());
+
 		/*
 		 * If the SRR1 value indicates that we woke up due to
 		 * an external interrupt, then clear the interrupt.
@@ -196,8 +195,7 @@ static void pnv_smp_cpu_kill_self(void)
 		 * contains 0.
 		 */
 		if (((srr1 & wmask) == SRR1_WAKEEE) ||
-		    ((srr1 & wmask) == SRR1_WAKEHVI) ||
-		    (local_paca->irq_happened & PACA_IRQ_EE)) {
+		    ((srr1 & wmask) == SRR1_WAKEHVI)) {
 			if (cpu_has_feature(CPU_FTR_ARCH_300)) {
 				if (xive_enabled())
 					xive_flush_interrupt();
@@ -209,14 +207,15 @@ static void pnv_smp_cpu_kill_self(void)
 			unsigned long msg = PPC_DBELL_TYPE(PPC_DBELL_SERVER);
 			asm volatile(PPC_MSGCLR(%0) : : "r" (msg));
 		}
-		local_paca->irq_happened &= ~(PACA_IRQ_EE | PACA_IRQ_DBELL);
 		smp_mb();
 
 		if (cpu_core_split_required())
 			continue;
 
 		if (srr1 && !generic_check_cpu_restart(cpu))
-			DBG("CPU%d Unexpected exit while offline !\n", cpu);
+			DBG("CPU%d Unexpected exit while offline srr1=%lx!\n",
+					cpu, srr1);
+
 	}
 
 	/* Re-enable decrementer interrupts */
-- 
2.11.0

  parent reply	other threads:[~2017-06-12  0:00 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-06-11 23:58 [PATCH 00/14 v2] idle performance improvements Nicholas Piggin
2017-06-11 23:58 ` [PATCH 01/14] powerpc/64s: idle move soft interrupt mask logic into C code Nicholas Piggin
2017-06-12  8:37   ` Gautham R Shenoy
2017-06-12 14:46     ` Nicholas Piggin
2017-06-13  4:28       ` Gautham R Shenoy
2017-06-11 23:58 ` Nicholas Piggin [this message]
2017-06-11 23:58 ` [PATCH 03/14] powerpc/64s: idle provide a default idle for POWER9 Nicholas Piggin
2017-06-12  8:53   ` Gautham R Shenoy
2017-06-12 14:46     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 04/14] powerpc/64s: idle process interrupts from system reset wakeup Nicholas Piggin
2017-06-12  9:41   ` Gautham R Shenoy
2017-06-12 14:51     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 05/14] powerpc/64s: msgclr when handling doorbell exceptions Nicholas Piggin
2017-06-12 14:38   ` Gautham R Shenoy
2017-06-11 23:58 ` [PATCH 06/14] powerpc/64s: interrupt replay balance the return branch predictor Nicholas Piggin
2017-06-12 14:41   ` Gautham R Shenoy
2017-06-13  9:51   ` Michael Ellerman
2017-06-13 11:09     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 07/14] powerpc/64s: idle branch to handler with virtual mode offset Nicholas Piggin
2017-06-11 23:58 ` [PATCH 08/14] powerpc/64s: idle avoid SRR usage in idle sleep/wake paths Nicholas Piggin
2017-06-13 10:25   ` Gautham R Shenoy
2017-06-13 10:45     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 09/14] powerpc/64s: idle hmi wakeup is unlikely Nicholas Piggin
2017-06-12 15:03   ` Gautham R Shenoy
2017-06-11 23:58 ` [PATCH 10/14] powerpc/64s: cpuidle set polling before enabling irqs Nicholas Piggin
2017-06-12 15:10   ` Gautham R Shenoy
2017-06-12 15:20     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 11/14] powerpc/64s: cpuidle read mostly for common globals Nicholas Piggin
2017-06-12 15:30   ` Gautham R Shenoy
2017-06-12 17:50     ` Vaidyanathan Srinivasan
2017-06-11 23:58 ` [PATCH 12/14] powerpc/64s: cpuidle no memory barrier after break from idle Nicholas Piggin
2017-06-12 17:48   ` Vaidyanathan Srinivasan
2017-06-13 12:47     ` Nicholas Piggin
2017-06-11 23:58 ` [PATCH 13/14] powerpc/64: runlatch CTRL[RUN] set optimisation Nicholas Piggin
2017-06-12 17:11   ` Vaidyanathan Srinivasan
2017-06-13 10:04     ` Michael Ellerman
2017-06-13 11:56       ` Nicholas Piggin
2017-06-13 13:45       ` Benjamin Herrenschmidt
2017-06-14  3:34         ` Michael Ellerman
2017-06-11 23:58 ` [PATCH 14/14] powerpc/64s: idle runlatch switch is done with MSR[EE]=0 Nicholas Piggin
2017-06-12 17:00   ` Vaidyanathan Srinivasan
  -- strict thread matches above, loose matches on Subject: below --
2017-06-08 15:50 [PATCH 00/14] idle performance improvements Nicholas Piggin
2017-06-08 15:51 ` [PATCH 02/14] powerpc/64s: idle hotplug lazy-irq simplification Nicholas Piggin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170611235835.7400-3-npiggin@gmail.com \
    --to=npiggin@gmail.com \
    --cc=ego@linux.vnet.ibm.com \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=shreyas@linux.vnet.ibm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.