Commit 7c3adb3c authored by Andy Lutomirski's avatar Andy Lutomirski Committed by Greg Kroah-Hartman

x86/fpu: Hard-disable lazy FPU mode

commit ca6938a1 upstream.

Since commit:

  58122bf1 ("x86/fpu: Default eagerfpu=on on all CPUs")

... in Linux 4.6, eager FPU mode has been the default on all x86
systems, and no one has reported any regressions.

This patch removes the ability to enable lazy mode: use_eager_fpu()
becomes "return true" and all of the FPU mode selection machinery is
removed.
Signed-off-by: default avatarAndy Lutomirski <luto@kernel.org>
Signed-off-by: default avatarRik van Riel <riel@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Quentin Casasnovas <quentin.casasnovas@oracle.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: pbonzini@redhat.com
Link: http://lkml.kernel.org/r/1475627678-20788-3-git-send-email-riel@redhat.comSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 8edb1d7e
...@@ -104,7 +104,7 @@ ...@@ -104,7 +104,7 @@
#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */ #define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */ #define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */ #define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */ /* free, was #define X86_FEATURE_EAGER_FPU ( 3*32+29) * "eagerfpu" Non lazy FPU restore */
#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */ #define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
......
...@@ -58,7 +58,7 @@ extern u64 fpu__get_supported_xfeatures_mask(void); ...@@ -58,7 +58,7 @@ extern u64 fpu__get_supported_xfeatures_mask(void);
*/ */
static __always_inline __pure bool use_eager_fpu(void) static __always_inline __pure bool use_eager_fpu(void)
{ {
return static_cpu_has_safe(X86_FEATURE_EAGER_FPU); return true;
} }
static __always_inline __pure bool use_xsaveopt(void) static __always_inline __pure bool use_xsaveopt(void)
......
...@@ -15,10 +15,7 @@ ...@@ -15,10 +15,7 @@
*/ */
static void fpu__init_cpu_ctx_switch(void) static void fpu__init_cpu_ctx_switch(void)
{ {
if (!boot_cpu_has(X86_FEATURE_EAGER_FPU)) clts();
stts();
else
clts();
} }
/* /*
...@@ -234,42 +231,6 @@ static void __init fpu__init_system_xstate_size_legacy(void) ...@@ -234,42 +231,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
setup_clear_cpu_cap(X86_FEATURE_XSAVES); setup_clear_cpu_cap(X86_FEATURE_XSAVES);
} }
/*
* FPU context switching strategies:
*
* Against popular belief, we don't do lazy FPU saves, due to the
* task migration complications it brings on SMP - we only do
* lazy FPU restores.
*
* 'lazy' is the traditional strategy, which is based on setting
* CR0::TS to 1 during context-switch (instead of doing a full
* restore of the FPU state), which causes the first FPU instruction
* after the context switch (whenever it is executed) to fault - at
* which point we lazily restore the FPU state into FPU registers.
*
* Tasks are of course under no obligation to execute FPU instructions,
* so it can easily happen that another context-switch occurs without
* a single FPU instruction being executed. If we eventually switch
* back to the original task (that still owns the FPU) then we have
* not only saved the restores along the way, but we also have the
* FPU ready to be used for the original task.
*
* 'lazy' is deprecated because it's almost never a performance win
* and it's much more complicated than 'eager'.
*
* 'eager' switching is by default on all CPUs, there we switch the FPU
* state during every context switch, regardless of whether the task
* has used FPU instructions in that time slice or not. This is done
* because modern FPU context saving instructions are able to optimize
* state saving and restoration in hardware: they can detect both
* unused and untouched FPU state and optimize accordingly.
*
* [ Note that even in 'lazy' mode we might optimize context switches
* to use 'eager' restores, if we detect that a task is using the FPU
* frequently. See the fpu->counter logic in fpu/internal.h for that. ]
*/
static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
/* /*
* Find supported xfeatures based on cpu features and command-line input. * Find supported xfeatures based on cpu features and command-line input.
* This must be called after fpu__init_parse_early_param() is called and * This must be called after fpu__init_parse_early_param() is called and
...@@ -277,40 +238,10 @@ static enum { ENABLE, DISABLE } eagerfpu = ENABLE; ...@@ -277,40 +238,10 @@ static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
*/ */
u64 __init fpu__get_supported_xfeatures_mask(void) u64 __init fpu__get_supported_xfeatures_mask(void)
{ {
/* Support all xfeatures known to us */ return XCNTXT_MASK;
if (eagerfpu != DISABLE)
return XCNTXT_MASK;
/* Warning of xfeatures being disabled for no eagerfpu mode */
if (xfeatures_mask & XFEATURE_MASK_EAGER) {
pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
xfeatures_mask & XFEATURE_MASK_EAGER);
}
/* Return a mask that masks out all features requiring eagerfpu mode */
return ~XFEATURE_MASK_EAGER;
}
/*
* Disable features dependent on eagerfpu.
*/
static void __init fpu__clear_eager_fpu_features(void)
{
setup_clear_cpu_cap(X86_FEATURE_MPX);
} }
/* /* Legacy code to initialize eager fpu mode. */
* Pick the FPU context switching strategy:
*
* When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of
* the following is true:
*
* (1) the cpu has xsaveopt, as it has the optimization and doing eager
* FPU switching has a relatively low cost compared to a plain xsave;
* (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU
* switching. Should the kernel boot with noxsaveopt, we support MPX
* with eager FPU switching at a higher cost.
*/
static void __init fpu__init_system_ctx_switch(void) static void __init fpu__init_system_ctx_switch(void)
{ {
static bool on_boot_cpu = 1; static bool on_boot_cpu = 1;
...@@ -320,17 +251,6 @@ static void __init fpu__init_system_ctx_switch(void) ...@@ -320,17 +251,6 @@ static void __init fpu__init_system_ctx_switch(void)
WARN_ON_FPU(current->thread.fpu.fpstate_active); WARN_ON_FPU(current->thread.fpu.fpstate_active);
current_thread_info()->status = 0; current_thread_info()->status = 0;
if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE)
eagerfpu = ENABLE;
if (xfeatures_mask & XFEATURE_MASK_EAGER)
eagerfpu = ENABLE;
if (eagerfpu == ENABLE)
setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy");
} }
/* /*
...@@ -339,11 +259,6 @@ static void __init fpu__init_system_ctx_switch(void) ...@@ -339,11 +259,6 @@ static void __init fpu__init_system_ctx_switch(void)
*/ */
static void __init fpu__init_parse_early_param(void) static void __init fpu__init_parse_early_param(void)
{ {
if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) {
eagerfpu = DISABLE;
fpu__clear_eager_fpu_features();
}
if (cmdline_find_option_bool(boot_command_line, "no387")) if (cmdline_find_option_bool(boot_command_line, "no387"))
setup_clear_cpu_cap(X86_FEATURE_FPU); setup_clear_cpu_cap(X86_FEATURE_FPU);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment