All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@suse.de>
To: stable-review@kernel.org, stable@kernel.org
Cc: Len Brown <len.brown@intel.com>,
	linux-pm@lists.linux-foundation.org, x86@kernel.org,
	"H. Peter Anvin" <hpa@linux.intel.com>
Subject: [213/474] x86, hotplug: Use mwait to offline a processor, fix the legacy case
Date: Thu, 17 Mar 2011 14:24:23 -0700	[thread overview]
Message-ID: <20110317212903.394948496__15517.3490326435$1300398924$gmane$org@clark.kroah.org> (raw)
In-Reply-To: <20110317213822.GA27980@kroah.com>

2.6.33-longterm review patch.  If anyone has any objections, please let us know.

------------------
Content-Length: 4240
Lines: 156


From: H. Peter Anvin <hpa@linux.intel.com>

upstream ea53069231f9317062910d6e772cca4ce93de8c8
x86, hotplug: Use mwait to offline a processor, fix the legacy case

Here included also some small follow-on patches to the same code:

upstream a68e5c94f7d3dd64fef34dd5d97e365cae4bb42a
x86, hotplug: Move WBINVD back outside the play_dead loop

upstream ce5f68246bf2385d6174856708d0b746dc378f20
x86, hotplug: In the MWAIT case of play_dead, CLFLUSH the cache line

https://bugzilla.kernel.org/show_bug.cgi?id=5471

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 arch/x86/include/asm/processor.h |   23 ----------
 arch/x86/kernel/smpboot.c        |   85 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 84 insertions(+), 24 deletions(-)

--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -767,29 +767,6 @@ extern unsigned long		boot_option_idle_o
 extern unsigned long		idle_halt;
 extern unsigned long		idle_nomwait;
 
-/*
- * on systems with caches, caches must be flashed as the absolute
- * last instruction before going into a suspended halt.  Otherwise,
- * dirty data can linger in the cache and become stale on resume,
- * leading to strange errors.
- *
- * perform a variety of operations to guarantee that the compiler
- * will not reorder instructions.  wbinvd itself is serializing
- * so the processor will not reorder.
- *
- * Systems without cache can just go into halt.
- */
-static inline void wbinvd_halt(void)
-{
-	mb();
-	/* check for clflush to determine if wbinvd is legal */
-	if (cpu_has_clflush)
-		asm volatile("cli; wbinvd; 1: hlt; jmp 1b" : : : "memory");
-	else
-		while (1)
-			halt();
-}
-
 extern void enable_sep_cpu(void);
 extern int sysenter_setup(void);
 
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1329,11 +1329,94 @@ void play_dead_common(void)
 	local_irq_disable();
 }
 
