FAILED: patch "[PATCH] sched/idle/x86: Restore mwait_idle() to fix boot hangs, to" failed to apply to 3.10-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 3.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
b253149b843f89cd300cbdbea27ce1f847506f99Mon Sep 17 00:00:00 2001
From: Len Brown <[email protected]>
Date: Wed, 15 Jan 2014 00:37:34 -0500
Subject: [PATCH] sched/idle/x86: Restore mwait_idle() to fix boot hangs, to
improve power savings and to improve performance
In Linux-3.9 we removed the mwait_idle() loop:
69fb3676df33 ("x86 idle: remove mwait_idle() and "idle=mwait" cmdline param")
The reasoning was that modern machines should be sufficiently happy during the boot process using the default_idle() HALT loop, until cpuidle loads and either acpi_idle or intel_idle invoke the newer MWAIT-with-hints idle loop.
But two machines reported problems:
1. Certain Core2-era machines support MWAIT-C1 and HALT only. MWAIT-C1 is preferred for optimal power and performance. But if they support just C1, cpuidle never loads and so they use the boot-time default idle loop forever.
2. Some laptops will boot-hang if HALT is used, but will boot successfully if MWAIT is used. This appears to be a hidden assumption in BIOS SMI, that is presumably valid on the proprietary OS where the BIOS was validated.
https://bugzilla.kernel.org/show_bug.cgi?id=60770
So here we effectively revert the patch above, restoring the mwait_idle() loop. However, we don't bother restoring the idle=mwait cmdline parameter, since it appears to add no value.
Maintainer notes:
For 3.9, simply revert 69fb3676df
for 3.10, patch -F3 applies, fuzz needed due to __cpuinit use in context For 3.11, 3.12, 3.13, this patch applies cleanly
arch/x86/include/asm/mwait.h +8 -0
@@ -30,6 +30,14 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) :: "a" (eax), "c" (ecx)); } +static inline void __sti_mwait (unsigned long eax,unsigned long ecx) +{ +trace_hardirqs_on (); +/* "mwait %eax, %ecx;" */ + asmvolatile ("sti; .byte 0x0f, 0x01, 0xc9;" + ::"a" (eax),"c" (ecx)); +} +/* * This uses new MONITOR/MWAIT instructions on P4 processors with PNI, * which can obviate IPI to trigger checking of need_resched.
arch/x86/kernel/process.c +47 -0
65 lines not on this page · raw message
Quoted 8 lines · On Wed, 2015-04-29 at 13:57 +0200, [email protected] wrote:
The patch below does not apply to the 3.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.From my 3.10-stable tree, with upstream commit header.
From
b253149b843f89cd300cbdbea27ce1f847506f99Mon Sep 17 00:00:00 2001
From: Len Brown <[email protected]>
Date: Wed, 15 Jan 2014 00:37:34 -0500
Subject: sched/idle/x86: Restore mwait_idle() to fix boot hangs, to improve power savings and to improve performance
In Linux-3.9 we removed the mwait_idle() loop:
69fb3676df33 ("x86 idle: remove mwait_idle() and "idle=mwait" cmdline param")
The reasoning was that modern machines should be sufficiently happy during the boot process using the default_idle() HALT loop, until cpuidle loads and either acpi_idle or intel_idle invoke the newer MWAIT-with-hints idle loop.
But two machines reported problems:
1. Certain Core2-era machines support MWAIT-C1 and HALT only. MWAIT-C1 is preferred for optimal power and performance. But if they support just C1, cpuidle never loads and so they use the boot-time default idle loop forever.
2. Some laptops will boot-hang if HALT is used, but will boot successfully if MWAIT is used. This appears to be a hidden assumption in BIOS SMI, that is presumably valid on the proprietary OS where the BIOS was validated.
https://bugzilla.kernel.org/show_bug.cgi?id=60770
So here we effectively revert the patch above, restoring the mwait_idle() loop. However, we don't bother restoring the idle=mwait cmdline parameter, since it appears to add no value.
Maintainer notes:
For 3.9, simply revert 69fb3676df
for 3.10, patch -F3 applies, fuzz needed due to __cpuinit use in context For 3.11, 3.12, 3.13, this patch applies cleanly
--- arch/x86/kernel/process.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+)
arch/x86/kernel/process.c +49 -0
@@ -398,6 +398,52 @@ static void amd_e400_idle(void)default_idle (); } +/* +* Intel Core2 and older machines prefer MWAIT over HALT for C1. +* We can't rely on cpuidle installing MWAIT, because it will not load +* on systems that support only C1 -- so the boot default must be MWAIT. +* +* Some AMD machines are the opposite, they depend on using HALT. +* +* So for default C1, which is used during boot until cpuidle loads, +* use MWAIT-C1 on Intel HW that has it, else use HALT. +*/ +static int prefer_mwait_c1_over_halt (const struct cpuinfo_x86 *c) +{ +if (c->x86_vendor !=X86_VENDOR_INTEL ) +return 0 ; + +if (!cpu_has (c,X86_FEATURE_MWAIT )) +return 0 ; + +return 1 ; +} + +/* +* MONITOR/MWAIT with no hints, used for default default C1 state. +* This invokes MWAIT with interrutps enabled and no flags, +* which is backwards compatible with the original MWAIT implementation. +*/ + +static void mwait_idle (void ) +{ +if (!current_set_polling_and_test ()) { +if (static_cpu_has (X86_FEATURE_CLFLUSH_MONITOR )) { +mb (); +clflush ((void *)¤t_thread_info ()->flags); +mb (); + } + +__monitor ((void *)¤t_thread_info ()->flags,0 ,0 ); +if (!need_resched ()) +__sti_mwait (0 ,0 ); +else +local_irq_enable (); + }else +local_irq_enable (); +__current_clr_polling (); +} +void __cpuinit select_idle_routine (const struct cpuinfo_x86 *c) {#ifdef CONFIG_SMP
@@ -411,6 +457,9 @@ void __cpuinit select_idle_routine(const/* E400: APIC timer interrupt does not wake up CPU from C1e */ pr_info ("using AMD E400 aware idle routine\n" ); x86_idle = amd_e400_idle; + }else if (prefer_mwait_c1_over_halt (c)) { +pr_info ("using mwait in idle threads\n" ); + x86_idle = mwait_idle; }else x86_idle = default_idle; }
Greg KH
maintainerQuoted 6 lines · Mike Galbraith
Quoted 4 lines · On Wed, 2015-04-29 at 13:57 +0200, [email protected] wrote:
The patch below does not apply to the 3.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
Quoted 6 lines
Quoted 3 lines
From my 3.10-stable tree, with upstream commit header.
From
b253149b843f89cd300cbdbea27ce1f847506f99Mon Sep 17 00:00:00 2001From: Len Brown <[email protected]>
Date: Wed, 15 Jan 2014 00:37:34 -0500
Subject: sched/idle/x86: Restoremwait_idle()to fix boot hangs, to improve power savings and to improve performance
Thanks, now applied.
greg k-h