[tip:x86/fpu] x86/fpu: Optimize fpu__activate_fpstate_write()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Commit-ID:  343763c3b0a4fa2d29f7c3ba405abf8771b90876
Gitweb:     http://git.kernel.org/tip/343763c3b0a4fa2d29f7c3ba405abf8771b90876
Author:     Ingo Molnar <mingo@xxxxxxxxxx>
AuthorDate: Wed, 27 May 2015 12:22:29 +0200
Committer:  Ingo Molnar <mingo@xxxxxxxxxx>
CommitDate: Wed, 27 May 2015 14:11:27 +0200

x86/fpu: Optimize fpu__activate_fpstate_write()

fpu__activate_fpstate_write() is used before ptrace writes to the fpstate
context. Because it expects the modified registers to be reloaded on the
nexts context switch, it's only valid to call this function for stopped
child tasks.

  - add a debugging check for this assumption

  - remove code that only runs if the current task's FPU state needs
    to be saved, which cannot occur here

  - update comments to match the implementation

Cc: Andy Lutomirski <luto@xxxxxxxxxxxxxx>
Cc: Bobby Powers <bobbypowers@xxxxxxxxx>
Cc: Borislav Petkov <bp@xxxxxxxxx>
Cc: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx>
Cc: Fenghua Yu <fenghua.yu@xxxxxxxxx>
Cc: H. Peter Anvin <hpa@xxxxxxxxx>
Cc: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Cc: Oleg Nesterov <oleg@xxxxxxxxxx>
Cc: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
Signed-off-by: Ingo Molnar <mingo@xxxxxxxxxx>
---
 arch/x86/kernel/fpu/core.c | 51 +++++++++++++++++-----------------------------
 1 file changed, 19 insertions(+), 32 deletions(-)

diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
index 6b0955a..86a9a9a 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -322,47 +322,34 @@ void fpu__activate_fpstate_read(struct fpu *fpu)
 }
 
 /*
- * This function must be called before we read or write a task's fpstate.
+ * This function must be called before we write a task's fpstate.
  *
- * If the task has not used the FPU before then initialize its
- * fpstate.
- *
- * If the task has used the FPU before then save and unlazy it.
- *
- * [ If this function is used for non-current child tasks, then
- *   after this function call, after registers in the fpstate are
- *   modified and the child task has woken up, the child task will
- *   restore the modified FPU state from the modified context. If we
- *   didn't clear its lazy status here then the lazy in-registers
- *   state pending on its former CPU could be restored, corrupting
- *   the modifications.
+ * If the task has used the FPU before then unlazy it.
+ * If the task has not used the FPU before then initialize its fpstate.
  *
- *   This function can be used for the current task as well, but
- *   only for reading the fpstate. Modifications to the fpstate
- *   will be lost on eagerfpu systems. ]
- *
- * TODO: A future optimization would be to skip the unlazying in
- *       the read-only case, it's not strictly necessary for
- *       read-only access to the context.
+ * After this function call, after registers in the fpstate are
+ * modified and the child task has woken up, the child task will
+ * restore the modified FPU state from the modified context. If we
+ * didn't clear its lazy status here then the lazy in-registers
+ * state pending on its former CPU could be restored, corrupting
+ * the modifications.
  */
 void fpu__activate_fpstate_write(struct fpu *fpu)
 {
 	/*
-	 * If fpregs are active (in the current CPU), then
-	 * copy them to the fpstate:
+	 * Only stopped child tasks can be used to modify the FPU
+	 * state in the fpstate buffer:
 	 */
-	if (fpu->fpregs_active) {
-		fpu__save(fpu);
+	WARN_ON_FPU(fpu == &current->thread.fpu);
+
+	if (fpu->fpstate_active) {
+		/* Invalidate any lazy state: */
+		fpu->last_cpu = -1;
 	} else {
-		if (fpu->fpstate_active) {
-			/* Invalidate any lazy state: */
-			fpu->last_cpu = -1;
-		} else {
-			fpstate_init(&fpu->state);
+		fpstate_init(&fpu->state);
 
-			/* Safe to do for current and for stopped child tasks: */
-			fpu->fpstate_active = 1;
-		}
+		/* Safe to do for stopped child tasks: */
+		fpu->fpstate_active = 1;
 	}
 }
 
--
To unsubscribe from this list: send the line "unsubscribe linux-tip-commits" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Stable Commits]     [Linux Stable Kernel]     [Linux Kernel]     [Linux USB Devel]     [Linux Video &Media]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux