Skip to content

Interrupt model, alpha 1

March 20, 2011

Okay, so here’s a first attempt at creating a portable interrupt model from the previous data :

  • There are, at some level, various atomic interrupt sources, which are each labeled in an arch-specific way (naming information can always be stored in a C-style struct which itself can be pointed by an integer, so it doesn’t matter). This is what unprivileged software can see.
  • There may or may not be a number of OS-controlled routing/masking layers inbetween, but these interrupt sources see their signals redirected to a number of standard interrupt signals which the processor can discriminate without communicating with another device. We call these IRQs, and they are managed by the kernel.
  • Whether the aforementioned routing layers should be managed by the kernel or by an external driver should be decided on a per-device basis, depending on things like its importance on the architecture (e.g. PCI and USB are universal on the x86 architecture), how much performance it needs, etc. However, to be managed within the kernel, an interrupt routing mechanism must be a widely documented standard, with freely available documentation. If two manufacturers or more which each have a significant market share manage the same mechanism in an incompatible way, it is not standard and must be left to external drivers.
  • Before starting to talk about IRQ handling, let’s remind a top security rule, which overrides any other concern : No process should ever be able to prevent the kernel from running for an unspecified period of time. We’ve been talking about this in a previous post about real time processes. What this means is that no process may ever get control on the IRQ where the clock is redirected, which belongs to the kernel scheduler, nor run while the clock interrupt is disabled.
  • Depending on the considered architecture, it may be possible to mask each IRQ individually, or only to mask groups of IRQs. Our interrupt management system must provide a way for low-level code to learn about this. Processes may mask all interrupts which they “own”, and to mask a group they need to own all interrupts within it.
  • Although our microkernel model requires the ability to start pop-up threads within processes each time an interrupt occurs, as if the interrupt directly triggered the execution of that process’ interrupt handling code, it is generally not safe on most architectures to set a user process as the interrupt handler, as it would imply running said process with the clock interrupt disabled and would offer no guarantee whatsoever that the state of the previously running process would be saved. For this reason, a bit of kernel code must be run before any interrupt is handled. This code takes care of saving the processor’s state on a stack or the heap and re-enabling other interrupts, before running the actual interrupt handler. Care must be taken that this code fully runs in kernel mode, with the kernel stack, and not with a potentially corrupt user-mode stack.
  • It may also be possible to prioritize some interrupts above others. This isn’t very important in this interrupt model, as we go back to user-mode code with interrupts enabled very quickly. But they say that power shouldn’t be hidden, so we have to find a way to provide low-level code with access to this capability.

What do you think about it ?

About these ads

From → OS development

8 Comments
  1. oiaohm permalink

    Universal not possible. With Linux for this you will have to either use RT tree or Wait until 2.6.39 and latter.

    The issue here does not only exist in Linux. Not All OS’s have threaded irq handlers. So prior to 2.6.39 irq was basically an exclusive. As soon as you enter irq its exclusive.

    After 2.6.39 threaded irq handling enters. This does change the irq handling a lot. Since now the irq events can be processed in independent threads possibly on independent processes. And in time possibly passing through a user-space part.

    Min requirement will be a OS with a threaded irq handler that can allocate. Something people are not aware of is there are per cpu irq as well as global irq multi core does make things a little more complex. Threading a cpu irq to another cpu really does not work.

    Next is a issue for how real-time. Will you require something like kernel mode linux. So your code runs in kernel space avoiding context switch costs.

    From memory USB devices don’t require irq handling.

  2. oiaohm permalink

    Opps I missed a point. Also before creating a new framework from nothing. Sanity would suggest taking fuse and extending it like cuse and buse were for irq handling if its going to be in userspace. Since fuse already extends over a lot of platforms..

  3. Min requirement will be a OS with a threaded irq handler that can allocate. Something people are not aware of is there are per cpu irq as well as global irq multi core does make things a little more complex. Threading a cpu irq to another cpu really does not work.

    Thanks for mentioning this, although I knew about LAPIC on x86 I didn’t think about this side of things. This means that when designing my process and thread model, one of the scheduling constraints which I’ll have to introduce is the ability to force a thread to run on a given CPU core. That would probably be not have been so much of a big deal to add later, but it’s best to think about such things early because it means less code to rewrite once the issue is found!

    Next is a issue for how real-time. Will you require something like kernel mode linux. So your code runs in kernel space avoiding context switch costs.

    I care a lot about putting things in user space, but I do have a plan to reduce context switching cost for critical “real time” tasks. It would go as follows: while a RT thread is running, multitasking is temporarily disabled, except if other RT threads are present, in which case we only multitask between RT threads. To prevent system lockup, RT threads are only allowed to run for a specific period of time (and cannot spawn other threads to go beyond that deadline, obviously). If they cannot complete their task within that time, they are either killed or downgraded to the non-RT status.

    There’s a more in-depth discussion of this idea in this post, if you can go past the GBA game abuse: http://theosperiment.wordpress.com/2010/11/13/an-aside-about-processes-and-reactive-scheduling/

    From memory USB devices don’t require irq handling.

    Those this mean… Polling ? Eeek !

  4. Opps I missed a point. Also before creating a new framework from nothing. Sanity would suggest taking fuse and extending it like cuse and buse were for irq handling if its going to be in userspace. Since fuse already extends over a lot of platforms..

    Afaik, FUSE is something for managing filesystems in userspace on Linux and other Unices, right? How would this help me?

  5. oiaohm permalink

    Character device in Userspace and Block device in Userspace are also based off fuse.

    Particularly that it already has a transfer system userspace and kernel space on many kernels in a generic way.

    http://www.kernel.org/doc/htmldocs/uio-howto.html#using_uio_pdrv_genirq There are currently non portable solution as well. And yes it does have particular limits. Without the thread interpret handler UIO can bring the house down, Just the same as if a kernel module failed. I guess you are wanting to try to avoid this.

    Linux real-time tree and using UIO has been safe since that added thread interpret handler.

  6. oiaohm permalink

    Yes for usb 1 and 2 it mean polling. http://www.libusb.org/ most likely leave USB alone its nicely covered by this. Simpler to leave usb to its own special field.

    usb 3 introduces the possibility of irq. Yes 1 irq for all devices connect to the USB 3 controller. Yes its particularly ugly.

    USB 3 is also most likely best left to a libusb.

  7. Yup, I plan to leave most complex drivers which already have a good implementation (filesystems, USB, ACPI, PCI…) to already working and efficient third-party implementations, only tweaking them to adapt them to my kernel model, as much as possible.

    This will leave me time to work on things which are of more interest to me, like the kernel’s structure itself (and the plenty of interesting problems with no trivial solution which it brings) or a fast VESA stack (comparing Haiku to Linux, one sees that there’s still work to be done in this area).

  8. eddyb permalink

    Wait, what?
    USB, since 1, it’s highly IRQ-based. Polling could be considered an outrageous stupidity for USB. And why USB3 changes anything? That’s how it has been, one IRQ/controller. You read status bits, find out why you get an IRQ, and if it’s because a transfer finished, then you can go ahead and notify the requester.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.