Subject: Re: intlock
To: None <fvdl@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: port-i386
Date: 04/15/2004 19:25:27
hi,
> Wait, I just realized something: currently, the kernel lock is
> only taken once for a chain of shared interrupts. This way,
> it will be taken for each individual call.
>
> I'm not sure if I like that.. though with MP-safe interrupt handlers,
> we'd need this construct anyway.. Hm.
i think that an alternative is something like the following.
int
x86_intr_callhandlers(struct intrhand *ih)
{
int ret;
boolean_t biglock = FALSE;
while (ih != NULL) {
if (!biglock && !is_mpsafe(ih)) {
KERNEL_LOCK(LK_EXCLUSIVE|LK_CANRECURSE);
biglock = TRUE;
}
ret |= (*ih->ih_fun)(ih->ih_arg);
KDASSERT(ih->ih_next == NULL ||
is_mpsafe(ih) || !is_mpsafe(ih->ih_next));
ih = ih->ih_next;
}
if (biglock)
KERNEL_UNLOCK();
return ret;
}
another alternative might be let intr_establish insert dummy handlers
which only does either lock or unlock.
although i personally like the version in my first mail
(using a wrapper function for handlers which need biglock)
because it'll look neat when all handlers are biglock-free.
> Then again, for MP system with ioapics, the chance of shared interrupts
> is a lot smaller.
>
> Well, I'm not sure. Do you have an MP system with a shared interrupt
> line you can test on?
it seems there's one which have two uhcis sharing a pin.
uhci0: interrupting at ioapic0 pin 16 (irq 11)
uhci3: interrupting at ioapic0 pin 16 (irq 11)
what kind of tests do you want?
YAMAMOTO Takashi