Yes, but it's a little more complex than that...01000101 wrote:I have it set to 'lowest priority' mode. In this mode, when multiple cpu's are allowed to respond to an interrupt, they choose the least used cpu at the time to take the interrupt. I'm still learning about all of this, so maybe that is wrong, but that is the idea that I have got from the specs.Just a quick question that I don't feel STFWing: if the interrupt gets sent to both processors, will they both start their ISR and is it up to the implementation to synchronize this?
The I/O APIC doesn't know which CPU is least used. An OS needs to use the "Task Priority Register" in the local APIC (which has nothing to do with multi-tasking) to tell the I/O APIC how important the work it's doing is. However, bits 4 to 7 of the TPR also block lower priority IRQs, which you probably don't want. To get around that I'd set the TPR to values between 0x00 and 0x0F to indicate how important the work it's doing is (e.g. 0x0F when it's running really important code, 0x00 when it's idle, etc), so that all CPUs are still willing to accept all IRQs.
Also, if a CPU is already handling an IRQ then bits 4 to 7 of the interrupt vector for that IRQ also effect the CPU's priority. For example, if a CPU's TPR = 0x00 and it's handling an IRQ that's mapped to interrupt 0x23, then the I/O APIC will assume the CPU is at "priority = 0x20". This means that IRQs tend to go to CPUs that aren't already handling an IRQ.
Finally, older CPUs have an (optional) feature called "focus checking". The idea here is that if a CPU is already handing an interrupt/IRQ and that same interrupt/IRQ occurs again, then the interrupt will be sent to the same CPU. This is probably a good thing, as it helps avoid cache misses, lock contention, etc.
Also note that for modern CPUs the TPR is aliased to "CR8" in long mode; and (at least for Intel CPUs) there's an MSR that can be used to disable "TPR messages" (where the CPU is prevented from telling the I/O APIC that it's TPR was changed).
Cheers,
Brendan