diff options
author | Artur Grabowski <art@cvs.openbsd.org> | 2004-07-10 14:21:41 +0000 |
---|---|---|
committer | Artur Grabowski <art@cvs.openbsd.org> | 2004-07-10 14:21:41 +0000 |
commit | c4662898f8a5504d906d7e13522818a4aea8d0dd (patch) | |
tree | dfe5726ecd0a0e3309161255fa07b7aae41c4f32 /sys | |
parent | df85339a5d0f61f8da868668f60c6c049875f9fa (diff) |
From NetBSD:
date: 2004/06/28 09:13:11; author: fvdl; state: Exp; lines: +6 -5
Updaing ci_ilevel and testing ci_ipending must be done with all interrupts
off, or priority inversion can occur, which can lead to IPI deadlocks.
Leaves interrupts off for a bit longer, sadly, but with no noticeable
effects on the systems I tested on.
From YAMAMOTO Takashi.
Fixes the IPI rendezvous panics for me.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/intr.c | 21 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/spl.S | 6 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/vector.S | 13 |
3 files changed, 21 insertions, 19 deletions
diff --git a/sys/arch/amd64/amd64/intr.c b/sys/arch/amd64/amd64/intr.c index 5f605a9e642..63c199e55dd 100644 --- a/sys/arch/amd64/amd64/intr.c +++ b/sys/arch/amd64/amd64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.5 2004/06/28 02:14:11 deraadt Exp $ */ +/* $OpenBSD: intr.c,v 1.6 2004/07/10 14:21:40 art Exp $ */ /* $NetBSD: intr.c,v 1.3 2003/03/03 22:16:20 fvdl Exp $ */ /* @@ -52,6 +52,7 @@ #include <machine/i8259.h> #include <machine/cpu.h> #include <machine/pio.h> +#include <machine/cpufunc.h> #include "ioapic.h" #include "lapic.h" @@ -734,17 +735,21 @@ spllower(int nlevel) { int olevel; struct cpu_info *ci = curcpu(); + u_int32_t imask; + u_long psl; - /* - * Since this should only lower the interrupt level, - * the XOR below should only show interrupts that - * are being unmasked. - */ + imask = IUNMASK(ci, nlevel); olevel = ci->ci_ilevel; - if (ci->ci_ipending & IUNMASK(ci,nlevel)) + + psl = read_psl(); + disable_intr(); + + if (ci->ci_ipending & imask) { Xspllower(nlevel); - else + } else { ci->ci_ilevel = nlevel; + write_psl(psl); + } return (olevel); } diff --git a/sys/arch/amd64/amd64/spl.S b/sys/arch/amd64/amd64/spl.S index 7772f14205b..aa3be7b6e5f 100644 --- a/sys/arch/amd64/amd64/spl.S +++ b/sys/arch/amd64/amd64/spl.S @@ -1,4 +1,4 @@ -/* $NetBSD: spl.S,v 1.1 2003/04/26 18:39:32 fvdl Exp $ */ +/* $NetBSD: spl.S,v 1.3 2004/06/28 09:13:11 fvdl Exp $ */ /* * Copyright (c) 2003 Wasabi Systems, Inc. @@ -132,10 +132,8 @@ IDTVEC(spllower) cli andl CPUVAR(IPENDING),%eax # any non-masked bits left? jz 2f - sti bsrl %eax,%eax btrl %eax,CPUVAR(IPENDING) - jnc 1b movq CPUVAR(ISOURCES)(,%rax,8),%rax jmp *IS_RECURSE(%rax) 2: @@ -162,10 +160,8 @@ IDTVEC(doreti) cli andl CPUVAR(IPENDING),%eax jz 2f - sti bsrl %eax,%eax # slow, but not worth optimizing btrl %eax,CPUVAR(IPENDING) - jnc 1b # some intr cleared the in-memory bit movq CPUVAR(ISOURCES)(,%rax, 8),%rax jmp *IS_RESUME(%rax) 2: /* Check for ASTs on exit to user mode. */ diff --git a/sys/arch/amd64/amd64/vector.S b/sys/arch/amd64/amd64/vector.S index db35fbd1edd..e269c7f60ae 100644 --- a/sys/arch/amd64/amd64/vector.S +++ b/sys/arch/amd64/amd64/vector.S @@ -1,5 +1,5 @@ -/* $OpenBSD: vector.S,v 1.4 2004/06/28 01:52:24 deraadt Exp $ */ -/* $NetBSD: vector.S,v 1.2 2003/05/04 23:46:41 fvdl Exp $ */ +/* $OpenBSD: vector.S,v 1.5 2004/07/10 14:21:40 art Exp $ */ +/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -296,8 +296,6 @@ IDTVEC(recurse_lapic_ipi) pushq $0 pushq $T_ASTFLT INTRENTRY -IDTVEC(resume_lapic_ipi) - cli jmp 1f IDTVEC(intr_lapic_ipi) pushq $0 @@ -307,6 +305,7 @@ IDTVEC(intr_lapic_ipi) movl CPUVAR(ILEVEL),%ebx cmpl $IPL_IPI,%ebx jae 2f +IDTVEC(resume_lapic_ipi) 1: incl CPUVAR(IDEPTH) movl $IPL_IPI,CPUVAR(ILEVEL) @@ -329,8 +328,6 @@ IDTVEC(recurse_lapic_ltimer) pushq $0 pushq $T_ASTFLT INTRENTRY -IDTVEC(resume_lapic_ltimer) - cli jmp 1f IDTVEC(intr_lapic_ltimer) pushq $0 @@ -340,6 +337,7 @@ IDTVEC(intr_lapic_ltimer) movl CPUVAR(ILEVEL),%ebx cmpl $IPL_CLOCK,%ebx jae 2f +IDTVEC(resume_lapic_ltimer) 1: incl CPUVAR(IDEPTH) movl $IPL_CLOCK,CPUVAR(ILEVEL) @@ -750,6 +748,7 @@ _C_LABEL(netisr): IDTVEC(softserial) movl $IPL_SOFTSERIAL, CPUVAR(ILEVEL) + sti incl CPUVAR(IDEPTH) #ifdef MULTIPROCESSOR call _C_LABEL(x86_softintlock) @@ -766,6 +765,7 @@ IDTVEC(softserial) IDTVEC(softnet) movl $IPL_SOFTNET, CPUVAR(ILEVEL) + sti incl CPUVAR(IDEPTH) #ifdef MULTIPROCESSOR call _C_LABEL(x86_softintlock) @@ -795,6 +795,7 @@ IDTVEC(softnet) IDTVEC(softclock) movl $IPL_SOFTCLOCK, CPUVAR(ILEVEL) + sti incl CPUVAR(IDEPTH) #ifdef MULTIPROCESSOR call _C_LABEL(x86_softintlock) |