diff options
| -rw-r--r-- | arch/x86/kernel/process_32.c | 27 |
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) |
