aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/process_32.c27
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 59f4524984af..a80eddd41658 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -350,14 +350,21 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
350 *next = &next_p->thread; 350 *next = &next_p->thread;
351 int cpu = smp_processor_id(); 351 int cpu = smp_processor_id();
352 struct tss_struct *tss = &per_cpu(init_tss, cpu); 352 struct tss_struct *tss = &per_cpu(init_tss, cpu);
353 bool preload_fpu;
353 354
354 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */ 355 /* never put a printk in __switch_to... printk() calls wake_up*() indirectly */
355 356
356 __unlazy_fpu(prev_p); 357 /*
358 * If the task has used fpu the last 5 timeslices, just do a full
359 * restore of the math state immediately to avoid the trap; the
360 * chances of needing FPU soon are obviously high now
361 */
362 preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
357 363
364 __unlazy_fpu(prev_p);
358 365
359 /* we're going to use this soon, after a few expensive things */ 366 /* we're going to use this soon, after a few expensive things */
360 if (next_p->fpu_counter > 5) 367 if (preload_fpu)
361 prefetch(next->xstate); 368 prefetch(next->xstate);
362 369
363 /* 370 /*
@@ -398,6 +405,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
398 task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT)) 405 task_thread_info(next_p)->flags & _TIF_WORK_CTXSW_NEXT))
399 __switch_to_xtra(prev_p, next_p, tss); 406 __switch_to_xtra(prev_p, next_p, tss);
400 407
408 /* If we're going to preload the fpu context, make sure clts
409 is run while we're batching the cpu state updates. */
410 if (preload_fpu)
411 clts();
412
401 /* 413 /*
402 * Leave lazy mode, flushing any hypercalls made here. 414 * Leave lazy mode, flushing any hypercalls made here.
403 * This must be done before restoring TLS segments so 415 * This must be done before restoring TLS segments so
@@ -407,15 +419,8 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
407 */ 419 */
408 arch_end_context_switch(next_p); 420 arch_end_context_switch(next_p);
409 421
410 /* If the task has used fpu the last 5 timeslices, just do a full 422 if (preload_fpu)
411 * restore of the math state immediately to avoid the trap; the 423 __math_state_restore();
412 * chances of needing FPU soon are obviously high now
413 *
414 * tsk_used_math() checks prevent calling math_state_restore(),
415 * which can sleep in the case of !tsk_used_math()
416 */
417 if (tsk_used_math(next_p) && next_p->fpu_counter > 5)
418 math_state_restore();
419 424
420 /* 425 /*
421 * Restore %gs if needed (which is common) 426 * Restore %gs if needed (which is common)