On Mon, Jul 18, 2016 at 2:41 PM, Jacob Pan <[email protected]> wrote: > From: Peter Zijlstra <[email protected]> > > Monitored cached line may not wake up from mwait on certain > Goldmont based CPUs. This patch will avoid calling > current_set_polling_and_test() and thereby not set the TIF_ flag. > The result is that we'll always send IPIs for wakeups. > > Signed-off-by: Peter Zijlstra <[email protected]> > Signed-off-by: Jacob Pan <[email protected]> > --- > arch/x86/include/asm/cpufeatures.h | 2 +- > arch/x86/include/asm/mwait.h | 2 +- > arch/x86/kernel/cpu/intel.c | 5 +++++ > arch/x86/kernel/process.c | 2 +- > 4 files changed, 8 insertions(+), 3 deletions(-) > > diff --git a/arch/x86/include/asm/cpufeatures.h > b/arch/x86/include/asm/cpufeatures.h > index c64b1e9..c5097a7 100644 > --- a/arch/x86/include/asm/cpufeatures.h > +++ b/arch/x86/include/asm/cpufeatures.h > @@ -310,5 +310,5 @@ > #endif > #define X86_BUG_NULL_SEG X86_BUG(10) /* Nulling a selector preserves > the base */ > #define X86_BUG_SWAPGS_FENCE X86_BUG(11) /* SWAPGS without input dep on GS > */ > - > +#define X86_BUG_MONITOR X86_BUG(12) /* IPI required to wake > up remote cpu */ > #endif /* _ASM_X86_CPUFEATURES_H */ > diff --git a/arch/x86/include/asm/mwait.h b/arch/x86/include/asm/mwait.h > index 0deeb2d..f37f2d8 100644 > --- a/arch/x86/include/asm/mwait.h > +++ b/arch/x86/include/asm/mwait.h > @@ -97,7 +97,7 @@ static inline void __sti_mwait(unsigned long eax, unsigned > long ecx) > */ > static inline void mwait_idle_with_hints(unsigned long eax, unsigned long > ecx) > { > - if (!current_set_polling_and_test()) { > + if (static_cpu_has_bug(X86_BUG_MONITOR) || > !current_set_polling_and_test()) { > if (static_cpu_has_bug(X86_BUG_CLFLUSH_MONITOR)) { > mb(); > clflush((void *)¤t_thread_info()->flags); > diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c > index f380b61..fcd484d 100644 > --- a/arch/x86/kernel/cpu/intel.c > +++ b/arch/x86/kernel/cpu/intel.c > @@ -13,6 +13,7 @@ > #include <asm/msr.h> > #include <asm/bugs.h> > #include <asm/cpu.h> > +#include <asm/intel-family.h> > > #ifdef CONFIG_X86_64 > #include <linux/topology.h> > @@ -508,6 +509,10 @@ static void init_intel(struct cpuinfo_x86 *c) > (c->x86_model == 29 || c->x86_model == 46 || c->x86_model == 47)) > set_cpu_bug(c, X86_BUG_CLFLUSH_MONITOR); > > + if (c->x86 == 6 && boot_cpu_has(X86_FEATURE_MWAIT) && > + ((c->x86_model == INTEL_FAM6_ATOM_GOLDMONT))) > + set_cpu_bug(c, X86_BUG_MONITOR); > + > #ifdef CONFIG_X86_64 > if (c->x86 == 15) > c->x86_cache_alignment = c->x86_clflush_size * 2; > diff --git a/arch/x86/kernel/process.c b/arch/x86/kernel/process.c > index 61b703c..62c0b0e 100644 > --- a/arch/x86/kernel/process.c > +++ b/arch/x86/kernel/process.c > @@ -405,7 +405,7 @@ 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)) > + if (!cpu_has(c, X86_FEATURE_MWAIT) || > static_cpu_has_bug(X86_BUG_MONITOR)) > return 0; > > return 1; > -- > 2.7.4 >
It would be simpler to just force clear X86_FEATURE_MWAIT. -- Brian Gerst

