RE: Floating point corruption: followup
David Mosberger <[email protected]> Thu, 8 May 2003 15:35:28 -0700
| Newsgroups | gmane.linux.redhat.ia64.general |
|---|---|
| Message-ID | <[email protected]> |
>>>>> On Thu, 8 May 2003 17:01:02 -0500, [email protected] said: Mike> If you are interested in demonstrating this, I can provide Mike> some example instructions. Yes, the problem is understood now (it sounds like several people were pursuing this, don't know if it was discovered independently or not). See the discussion here: https://lists.linuxia64.org/archives//linux-ia64/2003-May/005418.html I'm currently using the attached patch to fix the problem, but it clearly needs more testing. --david ===== include/asm-ia64/system.h 1.34 vs edited ===== --- 1.34/include/asm-ia64/system.h Tue Apr 1 01:19:53 2003 +++ edited/include/asm-ia64/system.h Thu May 8 14:52:49 2003 @@ -213,6 +213,7 @@ #endif #define __switch_to(prev,next,last) do { \ + ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next)); \ if (((prev)->thread.flags & (IA64_THREAD_DBG_VALID|IA64_THREAD_PM_VALID)) \ || IS_IA32_PROCESS(ia64_task_regs(prev)) || PERFMON_IS_SYSWIDE()) \ ia64_save_extra(prev); \ @@ -223,13 +224,11 @@ } while (0) #ifdef CONFIG_SMP - /* - * In the SMP case, we save the fph state when context-switching - * away from a thread that modified fph. This way, when the thread - * gets scheduled on another CPU, the CPU can pick up the state from - * task->thread.fph, avoiding the complication of having to fetch - * the latest fph state from another CPU. + * In the SMP case, we save the fph state when context-switching away from a thread that + * modified fph. This way, when the thread gets scheduled on another CPU, the CPU can + * pick up the state from task->thread.fph, avoiding the complication of having to fetch + * the latest fph state from another CPU. In other words: eager save, lazy restore. */ # define switch_to(prev,next,last) do { \ if (ia64_psr(ia64_task_regs(prev))->mfh) { \ @@ -238,22 +237,10 @@ __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); \ + __switch_to(prev, next, last); \ } while (0) #else -# define switch_to(prev,next,last) do { \ - ia64_psr(ia64_task_regs(next))->dfh = (ia64_get_fpu_owner() != (next)); \ - __switch_to(prev,next,last); \ -} while (0) +# define switch_to(prev,next,last) __switch_to(prev, next, last) #endif /*