x86/fpu: Optimize fpu__activate_fpstate_write()
[firefly-linux-kernel-4.4.55.git] / arch / x86 / kernel / fpu / core.c
index 6b0955a62d340c36d57f82410594b3259b7b408f..86a9a9a086fad3704291148c7c458dd795fb2ae1 100644 (file)
@@ -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;
        }
 }