to determine if an interrupt needs to grab the kernel lock or not,

check interrupt's own ipl rather than cpu's current ipl.
This commit is contained in:
yamt 2004-10-23 21:24:05 +00:00
parent 40efd0eeef
commit fa29ea9740
4 changed files with 41 additions and 41 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vector.S,v 1.5 2004/06/28 09:13:11 fvdl Exp $ */
/* $NetBSD: vector.S,v 1.6 2004/10/23 21:24:05 yamt Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -369,13 +369,6 @@ IDTVEC(resume_lapic_ltimer)
INTRFASTEXIT
#endif /* NLAPIC > 0 */
#ifdef MULTIPROCESSOR
#define LOCK_KERNEL movq %rsp,%rdi ; call _C_LABEL(x86_intlock)
#define UNLOCK_KERNEL movq %rsp,%rdi ; call _C_LABEL(x86_intunlock)
#else
#define LOCK_KERNEL
#define UNLOCK_KERNEL
#endif
#define voidop(num)
@ -418,7 +411,6 @@ IDTVEC(intr_/**/name/**/num) ;\
sti ;\
incl CPUVAR(IDEPTH) ;\
movq IS_HANDLERS(%r14),%rbx ;\
LOCK_KERNEL ;\
6: \
movl IH_LEVEL(%rbx),%r12d ;\
cmpl %r13d,%r12d ;\
@ -430,14 +422,12 @@ IDTVEC(intr_/**/name/**/num) ;\
testq %rbx,%rbx ;\
jnz 6b ;\
5: \
UNLOCK_KERNEL ;\
cli ;\
unmask(num) /* unmask it in hardware */ ;\
late_ack(num) ;\
sti ;\
jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\
7: \
UNLOCK_KERNEL ;\
cli ;\
orl $(1 << num),CPUVAR(IPENDING) ;\
level_mask(num) ;\

View File

@ -1,4 +1,4 @@
/* $NetBSD: vector.S,v 1.16 2004/07/07 01:03:57 mycroft Exp $ */
/* $NetBSD: vector.S,v 1.17 2004/10/23 21:24:05 yamt Exp $ */
/*
* Copyright 2002 (c) Wasabi Systems, Inc.
@ -232,13 +232,6 @@ IDTVEC(resume_lapic_ltimer)
INTRFASTEXIT
#endif /* NLAPIC > 0 */
#ifdef MULTIPROCESSOR
#define LOCK_KERNEL pushl %esp ; call _C_LABEL(x86_intlock) ; addl $4,%esp
#define UNLOCK_KERNEL pushl %esp ; call _C_LABEL(x86_intunlock) ; addl $4,%esp
#else
#define LOCK_KERNEL
#define UNLOCK_KERNEL
#endif
#define voidop(num)
@ -284,7 +277,6 @@ IDTVEC(intr_/**/name/**/num) ;\
sti ;\
incl CPUVAR(IDEPTH) ;\
movl IS_HANDLERS(%ebp),%ebx ;\
LOCK_KERNEL ;\
6: \
movl IH_LEVEL(%ebx),%edi ;\
cmpl %esi,%edi ;\
@ -298,14 +290,12 @@ IDTVEC(intr_/**/name/**/num) ;\
testl %ebx,%ebx ;\
jnz 6b ;\
5: \
UNLOCK_KERNEL ;\
cli ;\
unmask(num) /* unmask it in hardware */ ;\
late_ack(num) ;\
sti ;\
jmp _C_LABEL(Xdoreti) /* lower spl and do ASTs */ ;\
7: \
UNLOCK_KERNEL ;\
cli ;\
orl $(1 << num),CPUVAR(IPENDING) ;\
level_mask(num) ;\

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.h,v 1.13 2004/06/28 09:13:12 fvdl Exp $ */
/* $NetBSD: intr.h,v 1.14 2004/10/23 21:24:05 yamt Exp $ */
/*-
* Copyright (c) 1998, 2001 The NetBSD Foundation, Inc.
@ -102,6 +102,8 @@ struct intrhand {
int (*ih_fun)(void *);
void *ih_arg;
int ih_level;
int (*ih_realfun)(void *);
void *ih_realarg;
struct intrhand *ih_next;
int ih_pin;
int ih_slot;

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.18 2004/08/20 14:12:52 wennmach Exp $ */
/* $NetBSD: intr.c,v 1.19 2004/10/23 21:24:05 yamt Exp $ */
/*
* Copyright 2002 (c) Wasabi Systems, Inc.
@ -104,7 +104,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.18 2004/08/20 14:12:52 wennmach Exp $");
__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.19 2004/10/23 21:24:05 yamt Exp $");
#include "opt_multiprocessor.h"
@ -516,6 +516,29 @@ found:
return 0;
}
#ifdef MULTIPROCESSOR
static int intr_biglock_wrapper(void *);
/*
* intr_biglock_wrapper: grab biglock and call a real interrupt handler.
*/
static int
intr_biglock_wrapper(void *vp)
{
struct intrhand *ih = vp;
int ret;
KERNEL_LOCK(LK_EXCLUSIVE|LK_CANRECURSE);
ret = (*ih->ih_realfun)(ih->ih_realarg);
KERNEL_UNLOCK();
return ret;
}
#endif /* MULTIPROCESSOR */
void *
intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
int (*handler)(void *), void *arg)
@ -525,6 +548,9 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
int slot, error, idt_vec;
struct intrsource *source;
struct intrstub *stubp;
#ifdef MULTIPROCESSOR
boolean_t mpsafe = level >= IPL_SCHED;
#endif /* MULTIPROCESSOR */
#ifdef DIAGNOSTIC
if (legacy_irq != -1 && (legacy_irq < 0 || legacy_irq > 15))
@ -602,13 +628,19 @@ intr_establish(int legacy_irq, struct pic *pic, int pin, int type, int level,
p = &q->ih_next)
;
ih->ih_fun = handler;
ih->ih_arg = arg;
ih->ih_fun = ih->ih_realfun = handler;
ih->ih_arg = ih->ih_realarg = arg;
ih->ih_next = *p;
ih->ih_level = level;
ih->ih_pin = pin;
ih->ih_cpu = ci;
ih->ih_slot = slot;
#ifdef MULTIPROCESSOR
if (!mpsafe) {
ih->ih_fun = intr_biglock_wrapper;
ih->ih_arg = ih;
}
#endif /* MULTIPROCESSOR */
*p = ih;
intr_calculatemasks(ci);
@ -837,20 +869,6 @@ cpu_intr_init(struct cpu_info *ci)
}
#ifdef MULTIPROCESSOR
void
x86_intlock(struct intrframe *iframe)
{
if (iframe->if_ppl < IPL_SCHED)
spinlockmgr(&kernel_lock, LK_EXCLUSIVE|LK_CANRECURSE, 0);
}
void
x86_intunlock(struct intrframe *iframe)
{
if (iframe->if_ppl < IPL_SCHED)
spinlockmgr(&kernel_lock, LK_RELEASE, 0);
}
void
x86_softintlock(void)
{