From: Avi Kivity <avi@redhat.com>
To: Ingo Molnar <mingo@elte.hu>, "H. Peter Anvin" <hpa@zytor.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH 4/4] x86, fpu: don't save fpu state when switching from a task
Date: Sun, 13 Jun 2010 18:03:47 +0300 [thread overview]
Message-ID: <1276441427-31514-5-git-send-email-avi@redhat.com> (raw)
In-Reply-To: <1276441427-31514-1-git-send-email-avi@redhat.com>
Currently, we load the fpu state lazily when switching into a task: usually
we leave the fpu state in memory and only load it on demand.
However, when switching out of an fpu-using task, we eagerly save the fpu
state to memory. This can be detrimental if we'll switch right back to this
task without touching the fpu again - we'll have run a save/load cycle for
nothing.
This patch changes fpu saving on switch out to be lazy - we simply leave the
fpu state alone. If we're lucky, when we're back in this task the fpu state
will be loaded. If not the fpu API will save the current fpu state and load
our state back.
Signed-off-by: Avi Kivity <avi@redhat.com>
---
arch/x86/kernel/process_32.c | 12 ++++++++----
arch/x86/kernel/process_64.c | 13 ++++++++-----
2 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index 8d12878..4cb5bc4 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -302,10 +302,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* If the task has used fpu the last 5 timeslices, just do a full
* restore of the math state immediately to avoid the trap; the
* chances of needing FPU soon are obviously high now
+ *
+ * If the fpu is remote, we can't preload it since that requires an
+ * IPI. Let a math execption move it locally.
*/
- preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
-
- __unlazy_fpu(prev_p);
+ preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5
+ && !fpu_remote(&next->fpu);
/* we're going to use this soon, after a few expensive things */
if (preload_fpu)
@@ -351,8 +353,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/* If we're going to preload the fpu context, make sure clts
is run while we're batching the cpu state updates. */
- if (preload_fpu)
+ if (preload_fpu || fpu_loaded(&next->fpu))
clts();
+ else
+ stts();
/*
* Leave lazy mode, flushing any hypercalls made here.
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 3c2422a..65d2130 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -383,8 +383,12 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
* If the task has used fpu the last 5 timeslices, just do a full
* restore of the math state immediately to avoid the trap; the
* chances of needing FPU soon are obviously high now
+ *
+ * If the fpu is remote, we can't preload it since that requires an
+ * IPI. Let a math execption move it locally.
*/
- preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5;
+ preload_fpu = tsk_used_math(next_p) && next_p->fpu_counter > 5
+ && !fpu_remote(&next->fpu);
/* we're going to use this soon, after a few expensive things */
if (preload_fpu)
@@ -418,12 +422,11 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
load_TLS(next, cpu);
- /* Must be after DS reload */
- unlazy_fpu(prev_p);
-
/* Make sure cpu is ready for new context */
- if (preload_fpu)
+ if (preload_fpu || fpu_loaded(&next->fpu))
clts();
+ else
+ stts();
/*
* Leave lazy mode, flushing any hypercalls made here.
--
1.7.1
next prev parent reply other threads:[~2010-06-13 15:04 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-13 15:03 [PATCH 0/4] Really lazy fpu Avi Kivity
2010-06-13 15:03 ` [PATCH 1/4] x86, fpu: merge __save_init_fpu() implementations Avi Kivity
2010-06-13 15:03 ` [PATCH 2/4] x86, fpu: run device not available trap with interrupts enabled Avi Kivity
2010-06-13 15:03 ` [PATCH 3/4] x86, fpu: Let the fpu remember which cpu it is active on Avi Kivity
2010-06-13 15:03 ` Avi Kivity [this message]
2010-06-13 20:45 ` [PATCH 0/4] Really lazy fpu Valdis.Kletnieks
2010-06-14 7:47 ` Avi Kivity
2010-06-16 7:24 ` Avi Kivity
2010-06-16 7:32 ` H. Peter Anvin
2010-06-16 8:02 ` Avi Kivity
2010-06-16 8:39 ` Ingo Molnar
2010-06-16 9:01 ` Samuel Thibault
2010-06-16 9:43 ` Avi Kivity
2010-06-16 9:10 ` Nick Piggin
2010-06-16 9:30 ` Avi Kivity
2010-06-16 9:28 ` Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1276441427-31514-5-git-send-email-avi@redhat.com \
--to=avi@redhat.com \
--cc=hpa@zytor.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).