x86/fpu: Clean up FPU switching in the middle of task switching
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 18 Oct 2023 18:41:58 +0000 (20:41 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 20 Oct 2023 09:24:22 +0000 (11:24 +0200)
commit24b8a23638cbf92449c353f828b1d309548c78f4
treeea69830f0ac605520d2ee26f36ccd106d412a32d
parente39828d2c1c0781ccfcf742791daf88fdfa481ea
x86/fpu: Clean up FPU switching in the middle of task switching

It happens to work, but it's very very wrong, because our 'current'
macro is magic that is supposedly loading a stable value.

It just happens to be not quite stable enough and the compilers
re-load the value enough for this code to work.  But it's wrong.

The whole

        struct fpu *prev_fpu = &prev->fpu;

thing in __switch_to() is pretty ugly. There's no reason why we
should look at that 'prev_fpu' pointer there, or pass it down.

And it only generates worse code, in how it loads 'current' when
__switch_to() has the right task pointers.

The attached patch not only cleans this up, it actually
generates better code too:

 (a) it removes one push/pop pair at entry/exit because there's one
     less register used (no 'current')

 (b) it removes that pointless load of 'current' because it just uses
     the right argument:

-       movq    %gs:pcpu_hot(%rip), %r12
-       testq   $16384, (%r12)
+       testq   $16384, (%rdi)

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Uros Bizjak <ubizjak@gmail.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: https://lore.kernel.org/r/20231018184227.446318-1-ubizjak@gmail.com
arch/x86/include/asm/fpu/sched.h
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c