linux-mips
[Top] [All Lists]

FP exception statistics

To: linux-mips@oss.sgi.com
Subject: FP exception statistics
From: Atsushi Nemoto <nemoto@toshiba-tops.co.jp>
Date: Wed, 21 Nov 2001 16:03:47 +0900 (JST)
Cc: ralf@oss.sgi.com
Organization: TOSHIBA Personal Computer System Corporation
Sender: owner-linux-mips@oss.sgi.com
Sometimes I want to know what kind of (and how many times) FP
exceptions occurred in run time.  Here is a patch to provide us these
informations via /proc/cpuinfo.

Any comments are welcome.  (This patch is not tested on SMP)

diff -ur linux-sgi-cvs/arch/mips/config.in linux.new/arch/mips/config.in
--- linux-sgi-cvs/arch/mips/config.in   Wed Nov 21 10:31:56 2001
+++ linux.new/arch/mips/config.in       Wed Nov 21 15:45:44 2001
@@ -359,6 +359,7 @@
 else
    bool 'Generate little endian code' CONFIG_CPU_LITTLE_ENDIAN
 fi
+bool 'Support for FPU Exception statistics' CONFIG_MIPS_FPE_STATS
 
 if [ "$CONFIG_PROC_FS" = "y" ]; then
    define_bool CONFIG_KCORE_ELF y
diff -ur linux-sgi-cvs/arch/mips/kernel/proc.c linux.new/arch/mips/kernel/proc.c
--- linux-sgi-cvs/arch/mips/kernel/proc.c       Mon Oct 22 10:29:56 2001
+++ linux.new/arch/mips/kernel/proc.c   Wed Nov 21 15:43:24 2001
@@ -19,6 +19,10 @@
 #ifndef CONFIG_CPU_HAS_LLSC
 unsigned long ll_ops, sc_ops;
 #endif
+#ifdef CONFIG_MIPS_FPE_STATS
+unsigned int fpu_exceptions[6];
+static char fpe_types[6] = {'I', 'U', 'O', 'Z', 'V', 'E'};
+#endif
 
 /*
  * BUFFER is PAGE_SIZE bytes long.
@@ -61,6 +65,9 @@
                mach_nec_vr41xx_names};
        unsigned int version = read_32bit_cp0_register(CP0_PRID);
        int len;
+#ifdef CONFIG_MIPS_FPE_STATS
+       int i;
+#endif
 
        len = sprintf(buffer, "cpu\t\t\t: MIPS\n");
        len += sprintf(buffer + len, "cpu model\t\t: %s V%d.%d\n",
@@ -101,6 +108,14 @@
                       ll_ops);
        len += sprintf(buffer + len, "sc emulations\t\t: %lu\n",
                       sc_ops);
+#endif
+#ifdef CONFIG_MIPS_FPE_STATS
+       len += sprintf(buffer + len, "fpu exceptions\t\t:");
+       for (i = 0; i < sizeof(fpu_exceptions) / sizeof(fpu_exceptions[0]); 
i++) {
+               len += sprintf(buffer + len, " %u(%c)",
+                              fpu_exceptions[i], fpe_types[i]);
+       }
+       len += sprintf(buffer + len, "\n");
 #endif
        return len;
 }
diff -ur linux-sgi-cvs/arch/mips/kernel/traps.c 
linux.new/arch/mips/kernel/traps.c
--- linux-sgi-cvs/arch/mips/kernel/traps.c      Wed Nov 21 10:31:57 2001
+++ linux.new/arch/mips/kernel/traps.c  Wed Nov 21 15:46:15 2001
@@ -461,6 +461,18 @@
  */
 asmlinkage void do_fpe(struct pt_regs *regs, unsigned long fcr31)
 {
+#ifdef CONFIG_MIPS_FPE_STATS
+       extern unsigned int fpu_exceptions[];
+       unsigned char fpe;
+       int i;
+       fpe = ((fcr31 & FPU_CSR_ALL_X) / FPU_CSR_INE_X) &
+               ((fcr31 | ~FPU_CSR_ALL_E) / FPU_CSR_INE_E);
+       for (i = 0; i < 6; i++) {
+               if (fpe & (1 << i))
+                       fpu_exceptions[i]++;
+       }
+#endif
+
        if (fcr31 & FPU_CSR_UNI_X) {
                extern void save_fp(struct task_struct *);
                extern void restore_fp(struct task_struct *);
---
Atsushi Nemoto

<Prev in Thread] Current Thread [Next in Thread>