Skip to content

Commit d01e7a4

Browse files
amlutoZhengShunQian
authored andcommitted
x86/fpu: Hard-disable lazy FPU mode
commit ca6938a upstream. Since commit: 58122bf ("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 <[email protected]> Signed-off-by: Rik van Riel <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: Fenghua Yu <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Quentin Casasnovas <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d21c4d8 commit d01e7a4

File tree

3 files changed

+5
-90
lines changed

3 files changed

+5
-90
lines changed

arch/x86/include/asm/cpufeature.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
#define X86_FEATURE_EXTD_APICID ( 3*32+26) /* has extended APICID (8 bits) */
105105
#define X86_FEATURE_AMD_DCM ( 3*32+27) /* multi-node processor */
106106
#define X86_FEATURE_APERFMPERF ( 3*32+28) /* APERFMPERF */
107-
#define X86_FEATURE_EAGER_FPU ( 3*32+29) /* "eagerfpu" Non lazy FPU restore */
107+
/* free, was #define X86_FEATURE_EAGER_FPU ( 3*32+29) * "eagerfpu" Non lazy FPU restore */
108108
#define X86_FEATURE_NONSTOP_TSC_S3 ( 3*32+30) /* TSC doesn't stop in S3 state */
109109

110110
/* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */

arch/x86/include/asm/fpu/internal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ extern u64 fpu__get_supported_xfeatures_mask(void);
5858
*/
5959
static __always_inline __pure bool use_eager_fpu(void)
6060
{
61-
return static_cpu_has_safe(X86_FEATURE_EAGER_FPU);
61+
return true;
6262
}
6363

6464
static __always_inline __pure bool use_xsaveopt(void)

arch/x86/kernel/fpu/init.c

Lines changed: 3 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
*/
1616
static void fpu__init_cpu_ctx_switch(void)
1717
{
18-
if (!boot_cpu_has(X86_FEATURE_EAGER_FPU))
19-
stts();
20-
else
21-
clts();
18+
clts();
2219
}
2320

2421
/*
@@ -234,83 +231,17 @@ static void __init fpu__init_system_xstate_size_legacy(void)
234231
setup_clear_cpu_cap(X86_FEATURE_XSAVES);
235232
}
236233

237-
/*
238-
* FPU context switching strategies:
239-
*
240-
* Against popular belief, we don't do lazy FPU saves, due to the
241-
* task migration complications it brings on SMP - we only do
242-
* lazy FPU restores.
243-
*
244-
* 'lazy' is the traditional strategy, which is based on setting
245-
* CR0::TS to 1 during context-switch (instead of doing a full
246-
* restore of the FPU state), which causes the first FPU instruction
247-
* after the context switch (whenever it is executed) to fault - at
248-
* which point we lazily restore the FPU state into FPU registers.
249-
*
250-
* Tasks are of course under no obligation to execute FPU instructions,
251-
* so it can easily happen that another context-switch occurs without
252-
* a single FPU instruction being executed. If we eventually switch
253-
* back to the original task (that still owns the FPU) then we have
254-
* not only saved the restores along the way, but we also have the
255-
* FPU ready to be used for the original task.
256-
*
257-
* 'lazy' is deprecated because it's almost never a performance win
258-
* and it's much more complicated than 'eager'.
259-
*
260-
* 'eager' switching is by default on all CPUs, there we switch the FPU
261-
* state during every context switch, regardless of whether the task
262-
* has used FPU instructions in that time slice or not. This is done
263-
* because modern FPU context saving instructions are able to optimize
264-
* state saving and restoration in hardware: they can detect both
265-
* unused and untouched FPU state and optimize accordingly.
266-
*
267-
* [ Note that even in 'lazy' mode we might optimize context switches
268-
* to use 'eager' restores, if we detect that a task is using the FPU
269-
* frequently. See the fpu->counter logic in fpu/internal.h for that. ]
270-
*/
271-
static enum { ENABLE, DISABLE } eagerfpu = ENABLE;
272-
273234
/*
274235
* Find supported xfeatures based on cpu features and command-line input.
275236
* This must be called after fpu__init_parse_early_param() is called and
276237
* xfeatures_mask is enumerated.
277238
*/
278239
u64 __init fpu__get_supported_xfeatures_mask(void)
279240
{
280-
/* Support all xfeatures known to us */
281-
if (eagerfpu != DISABLE)
282-
return XCNTXT_MASK;
283-
284-
/* Warning of xfeatures being disabled for no eagerfpu mode */
285-
if (xfeatures_mask & XFEATURE_MASK_EAGER) {
286-
pr_err("x86/fpu: eagerfpu switching disabled, disabling the following xstate features: 0x%llx.\n",
287-
xfeatures_mask & XFEATURE_MASK_EAGER);
288-
}
289-
290-
/* Return a mask that masks out all features requiring eagerfpu mode */
291-
return ~XFEATURE_MASK_EAGER;
292-
}
293-
294-
/*
295-
* Disable features dependent on eagerfpu.
296-
*/
297-
static void __init fpu__clear_eager_fpu_features(void)
298-
{
299-
setup_clear_cpu_cap(X86_FEATURE_MPX);
241+
return XCNTXT_MASK;
300242
}
301243

302-
/*
303-
* Pick the FPU context switching strategy:
304-
*
305-
* When eagerfpu is AUTO or ENABLE, we ensure it is ENABLE if either of
306-
* the following is true:
307-
*
308-
* (1) the cpu has xsaveopt, as it has the optimization and doing eager
309-
* FPU switching has a relatively low cost compared to a plain xsave;
310-
* (2) the cpu has xsave features (e.g. MPX) that depend on eager FPU
311-
* switching. Should the kernel boot with noxsaveopt, we support MPX
312-
* with eager FPU switching at a higher cost.
313-
*/
244+
/* Legacy code to initialize eager fpu mode. */
314245
static void __init fpu__init_system_ctx_switch(void)
315246
{
316247
static bool on_boot_cpu = 1;
@@ -320,17 +251,6 @@ static void __init fpu__init_system_ctx_switch(void)
320251

321252
WARN_ON_FPU(current->thread.fpu.fpstate_active);
322253
current_thread_info()->status = 0;
323-
324-
if (boot_cpu_has(X86_FEATURE_XSAVEOPT) && eagerfpu != DISABLE)
325-
eagerfpu = ENABLE;
326-
327-
if (xfeatures_mask & XFEATURE_MASK_EAGER)
328-
eagerfpu = ENABLE;
329-
330-
if (eagerfpu == ENABLE)
331-
setup_force_cpu_cap(X86_FEATURE_EAGER_FPU);
332-
333-
printk(KERN_INFO "x86/fpu: Using '%s' FPU context switches.\n", eagerfpu == ENABLE ? "eager" : "lazy");
334254
}
335255

336256
/*
@@ -339,11 +259,6 @@ static void __init fpu__init_system_ctx_switch(void)
339259
*/
340260
static void __init fpu__init_parse_early_param(void)
341261
{
342-
if (cmdline_find_option_bool(boot_command_line, "eagerfpu=off")) {
343-
eagerfpu = DISABLE;
344-
fpu__clear_eager_fpu_features();
345-
}
346-
347262
if (cmdline_find_option_bool(boot_command_line, "no387"))
348263
setup_clear_cpu_cap(X86_FEATURE_FPU);
349264

0 commit comments

Comments
 (0)