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.
This commit is contained in:
parent
2a4235ed84
commit
029ca90566
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: spl.S,v 1.2 2003/08/20 21:48:48 fvdl Exp $ */
|
||||
/* $NetBSD: spl.S,v 1.3 2004/06/28 09:13:11 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003 Wasabi Systems, Inc.
|
||||
|
@ -136,10 +136,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:
|
||||
|
@ -166,10 +164,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. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vector.S,v 1.4 2004/06/15 11:28:23 fvdl Exp $ */
|
||||
/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001 Wasabi Systems, Inc.
|
||||
|
@ -298,8 +298,6 @@ IDTVEC(recurse_lapic_ipi)
|
|||
pushq $0
|
||||
pushq $T_ASTFLT
|
||||
INTRENTRY
|
||||
IDTVEC(resume_lapic_ipi)
|
||||
cli
|
||||
jmp 1f
|
||||
IDTVEC(intr_lapic_ipi)
|
||||
pushq $0
|
||||
|
@ -309,6 +307,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)
|
||||
|
@ -346,8 +345,6 @@ IDTVEC(recurse_lapic_ltimer)
|
|||
pushq $0
|
||||
pushq $T_ASTFLT
|
||||
INTRENTRY
|
||||
IDTVEC(resume_lapic_ltimer)
|
||||
cli
|
||||
jmp 1f
|
||||
IDTVEC(intr_lapic_ltimer)
|
||||
pushq $0
|
||||
|
@ -357,6 +354,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)
|
||||
|
@ -757,6 +755,7 @@ _C_LABEL(eintrcnt):
|
|||
|
||||
IDTVEC(softserial)
|
||||
movl $IPL_SOFTSERIAL, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
@ -773,6 +772,7 @@ IDTVEC(softserial)
|
|||
|
||||
IDTVEC(softnet)
|
||||
movl $IPL_SOFTNET, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
@ -802,6 +802,7 @@ IDTVEC(softnet)
|
|||
|
||||
IDTVEC(softclock)
|
||||
movl $IPL_SOFTCLOCK, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: spl.S,v 1.10 2004/05/13 12:27:38 yamt Exp $ */
|
||||
/* $NetBSD: spl.S,v 1.11 2004/06/28 09:13:12 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||
|
@ -109,10 +109,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
|
||||
movl CPUVAR(ISOURCES)(,%eax,4),%eax
|
||||
jmp *IS_RECURSE(%eax)
|
||||
2:
|
||||
|
@ -143,10 +141,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
|
||||
movl CPUVAR(ISOURCES)(,%eax, 4),%eax
|
||||
jmp *IS_RESUME(%eax)
|
||||
2: /* Check for ASTs on exit to user mode. */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: vector.S,v 1.14 2004/04/20 11:59:20 yamt Exp $ */
|
||||
/* $NetBSD: vector.S,v 1.15 2004/06/28 09:13:12 fvdl Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 2002 (c) Wasabi Systems, Inc.
|
||||
|
@ -156,8 +156,6 @@ IDTVEC(recurse_lapic_ipi)
|
|||
pushl $0
|
||||
pushl $T_ASTFLT
|
||||
INTRENTRY
|
||||
IDTVEC(resume_lapic_ipi)
|
||||
cli
|
||||
jmp 1f
|
||||
IDTVEC(intr_lapic_ipi)
|
||||
pushl $0
|
||||
|
@ -167,6 +165,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)
|
||||
|
@ -208,8 +207,6 @@ IDTVEC(recurse_lapic_ltimer)
|
|||
pushl $0
|
||||
pushl $T_ASTFLT
|
||||
INTRENTRY
|
||||
IDTVEC(resume_lapic_ltimer)
|
||||
cli
|
||||
jmp 1f
|
||||
IDTVEC(intr_lapic_ltimer)
|
||||
pushl $0
|
||||
|
@ -219,6 +216,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)
|
||||
|
@ -624,6 +622,7 @@ _C_LABEL(eintrcnt):
|
|||
|
||||
IDTVEC(softserial)
|
||||
movl $IPL_SOFTSERIAL, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
@ -642,6 +641,7 @@ IDTVEC(softserial)
|
|||
|
||||
IDTVEC(softnet)
|
||||
movl $IPL_SOFTNET, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
@ -673,6 +673,7 @@ IDTVEC(softnet)
|
|||
|
||||
IDTVEC(softclock)
|
||||
movl $IPL_SOFTCLOCK, CPUVAR(ILEVEL)
|
||||
sti
|
||||
incl CPUVAR(IDEPTH)
|
||||
#ifdef MULTIPROCESSOR
|
||||
call _C_LABEL(x86_softintlock)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: intr.h,v 1.12 2004/03/04 19:10:10 dbj Exp $ */
|
||||
/* $NetBSD: intr.h,v 1.13 2004/06/28 09:13:12 fvdl Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
|
||||
|
@ -156,16 +156,21 @@ static __inline void
|
|||
spllower(int nlevel)
|
||||
{
|
||||
struct cpu_info *ci = curcpu();
|
||||
u_int32_t imask;
|
||||
u_long psl;
|
||||
|
||||
__splbarrier();
|
||||
/*
|
||||
* Since this should only lower the interrupt level,
|
||||
* the XOR below should only show interrupts that
|
||||
* are being unmasked.
|
||||
*/
|
||||
ci->ci_ilevel = nlevel;
|
||||
if (ci->ci_ipending & IUNMASK(ci,nlevel))
|
||||
|
||||
imask = IUNMASK(ci, nlevel);
|
||||
psl = read_psl();
|
||||
disable_intr();
|
||||
if (ci->ci_ipending & imask) {
|
||||
Xspllower(nlevel);
|
||||
/* Xspllower does enable_intr() */
|
||||
} else {
|
||||
ci->ci_ilevel = nlevel;
|
||||
write_psl(psl);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue