x86/fpu: Hard-disable lazy FPU mode
authorAndy Lutomirski <luto@kernel.org>
Wed, 5 Oct 2016 00:34:31 +0000 (20:34 -0400)
committerIngo Molnar <mingo@kernel.org>
Fri, 7 Oct 2016 09:14:17 +0000 (11:14 +0200)
Since commit:

  58122bf1d856 ("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: Andy Lutomirski <luto@kernel.org>
Signed-off-by: Rik 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.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/asm/cpufeatures.h
arch/x86/include/asm/fpu/internal.h
arch/x86/kernel/fpu/init.c

index 1188bc849ee3b3253fd8229fca21bf2d6c87856e..b212b862314a997e4ae9ab75439433fbdc93304c 100644 (file)
 #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_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 */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
index 2737366ea5830df0f3b54b69be488c41768dc799..8852e3afa1adc2134f0badd9e8c1375ec492ea66 100644 (file)
@@ -62,7 +62,7 @@ extern u64 fpu__get_supported_xfeatures_mask(void);
  */
 static __always_inline __pure bool use_eager_fpu(void)
 {
-       return static_cpu_has(X86_FEATURE_EAGER_FPU);
+       return true;
 }
 
 static __always_inline __pure bool use_xsaveopt(void)
index 2f2b8c7ccb857f636f745a5754810ea47e3d86df..1a09d133c801049344bd0501d7c1a198b0730421 100644 (file)
  */
 static void fpu__init_cpu_ctx_switch(void)
 {
-       if (!boot_cpu_has(X86_FEATURE_EAGER_FPU))
-               stts();
-       else
-               clts();
+       clts();
 }
 
 /*
@@ -232,42 +229,6 @@ static void __init fpu__init_system_xstate_size_legacy(void)
        fpu_user_xstate_size = fpu_kernel_xstate_size;
 }
 
-/*
- * 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.
  * This must be called after fpu__init_parse_early_param() is called and
@@ -275,40 +236,10 @@ static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
  */
 u64 __init fpu__get_supported_xfeatures_mask(void)
 {
-       /* Support all xfeatures known to us */
-       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);
+       return XCNTXT_MASK;
 }
 
-/*
- * 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.
- */
+/* Legacy code to initialize eager fpu mode. */
 static void __init fpu__init_system_ctx_switch(void)
 {
        static bool on_boot_cpu __initdata = 1;
@@ -317,17 +248,6 @@ static void __init fpu__init_system_ctx_switch(void)
        on_boot_cpu = 0;
 
        WARN_ON_FPU(current->thread.fpu.fpstate_active);
-
-       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");
 }
 
 /*
@@ -336,11 +256,6 @@ static void __init fpu__init_system_ctx_switch(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"))
                setup_clear_cpu_cap(X86_FEATURE_FPU);