summaryrefslogtreecommitdiff
path: root/sys/arch/mips64
diff options
context:
space:
mode:
authorTakuya ASADA <syuu@cvs.openbsd.org>2009-11-26 23:32:47 +0000
committerTakuya ASADA <syuu@cvs.openbsd.org>2009-11-26 23:32:47 +0000
commit88462ef42deba06babae67a1c50b91f60063a010 (patch)
tree419fa11aee0c410639add45ddd52eb6b29278a2d /sys/arch/mips64
parent8b11e1432e0e80298847a164b1d8792a92603605 (diff)
Now IPI can interrupt to clock interrupt handler.
It prevents deadlock with TLB shootdown and clock interrupt. ok miod@
Diffstat (limited to 'sys/arch/mips64')
-rw-r--r--sys/arch/mips64/mips64/clock.c16
-rw-r--r--sys/arch/mips64/mips64/interrupt.c13
-rw-r--r--sys/arch/mips64/mips64/softintr.c8
3 files changed, 22 insertions, 15 deletions
diff --git a/sys/arch/mips64/mips64/clock.c b/sys/arch/mips64/mips64/clock.c
index 91c405be630..0cd58d1559c 100644
--- a/sys/arch/mips64/mips64/clock.c
+++ b/sys/arch/mips64/mips64/clock.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: clock.c,v 1.29 2009/11/22 22:15:25 syuu Exp $ */
+/* $OpenBSD: clock.c,v 1.30 2009/11/26 23:32:46 syuu Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -117,9 +117,13 @@ clockattach(struct device *parent, struct device *self, void *aux)
uint32_t
clock_int5(uint32_t mask, struct trap_frame *tf)
{
- u_int32_t clkdiff;
+ u_int32_t clkdiff, sr;
struct cpu_info *ci = curcpu();
+ /* Enable interrupts at this (hardware) level again */
+ sr = getsr();
+ updateimask(mask);
+
/*
* If we got an interrupt before we got ready to process it,
* retrigger it as far as possible. cpu_initclocks() will
@@ -127,6 +131,7 @@ clock_int5(uint32_t mask, struct trap_frame *tf)
*/
if (ci->ci_clock_started == 0) {
cp0_set_compare(cp0_get_count() - 1);
+ setsr(sr);
return CR_INT_5;
}
@@ -158,12 +163,19 @@ clock_int5(uint32_t mask, struct trap_frame *tf)
* Process clock interrupt unless it is currently masked.
*/
if (tf->ipl < IPL_CLOCK) {
+#ifdef MULTIPROCESSOR
+ __mp_lock(&kernel_lock);
+#endif
while (ci->ci_pendingticks) {
clk_count.ec_count++;
hardclock(tf);
ci->ci_pendingticks--;
}
+#ifdef MULTIPROCESSOR
+ __mp_unlock(&kernel_lock);
+#endif
}
+ setsr(sr);
return CR_INT_5; /* Clock is always on 5 */
}
diff --git a/sys/arch/mips64/mips64/interrupt.c b/sys/arch/mips64/mips64/interrupt.c
index 5f6717b34e1..5bd47a08a4c 100644
--- a/sys/arch/mips64/mips64/interrupt.c
+++ b/sys/arch/mips64/mips64/interrupt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interrupt.c,v 1.53 2009/11/22 00:31:03 syuu Exp $ */
+/* $OpenBSD: interrupt.c,v 1.54 2009/11/26 23:32:46 syuu Exp $ */
/*
* Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com)
@@ -114,12 +114,6 @@ interrupt(struct trap_frame *trapframe)
#ifdef DEBUG_INTERRUPT
trapdebug_enter(trapframe, 0);
#endif
-
-#ifdef MULTIPROCESSOR
- if (ci->ci_ipl < IPL_SCHED)
- __mp_lock(&kernel_lock);
-#endif
-
uvmexp.intrs++;
/* Mask out interrupts from cause that are unmasked */
@@ -152,11 +146,6 @@ interrupt(struct trap_frame *trapframe)
ci->ci_ipl = s; /* no-overhead splx */
__asm__ ("sync\n\t.set reorder\n");
}
-
-#ifdef MULTIPROCESSOR
- if (ci->ci_ipl < IPL_SCHED)
- __mp_unlock(&kernel_lock);
-#endif
}
diff --git a/sys/arch/mips64/mips64/softintr.c b/sys/arch/mips64/mips64/softintr.c
index c9244cf76e8..354480fe936 100644
--- a/sys/arch/mips64/mips64/softintr.c
+++ b/sys/arch/mips64/mips64/softintr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.c,v 1.7 2009/11/22 22:15:25 syuu Exp $ */
+/* $OpenBSD: softintr.c,v 1.8 2009/11/26 23:32:46 syuu Exp $ */
/* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */
/*
@@ -205,6 +205,9 @@ dosoftint()
struct cpu_info *ci = curcpu();
int sir, q, mask;
+ if (ci->ci_ipl < IPL_SCHED)
+ __mp_lock(&kernel_lock);
+
while ((sir = ci->ci_softpending) != 0) {
atomic_clearbits_int(&ci->ci_softpending, sir);
@@ -214,4 +217,7 @@ dosoftint()
softintr_dispatch(q);
}
}
+
+ if (ci->ci_ipl < IPL_SCHED)
+ __mp_unlock(&kernel_lock);
}