Subject: Re: Interrupt, interrupt threads, continuations, and kernel lwps
To: Andrew Doran <>
From: Lars Heidieker <>
List: tech-kern
Date: 02/22/2007 23:45:29
Hash: SHA1

On 22 Feb 2007, at 20:54, Andrew Doran wrote:

> On Thu, Feb 22, 2007 at 09:46:42AM -0800, Bill Studenmund wrote:
>> On Thu, Feb 22, 2007 at 09:13:36AM -0800, =20
>> wrote:
>>> ....
>> I think the problem is you've assumed an implementation, and =20
>> specifically
>> you've assumed one other than what Andy was suggesting.
>> My understanding is that Andy has figured out a way to have, at =20
>> least on
>> x86, the interrupt handler borrow the context of the interrupted =20
>> thread.
>> So the interrupt context switch is also the context switch to the =20
>> thread.
>> That's why he said it was the same as what we do now.
> Exactly. We already context switch for interrupts, but it is not =20
> the same as
> mi_switch. What I want to do is give the interrupt handler enough =20
> context
> (curlwp, stack) that it can block briefly and be restarted later. =20
> There are
> two outcomes: the interrupt runs to completion, or the handler =20
> blocks. In
> both of those cases, we return back to the interrupted LWP just as =20
> we do
> now.
> The handlers would be permitted to block only in order to acquire a =20=

> mutex or
> RW lock. Calling cv_wait(), or lockmgr() or pool_get(, PR_WAITOK) =20
> etc. from
> the handler's context would panic the machine.
> When the lock a handler is waiting on is released, we end up in =20
> sleepq_wake.
> The interrupt handler gets marked runnable and put onto a per-CPU =20
> run queue.
> Just before returning, sleepq_wake notices that there is a high =20
> priority LWP
> (above system or kernel priority) waiting to run and calls preempt. =20=

> The
> interrupt handler is the highest priority item in the run queue, so =20=

> it gets
> picked and put back on the CPU.
> What Jonathan is describing is roughly how FreeBSD works, I think. =20
> When the
> interrupt comes in, mi_switch() is called to dispatch it. The =20
> thread that
> was running when the interrupt came in gets kicked off the CPU.
> Andrew

This is how solaris handles the interrupts as threads, just switching =20=

the stack and setting curlwp to get the
interrupt thread  running, essentially delaying parts of the context =20
switch to the rare case when the interrupt thread has to sleep.
A difference, worse to be mentioned, is that in solaris there is one =20
interrupt thread for each ipl for each cpu, while in freebsd there
is on for each "interrupt" (like irq1 irq3 on i386 which is not =20
necessarily the same as ipl).
The overhead of going thru mi_switch() for interrupt handling is =20
probably quite high, therefor it will be a lot better to
use this "lazy context switching" interrupt approach. Where in the =20
normal case where the interrupt does not have to block,
the overhead is quite small (judged by the 29 instructions mentioned =20
and the size of the isr).
In the case where the interrupt thread does not block, this is very =20
similar to conventional interrupt handling.
I don't agree with  "In both of those cases, we return back to the =20
interrupted LWP just as we do now"
as think this is only true for the non-blocking case in the blocking =20
case it will be that after the interrupt thread has completed its work
a new runnable thread will be choosen from the runqueues or do you =20
have a subtle difference in mind?

- --

Viele Gr=FC=DFe,
Lars Heidieker

- ------------------------------------

Mystische Erkl=E4rungen.
Die mystischen Erkl=E4rungen gelten f=FCr tief;
die Wahrheit ist, dass sie noch nicht einmal oberfl=E4chlich sind.
      -- Friedrich Nietzsche

Version: GnuPG v1.4.5 (Darwin)