Subject: Re: intlock
To: None <fvdl@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: port-amd64
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