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