Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/sgimips/sgimips Fix nasty crashes on IP22 machines ...



details:   https://anonhg.NetBSD.org/src/rev/1448d835b2af
branches:  trunk
changeset: 526238:1448d835b2af
user:      rafal <rafal%NetBSD.org@localhost>
date:      Mon Apr 29 02:06:14 2002 +0000

description:
Fix nasty crashes on IP22 machines with console running at 38.4kbps (which
generally translates to "high interrupt load") -- the old code re-enabled
interrupts in the machine-specific hardware interrupt handler causing the
handler to be re-entered, possible multiple times.  Could lead to kernel
stack overflows, and all sorts of mysterious crashes/hangs as a result.

While here, fix up the IP32 interrupt handler code to also not re-enable
interrupts.

Thanks for ideas/comments go to Chuq and Stephen Ma.

diffstat:

 sys/arch/sgimips/sgimips/ip22.c    |  15 ++++++++++++---
 sys/arch/sgimips/sgimips/ip32.c    |  13 +++++++++++--
 sys/arch/sgimips/sgimips/machdep.c |  15 ++++++++++++---
 3 files changed, 35 insertions(+), 8 deletions(-)

diffs (135 lines):

diff -r 93e8b212336a -r 1448d835b2af sys/arch/sgimips/sgimips/ip22.c
--- a/sys/arch/sgimips/sgimips/ip22.c   Mon Apr 29 01:54:11 2002 +0000
+++ b/sys/arch/sgimips/sgimips/ip22.c   Mon Apr 29 02:06:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip22.c,v 1.8 2002/03/13 13:12:29 simonb Exp $  */
+/*     $NetBSD: ip22.c,v 1.9 2002/04/29 02:06:14 rafal Exp $   */
 
 /*
  * Copyright (c) 2001 Rafal K. Boni
@@ -46,6 +46,9 @@
 static struct evcnt mips_int5_evcnt =
     EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 5 (clock)");
 
+static struct evcnt mips_spurint_evcnt =
+    EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "spurious interrupts");
+
 static u_int32_t iocwrite;     /* IOC write register: read-only */
 static u_int32_t iocreset;     /* IOC reset register: read-only */
 
@@ -60,7 +63,7 @@
 int            ip22_local0_intr(void);
 int            ip22_local1_intr(void);
 int            ip22_mappable_intr(void *);
-void           ip22_intr(u_int, u_int, u_int, u_int);
+void           ip22_intr(u_int, u_int, u_int, u_int);
 void           ip22_intr_establish(int, int, int (*)(void *), void *);
 
 unsigned long  ip22_clkread(void);
@@ -180,6 +183,7 @@
        ticks_per_usec = cps * hz / 1000000;
 
        evcnt_attach_static(&mips_int5_evcnt);
+       evcnt_attach_static(&mips_spurint_evcnt);
 }
 
 void
@@ -189,6 +193,10 @@
        *(volatile u_int32_t *)MIPS_PHYS_TO_KSEG1(0x1fa000fc) = 0;
 }
 
+/*
+ * NB: Do not re-enable interrupts here -- reentrancy here can cause all
+ * sorts of Bad Things(tm) to happen, including kernel stack overflows.
+ */
 void
 ip22_intr(status, cause, pc, ipending)
        u_int32_t status;
@@ -235,7 +243,8 @@
                cause &= ~MIPS_INT_MASK_4;
        }
 
-       _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
+       if (cause & status & MIPS_HARD_INT_MASK) 
+               mips_spurint_evcnt.ev_count++;
 }
 
 int
diff -r 93e8b212336a -r 1448d835b2af sys/arch/sgimips/sgimips/ip32.c
--- a/sys/arch/sgimips/sgimips/ip32.c   Mon Apr 29 01:54:11 2002 +0000
+++ b/sys/arch/sgimips/sgimips/ip32.c   Mon Apr 29 02:06:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip32.c,v 1.7 2002/03/13 13:12:29 simonb Exp $  */
+/*     $NetBSD: ip32.c,v 1.8 2002/04/29 02:06:14 rafal Exp $   */
 
 /*
  * Copyright (c) 2000 Soren S. Jorvang
@@ -55,6 +55,9 @@
 static struct evcnt mips_int5_evcnt =
     EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "int 5 (clock)");
 
+static struct evcnt mips_spurint_evcnt =
+    EVCNT_INITIALIZER(EVCNT_TYPE_INTR, NULL, "mips", "spurious interrupts");
+
 static unsigned long ticks_per_hz;
 
 void ip32_init(void)
@@ -75,6 +78,7 @@
        clockmask = 0xff00;
 
        evcnt_attach_static(&mips_int5_evcnt);
+       evcnt_attach_static(&mips_spurint_evcnt);
 }
 
 void
@@ -83,6 +87,10 @@
        /* do nothing */
 }
 
+/*
+ * NB: Do not re-enable interrupts here -- reentrancy here can cause all
+ * sorts of Bad Things(tm) to happen, including kernel stack overflows.
+ */
 void
 ip32_intr(status, cause, pc, ipending)
        u_int32_t status;
@@ -143,7 +151,8 @@
                                        cause &= ~(MIPS_INT_MASK_0 << i);
        }
 
-       _splset((status & ~cause & MIPS_HARD_INT_MASK) | MIPS_SR_INT_IE);
+       if (cause & status & MIPS_HARD_INT_MASK) 
+               mips_spurint_evcnt.ev_count++;
 }
 
 void
diff -r 93e8b212336a -r 1448d835b2af sys/arch/sgimips/sgimips/machdep.c
--- a/sys/arch/sgimips/sgimips/machdep.c        Mon Apr 29 01:54:11 2002 +0000
+++ b/sys/arch/sgimips/sgimips/machdep.c        Mon Apr 29 02:06:14 2002 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.34 2002/03/13 13:12:29 simonb Exp $      */
+/*     $NetBSD: machdep.c,v 1.35 2002/04/29 02:06:14 rafal Exp $       */
 
 /*
  * Copyright (c) 2000 Soren S. Jorvang
@@ -836,9 +836,18 @@
        if (ipending & MIPS_HARD_INT_MASK)
                (*platform.iointr)(status, cause, pc, ipending);
 
+       /*
+        * Service pending soft interrupts -- make sure to re-enable
+        * only those hardware interrupts that are not masked and 
+        * that weren't pending on the current invocation of the
+        * interrupt handler, else we risk infinite stack growth
+        * due to nested interrupts.
+        */
        /* software simulated interrupt */
-       if ((ipending & MIPS_SOFT_INT_MASK_1)
-                   || (ssir && (status & MIPS_SOFT_INT_MASK_1))) {
+       if ((ipending & MIPS_SOFT_INT_MASK_1) || 
+           (ssir && (status & MIPS_SOFT_INT_MASK_1))) {
+               _splset(MIPS_SR_INT_IE |
+                           (status & ~ipending & MIPS_HARD_INT_MASK));
                _clrsoftintr(MIPS_SOFT_INT_MASK_1);
                softintr_dispatch();
        }



Home | Main Index | Thread Index | Old Index