]> git.neil.brown.name Git - history.git/commitdiff
ia64: Make fph-restore lazy. Patch by Asit K. Mallick.
authorDavid Mosberger <davidm@tiger.hpl.hp.com>
Mon, 12 Aug 2002 09:10:32 +0000 (02:10 -0700)
committerDavid Mosberger <davidm@wailua.hpl.hp.com>
Mon, 12 Aug 2002 09:10:32 +0000 (02:10 -0700)
arch/ia64/kernel/traps.c
include/asm-ia64/processor.h
include/asm-ia64/system.h

index 37a53502934e033b3aedd770702fc341794889f7..5ee868cdb31152f8c3da45da2d4e5f3e7003504e 100644 (file)
@@ -248,10 +248,9 @@ disabled_fph_fault (struct pt_regs *regs)
 
                if (fpu_owner)
                        ia64_flush_fph(fpu_owner);
-
-               ia64_set_fpu_owner(current);
        }
 #endif /* !CONFIG_SMP */
+       ia64_set_fpu_owner(current);
        if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
                __ia64_load_fpu(current->thread.fph);
                psr->mfh = 0;
index 21535bda51e387e985342167b8659c2e1d232830..a2065b195fefee4618acba2241af16cd43c69cef 100644 (file)
@@ -223,6 +223,7 @@ struct thread_struct {
        __u64 map_base;                 /* base address for get_unmapped_area() */
        __u64 task_size;                /* limit for task size */
        struct siginfo *siginfo;        /* current siginfo struct for ptrace() */
+       __u64 last_fph_cpu;             /* CPU that may hold the contents of f32-f127 */
 
 #ifdef CONFIG_IA32_SUPPORT
        __u64 eflag;                    /* IA32 EFLAGS reg */
@@ -389,8 +390,6 @@ ia64_set_kr (unsigned long regnum, unsigned long r)
        }
 }
 
-#ifndef CONFIG_SMP
-
 static inline struct task_struct *
 ia64_get_fpu_owner (void)
 {
@@ -403,8 +402,6 @@ ia64_set_fpu_owner (struct task_struct *t)
        ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) t);
 }
 
-#endif /* !CONFIG_SMP */
-
 extern void __ia64_init_fpu (void);
 extern void __ia64_save_fpu (struct ia64_fpreg *fph);
 extern void __ia64_load_fpu (struct ia64_fpreg *fph);
index 4a944ee66020cd6dab43817e95933e6dd551e6d3..44d7fda7efd85c0296dbb78dffd4aa49eb6effa4 100644 (file)
@@ -396,14 +396,23 @@ extern void ia64_load_extra (struct task_struct *task);
  * task->thread.fph, avoiding the complication of having to fetch
  * the latest fph state from another CPU.
  */
-# define switch_to(prev,next,last) do {                                                \
-       if (ia64_psr(ia64_task_regs(prev))->mfh) {                              \
-               ia64_psr(ia64_task_regs(prev))->mfh = 0;                        \
-               (prev)->thread.flags |= IA64_THREAD_FPH_VALID;                  \
-               __ia64_save_fpu((prev)->thread.fph);                            \
-       }                                                                       \
-       ia64_psr(ia64_task_regs(prev))->dfh = 1;                                \
-       __switch_to(prev,next,last);                                            \
+# define switch_to(prev,next,last) do {                                        \
+       if (ia64_psr(ia64_task_regs(prev))->mfh) {                      \
+               ia64_psr(ia64_task_regs(prev))->mfh = 0;                \
+               (prev)->thread.flags |= IA64_THREAD_FPH_VALID;          \
+               __ia64_save_fpu((prev)->thread.fph);                    \
+               (prev)->thread.last_fph_cpu = smp_processor_id();       \
+       }                                                               \
+       if ((next)->thread.flags & IA64_THREAD_FPH_VALID) {             \
+               if (((next)->thread.last_fph_cpu == smp_processor_id()) \
+                   && (ia64_get_fpu_owner() == next))                  \
+               {                                                       \
+                       ia64_psr(ia64_task_regs(next))->dfh = 0;        \
+                       ia64_psr(ia64_task_regs(next))->mfh = 0;        \
+               } else                                          \
+                       ia64_psr(ia64_task_regs(next))->dfh = 1;        \
+       }                                                               \
+       __switch_to(prev,next,last);                                    \
   } while (0)
 #else
 # define switch_to(prev,next,last) do {                                                \