views:

305

answers:

2

Are Interrupts assigned to a fixed CPU (always handled by the same CPU)?

To put my question in context:

From: http://msdn.microsoft.com/en-us/library/ms795060.aspx

The spin lock that protects the shared area has an IRQL equal to the DIRQL at which the device interrupts. As long as the critical-section routine holds the spin lock and accesses the shared area at DIRQL, the ISR cannot be run in either a uniprocessor or SMP machine.

That makes sense on a uniprocessor machine as the interrupt will not be serviced by the CPU until the lock is released since the IRQL of the CPU is not less than the interrupt IRQL. On a SMP machine however, what would prevent the interrupt to be handled by the other CPU (not the CPU owning the lock) and corrupt the data... ?

A: 

My understanding is that when the system raises the DIRQL to a certain level any interrupts that are at that DIRQL or lower are effectively disabled on all processors. That's why you shouldn't raise the IRQL for any longer than it absolutely needs to be held.

Very little driver code needs to raise the IRQL to a level above dispatch level (which doesn't mask any interrupts). The only driver code that should need to raise the IRQL higher is code that actually needs to interact with (share data with) the interrupt handler.

Edit: ChrisW had a better description of what's going on in an SMP system - raising the IRQL on a processor will prevent the IRQ from being handled on that particular processor. If the interrtupt handler is scheduled on another CPU while the spinlock protecting the shared data is held by the first CPU, the interrupt handler will spin on its CPU until the first CPU releases the spinlock (to peroperly access the shared data, the interrupt handler must aquire the spin lock, which is what forces the interrupt handler to wait).

So hold those spin locks as short as possible (and as infrequently as possible).

Michael Burr
Thanks. I deleted my answer because I couldn't figure out why it was plausible; but I've since undeleted it, and added a second paragraph to explain why (I think) it's that way.
ChrisW
+1  A: 

Reading the next section ...

In an SMP machine, the ISR cannot acquire the spin lock that protects the shared data while the critical-section routine holds the spin lock and accesses the shared data at DIRQL.

... I think that's saying that on an SMP machine an interrupt can happen; but that if the interrupt happens, then the interrupt service routine (running on the other CPU) still can't acquire the spin lock: i.e. it spins, wasting cycles, trying the acquire the spin lock, unless you release the spin lock which lets the waiting ISR acquire it.

I was wondering why it might allow an ISR to run on the other CPU, instead of masking interrupts (to prevent the ISR being started) as it does in single-CPU case. An answer to that is that, no matter whether or not new ISRs can be started on the other CPU while the spinlock is held, the fact is that (unlike in the single-CPU case) an ISR might already be running on the other CPU at the moment when the DIRQL spinlock is started: and it's for that reason that such an ISR (if it exists on the other CPU) must spin (if it tries to acquire the spinlock).

ChrisW