[S390] switch_to: dont restore/save access & fpu regs for kernel threads
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 25 Oct 2010 14:10:18 +0000 (16:10 +0200)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>
Mon, 25 Oct 2010 14:10:16 +0000 (16:10 +0200)
If the previous task was a kernel thread there is no need to save the
contents of the fpu and access registers since they aren't used in
kernel mode.
For the same reason it is not necessary to restore these registers if
the next task is a kernel thread.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/system.h

index 1f2ebc4afd828f47da56d6763be4a16ba713263c..c35d0a383f0015759efb8ecf6f2eedfba343c385 100644 (file)
@@ -85,14 +85,18 @@ static inline void restore_access_regs(unsigned int *acrs)
        asm volatile("lam 0,15,%0" : : "Q" (*acrs));
 }
 
-#define switch_to(prev,next,last) do {                                      \
-       if (prev == next)                                                    \
-               break;                                                       \
-       save_fp_regs(&prev->thread.fp_regs);                                 \
-       restore_fp_regs(&next->thread.fp_regs);                              \
-       save_access_regs(&prev->thread.acrs[0]);                             \
-       restore_access_regs(&next->thread.acrs[0]);                          \
-       prev = __switch_to(prev,next);                                       \
+#define switch_to(prev,next,last) do {                                 \
+       if (prev == next)                                               \
+               break;                                                  \
+       if (prev->mm) {                                                 \
+               save_fp_regs(&prev->thread.fp_regs);                    \
+               save_access_regs(&prev->thread.acrs[0]);                \
+       }                                                               \
+       if (next->mm) {                                                 \
+               restore_fp_regs(&next->thread.fp_regs);                 \
+               restore_access_regs(&next->thread.acrs[0]);             \
+       }                                                               \
+       prev = __switch_to(prev,next);                                  \
 } while (0)
 
 extern void account_vtime(struct task_struct *, struct task_struct *);