Information about interrupt handling in the Linux Kernel

Submitted by jlangston
on January 13, 2009 - 12:15pm

I've been working on Linux drivers for custom hardware we produce in-house, and in the process I have some unanswered questions about how interrupts actually work at a low level in Linux.

Specifically, what does spin_lock_irqsave() do to the underlying interrupt routines in the OS, and the interrupt controller itself? Is there a chance I'll miss an interrupt, or am I just being paranoid? I'm only manipulating a couple of pointers in my interrupt message list (not allocating memory or anything slow), so we should only be talking a couple of microseconds or so...

I have all of the requisite O'Reilly books on Embedded Linux development and writing drivers for Linux, but I am still missing background information that I'd like to see to be sure that my drivers are correct and that I won't be getting problem reports the day it ships out to our customers.

If anyone can help me understand what goes on under the covers, or point me at a better book or a white paper, I'd appreciate it.

Jim

Have you checked out

Anonymous (not verified)
on
January 13, 2009 - 6:49pm

Have you checked out "Understanding the Linux Kernel" (O'Reilly)?

Most of what you're referring to is over my head, but the book states that spin_lock_irqsave() is a macro for local_irq_save() and spin_lock(). On a uniprocessor system, the macro only issues local_irq_save() which lets you save the state of the eflags register to a local variable so that you can restore it later after your critical section. I guess the problem is that since interrupts can execute in a nested fashion, the kernel doesn't necessarilly know the state of the IF flag to properly restore it. By using this function, you simply save the state of the flag and restore it when you're done. On multiprocessor systems, the macro adds in a spin_lock() for good measure.

As far as I can tell, the book doesn't state that anything happens to the interrupt controller itself. It's just an easier way to save the register state and automatically handle multiproc situations. Don't take my word for it though :)

Mike

common sense?

Anonymous (not verified)
on
January 14, 2009 - 5:34am

Have you tried reading the actual implementation and your architecture reference manual?

x86 does the following:

spin_lock_irqsafe(lock, flags)
{
asm ("pushf; pop %0" : "=g" (flags) : : "memory");
asm ("cli" : : : "memory");

spin_lock(lock);
}

IOW, it saves the current cpu flags (which contain the current IRQ enable state) and disables interrupts, then it takes the lock.

Disabling interrupts doesn't do anything to interrupt routines, it just tells the interrupt controller to not deliver interrupts for a while -- what happens to interrupts that do happen during that period is slightly arch dependent, but is generally assumed it has at least 1 pending bit for each interrupt line, so you'll only loose second and third interrupts on an already pending line, which isn't much of a problem.

It's counterpart: spin_unlock_irqrestore() unlocks the lock and restores the IRQ state to the previous state -- if they were disabled, leaves them disabled, if they were enabled, it enables them.

Once interrupts get enabled again the interrupt controller will deliver those interrupts for which a pending bit is kept.

I can recommend reading up on your hardware architecture reference manuals and the actual implementation if you have need for more details.

I had found and downloaded

jlangston
on
January 14, 2009 - 12:52pm

I had found and downloaded the Intel 8259A data sheet which is what all modern chipsets appear to implement to understand the workings of the interrupt controller, and read the kernel routines for the x86, but I just wanted someone who might know better than me to corroborate what I thought (and hoped) was happening. Some of the kernel internals can be a bit daunting unless you have cause to tinker with them frequently.

Thanks for the feedback.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.