linux-mips
[Top] [All Lists]

ieee754_csr and smp (again)

To: linux-mips@oss.sgi.com
Subject: ieee754_csr and smp (again)
From: Jun Sun <jsun@mvista.com>
Date: Wed, 17 Apr 2002 17:30:17 -0700
Sender: owner-linux-mips@oss.sgi.com
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.4) Gecko/20011126 Netscape6/6.2.1
OK, ieee754_csr is a global variable and it screws up fpu emulation code under smp.

I have a patch that makes the problem go away. It basically transform this variable into an array of global variables. Each cpu only uses one of the elements. See the attachment.

That patch works, but I think there might be a better fix. Looking through the code, I am rather confused by the usage of this variable. Hopefully someone with more better knowledge can help me out here.

. should ieee754_csr be a per-thread variable? If yes, we should just use the current->thread->xxx instead of this global variable.

. what is ieee754_csr for anyway?

. Some of the fields in ieee754_csr (such as nod, rm, cx) gets set in fpu_emulator_cop1Handler(). But what about others?

. I can't find anywhere we write iee754_csr back to the current->thread structure. Do I miss anything?

Thanks.

Jun
Copy from the patch checked into our EAP.  This
is still a little hackish.  Hopefully we can settle it better later.
A per-cpu page would be nice so that we don't have declare arrays.

BTW, ralf thinks ieee754_csr should belong to per thread fpu structure.
I check it in now anyway so that we have some reliable for running.

Jun

diff -Nru smp/arch/mips/kernel/traps.c.orig smp/arch/mips/kernel/traps.c
--- smp/arch/mips/kernel/traps.c.orig   Wed Feb 13 16:23:12 2002
+++ smp/arch/mips/kernel/traps.c        Thu Apr 11 15:46:11 2002
@@ -678,14 +678,11 @@
        return;
 
 fp_emul:
-       if (last_task_used_math != current) {
-               if (!current->used_math) {
-                       fpu_emulator_init_fpu();
-                       current->used_math = 1;
-               }
+       if (!current->used_math) {
+               fpu_emulator_init_fpu();
+               current->used_math = 1;
        }
        sig = fpu_emulator_cop1Handler(regs);
-       last_task_used_math = current;
        if (sig)
                force_sig(sig, current);
        return;
diff -Nru smp/arch/mips/math-emu/ieee754.h.orig smp/arch/mips/math-emu/ieee754.h
--- smp/arch/mips/math-emu/ieee754.h.orig       Tue Jan 22 17:11:40 2002
+++ smp/arch/mips/math-emu/ieee754.h    Thu Apr 11 15:46:11 2002
@@ -323,7 +323,7 @@
 
 /* the control status register 
 */
-struct ieee754_csr {
+struct ieee754_csr_struct {
        unsigned pad:13;
        unsigned nod:1;         /* set 1 for no denormalised numbers */
        unsigned cx:5;          /* exceptions this operation */
@@ -331,7 +331,13 @@
        unsigned sx:5;          /* exceptions total */
        unsigned rm:2;          /* current rounding mode */
 };
-extern struct ieee754_csr ieee754_csr;
+
+#include <linux/sched.h>
+#include <linux/threads.h>
+#include <linux/smp.h>
+#include <asm/current.h>
+extern struct ieee754_csr_struct ieee754_csr_array[NR_CPUS];
+#define        ieee754_csr ieee754_csr_array[smp_processor_id()]
 
 static __inline unsigned ieee754_getrm(void)
 {
diff -Nru smp/arch/mips/math-emu/ieee754.c.orig smp/arch/mips/math-emu/ieee754.c
--- smp/arch/mips/math-emu/ieee754.c.orig       Tue Jan 15 13:25:24 2002
+++ smp/arch/mips/math-emu/ieee754.c    Thu Apr 11 15:46:11 2002
@@ -52,7 +52,7 @@
 
 /* the control status register 
 */
-struct ieee754_csr ieee754_csr;
+struct ieee754_csr_struct ieee754_csr_array[NR_CPUS];
 
 /* special constants
 */
diff -Nru smp/arch/mips/math-emu/cp1emu.c.orig smp/arch/mips/math-emu/cp1emu.c
--- smp/arch/mips/math-emu/cp1emu.c.orig        Tue Jan 15 13:25:24 2002
+++ smp/arch/mips/math-emu/cp1emu.c     Thu Apr 11 15:46:12 2002
@@ -945,7 +945,7 @@
 static ieee754##p fpemu_##p##_##name (ieee754##p r, ieee754##p s, \
     ieee754##p t) \
 { \
-    struct ieee754_csr ieee754_csr_save; \
+    struct ieee754_csr_struct ieee754_csr_save; \
     s = f1 (s, t); \
     ieee754_csr_save = ieee754_csr; \
     s = f2 (s, r); \
diff -Nru smp/arch/mips/math-emu/dp_sqrt.c.orig smp/arch/mips/math-emu/dp_sqrt.c
--- smp/arch/mips/math-emu/dp_sqrt.c.orig       Tue Jan 15 13:25:24 2002
+++ smp/arch/mips/math-emu/dp_sqrt.c    Thu Apr 11 15:46:12 2002
@@ -37,7 +37,7 @@
 
 ieee754dp ieee754dp_sqrt(ieee754dp x)
 {
-       struct ieee754_csr oldcsr;
+       struct ieee754_csr_struct oldcsr;
        ieee754dp y, z, t;
        unsigned scalx, yh;
        COMPXDP;
<Prev in Thread] Current Thread [Next in Thread>
  • ieee754_csr and smp (again), Jun Sun <=