Subject: intlock
To: None <port-i386@netbsd.org, port-amd64@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: port-amd64
Date: 02/22/2004 18:42:19
--NextPart-20040222183830-0158900
Content-Type: Text/Plain; charset=us-ascii
hi,
while x86_intlock() currently uses the previous spl (if_ppl) to
determine if the kernel lock is needed or not,
what really matters there is the interrupt handler's own IPL_.
i'd like to check the attached diff if no one objects.
(it's a little ugly but i don't think it's a problem because
the kernel lock should go away eventually anyway :-)
YAMAMOTO Takashi
--NextPart-20040222183830-0158900
Content-Type: Text/Plain; charset=us-ascii
Content-Disposition: attachment; filename="x86.intlock.diff"
Index: i386/i386/vector.S
===================================================================
--- i386/i386/vector.S (revision 581)
+++ i386/i386/vector.S (revision 582)
@@ -234,13 +234,6 @@ IDTVEC(intr_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)
@@ -286,7 +279,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 ;\
@@ -299,14 +291,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) ;\
Index: amd64/amd64/vector.S
===================================================================
--- amd64/amd64/vector.S (revision 581)
+++ amd64/amd64/vector.S (revision 582)
@@ -371,13 +371,6 @@ IDTVEC(intr_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)
@@ -420,7 +413,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 ;\
@@ -432,14 +424,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) ;\
Index: x86/include/intr.h
===================================================================
--- x86/include/intr.h (revision 581)
+++ x86/include/intr.h (revision 582)
@@ -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;
Index: x86/x86/intr.c
===================================================================
--- x86/x86/intr.c (revision 581)
+++ x86/x86/intr.c (revision 582)
@@ -451,6 +451,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)
@@ -460,6 +483,9 @@ intr_establish(int legacy_irq, struct pi
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))
@@ -537,13 +563,19 @@ intr_establish(int legacy_irq, struct pi
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);
@@ -773,20 +805,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)
{
spinlockmgr(&kernel_lock, LK_EXCLUSIVE|LK_CANRECURSE, 0);
--NextPart-20040222183830-0158900--