+#define MWAIT_SUBSTATE_MASK		0xf
+#define MWAIT_SUBSTATE_SIZE		4
+
+#define CPUID_MWAIT_LEAF		5
+#define CPUID5_ECX_EXTENSIONS_SUPPORTED 0x1
+
+/*
+ * We need to flush the caches before going to sleep, lest we have
+ * dirty data in our caches when we come back up.
+ */
+static inline void mwait_play_dead(void)
+{
+	unsigned int eax, ebx, ecx, edx;
+	unsigned int highest_cstate = 0;
+	unsigned int highest_subcstate = 0;
+	int i;
+	void *mwait_ptr;
+
+	if (!cpu_has(&current_cpu_data, X86_FEATURE_MWAIT))
+		return;
+	if (!cpu_has(&current_cpu_data, X86_FEATURE_CLFLSH))
+		return;
+	if (current_cpu_data.cpuid_level < CPUID_MWAIT_LEAF)
+		return;
+
+	eax = CPUID_MWAIT_LEAF;
+	ecx = 0;
+	native_cpuid(&eax, &ebx, &ecx, &edx);
+
+	/*
+	 * eax will be 0 if EDX enumeration is not valid.
+	 * Initialized below to cstate, sub_cstate value when EDX is valid.
+	 */
+	if (!(ecx & CPUID5_ECX_EXTENSIONS_SUPPORTED)) {
+		eax = 0;
+	} else {
+		edx >>= MWAIT_SUBSTATE_SIZE;
+		for (i = 0; i < 7 && edx; i++, edx >>= MWAIT_SUBSTATE_SIZE) {
+			if (edx & MWAIT_SUBSTATE_MASK) {
+				highest_cstate = i;
+				highest_subcstate = edx & MWAIT_SUBSTATE_MASK;
+			}
+		}
+		eax = (highest_cstate << MWAIT_SUBSTATE_SIZE) |
+			(highest_subcstate - 1);
+	}
+
+	/*
+	 * This should be a memory location in a cache line which is
+	 * unlikely to be touched by other processors.  The actual
+	 * content is immaterial as it is not actually modified in any way.
+	 */
+	mwait_ptr = &current_thread_info()->flags;
+
+	wbinvd();
+
+	while (1) {
+		/*
+		 * The CLFLUSH is a workaround for erratum AAI65 for
+		 * the Xeon 7400 series.  It's not clear it is actually
+		 * needed, but it should be harmless in either case.
+		 * The WBINVD is insufficient due to the spurious-wakeup
+		 * case where we return around the loop.
+		 */
+		clflush(mwait_ptr);
+		__monitor(mwait_ptr, 0, 0);
+		mb();
+		__mwait(eax, 0);
+	}
+}
+
+static inline void hlt_play_dead(void)
+{
+	if (current_cpu_data.x86 >= 4)
+		wbinvd();
+
+	while (1) {
+		native_halt();
+	}
+}
+
 void native_play_dead(void)
 {
 	play_dead_common();
 	tboot_shutdown(TB_SHUTDOWN_WFS);
-	wbinvd_halt();
+
+	mwait_play_dead();	/* Only returns on failure */
+	hlt_play_dead();
 }
 
 #else /* ... !CONFIG_HOTPLUG_CPU */

  parent reply	other threads:[~2011-03-17 21:24 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-03-17 21:38 [000/474] 2.6.33.8-longterm review Greg KH
2011-03-17 21:22 ` [072/474] mm, x86: Saving vmcore with non-lazy freeing of vmas Greg KH
2011-03-17 21:22 ` [078/474] x86, kdump: Change copy_oldmem_page() to use cached addressing Greg KH
2011-03-17 21:24 ` Greg KH [this message]
2011-03-17 21:27 ` [421/474] powerpc/kexec: Fix orphaned offline CPUs across kexec Greg KH
2011-03-17 21:28 ` [430/474] MIPS: MTX-1: Make au1000_eth probe all PHY addresses Greg KH
2011-03-18  5:26 ` [000/474] 2.6.33.8-longterm review Mike Galbraith
2011-03-18  8:44 ` Thomas Gleixner
2011-03-19 14:47   ` Remy Bohmer
2011-03-20 12:52     ` Thomas Gleixner
2011-03-20 14:06       ` Niccolò Belli
2011-03-18  9:21 ` John Kacur
2011-03-18 19:36   ` Greg KH
2011-03-19 10:08     ` [stable] " John Kacur
     [not found] ` <20110317212903.394948496@clark.kroah.org>
2011-08-28 18:40   ` [regression] Re: [213/474] x86, hotplug: Use mwait to offline a processor, fix the legacy case Jonathan Nieder
     [not found]   ` <20110828184004.GA7690@elie.gateway.2wire.net>
2011-08-30 22:34     ` [stable] " Greg KH

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='20110317212903.394948496__15517.3490326435$1300398924$gmane$org@clark.kroah.org' \
    --to=gregkh@suse.de \
    --cc=hpa@linux.intel.com \
    --cc=len.brown@intel.com \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=stable-review@kernel.org \
    --cc=stable@kernel.org \
    --cc=x86@kernel.org \
    /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.