aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/x86/kernel/process_64.c27
1 files changed, 18 insertions, 9 deletions
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index c9b8904736db..a28279dbb07c 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -386,9 +386,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
386 int cpu = smp_processor_id(); 386 int cpu = smp_processor_id();
387 struct tss_struct *tss = &per_cpu(init_tss, cpu); 387 struct tss_struct *tss = &per_cpu(init_tss, cpu);
388 unsigned fsindex, gsindex; 388 unsigned fsindex, gsindex;
389 bool preload_fpu;
390
391 /*
392 * If the task has used fpu the last 5 timeslices, just do a full
393 * restore of the math state immediately to avoid the trap; the
394 * chances of needing FPU soon are obviously high now
395 */
396 preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
389 397
390 /* we're going to use this soon, after a few expensive things */ 398 /* we're going to use this soon, after a few expensive things */
391 if (next_p->fpu_counter > 5) 399 if (preload_fpu)
392 prefetch(next->xstate); 400 prefetch(next->xstate);
393 401
394 /* 402 /*
@@ -422,6 +430,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
422 /* Must be after DS reload */ 430 /* Must be after DS reload */
423 unlazy_fpu(prev_p); 431 unlazy_fpu(prev_p);
424 432
433 /* Make sure cpu is ready for new context */
434 if (preload_fpu)
435 clts();
436
425 /* 437 /*
426 * Leave lazy mode, flushing any hypercalls made here. 438 * Leave lazy mode, flushing any hypercalls made here.
427 * This must be done before restoring TLS segments so 439 * This must be done before restoring TLS segments so
@@ -480,15 +492,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
480 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV)) 492 task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
481 __switch_to_xtra(prev_p, next_p, tss); 493 __switch_to_xtra(prev_p, next_p, tss);
482 494
483 /* If the task has used fpu the last 5 timeslices, just do a full 495 /*
484 * restore of the math state immediately to avoid the trap; the 496 * Preload the FPU context, now that we've determined that the
485 * chances of needing FPU soon are obviously high now 497 * task is likely to be using it.
486 *
487 * tsk_used_math() checks prevent calling math_state_restore(),
488 * which can sleep in the case of !tsk_used_math()
489 */ 498 */
490 if (tsk_used_math(next_p) && next_p->fpu_counter > 5) 499 if (preload_fpu)
491 math_state_restore(); 500 __math_state_restore();
492 return prev_p; 501 return prev_p;
493} 502}
494 503