Page 1 of 1

IOAPIC redirection entries

Posted: Fri Mar 19, 2010 7:42 pm
by mutex
Hi,

I have issues with moving from PIC to IOAPIC for handling keyboard irq (and probably other interrupts aswell).

I do;
Disable PIC, Mask of all in PIC
Enable APIC (works well, also uses apic timer)
Enable IOAPIC redirection entry inin1 to handle my keyboard.

Bochs says:
[IOAP ] vector 0x21 stuck???

I guess it have something with the ACKnowledge of the interrupt or something?? Im really stuck...

My isr for keyboard is at 0x21 so that seems to be correct. It might be my destination id, destination mode etc beeing wrong, since i pretty sure edgemode, active high etc is correct.

This is my ioapic and apic when kernel is just started:
IOAPIC and APIC dump
IOAPIC and APIC dump
Anyone got a tip or a good guess? :)

-
Thomas

Re: IOAPIC redirection entries

Posted: Sat Mar 20, 2010 7:17 am
by mutex
I fixed it. Was the destination that was not right. Added 0xFF000000 (broadcast) to destiation instead of 0x00000000. Now it works :)

CORRECTION:
It does not work. The isr fire on keypress and seems to work, but bochs still tells [IOAP ] vector 0x21 stuck??. It also seems that after a while it crashes and burns. Probably due to some error not beeing handled correctly... So i guess i fixed the delivery, but not completely.

Is anyone able to dump their apic and ioapic values for me so i can see if there is some major differences in setup?

Thanks!

-
Thomas

Re: IOAPIC redirection entries

Posted: Sat Mar 20, 2010 7:23 am
by Brendan
Hi,
thomasnilsen wrote:I fixed it. Was the destination that was not right. Added 0xFF000000 (broadcast) to destiation instead of 0x00000000. Now it works :)
I'm glad you're making progress, but...

You don't want to broadcast the IRQ to all CPUs (and have all CPUs execute the keyboard IRQ handler at the same time). You want to send the IRQ to one (and only one) CPU - either a specific CPU, or the lowest priority CPU, or the lowest priority CPU within a specific group of CPUs.


Cheers,

Brendan

Re: IOAPIC redirection entries

Posted: Sat Mar 20, 2010 7:31 am
by mutex
Hi,

You are most definetly right. I was thinking to use the PPR and TPR to tell interrupt system what priority each cpu currently has.

Well i have setup the destination mode to 0b001 (lowest priority mode) so with broadcast i guess it that only lowest priority one will handle or am i wrong?

-
Thomas

Re: IOAPIC redirection entries

Posted: Sat Mar 20, 2010 1:05 pm
by Brendan
Hi,

Ok - first I should say it's 5:30 in the morning here (I'm tired) and the following is from memory - it'd be a good idea to double check anything I've said before you rely on it, just in case... ;)
thomasnilsen wrote:Well i have setup the destination mode to 0b001 (lowest priority mode) so with broadcast i guess it that only lowest priority one will handle or am i wrong?
The lowest priority delivery mode is a little tricky. The processor's priority is determined by the highest value in the TPR register, the IRR register and the ISR register (where the lowest 4 bits of the IRR and ISR are ignored); and any interrupt that is lower priority than the processor's priority won't be accepted (e.g. if all CPUs have their TPR set to 0xFF then no interrupts will be accepted by any CPU). If you don't change the TPR then all IRQs will go to the same CPU every time, unless that CPU happens to be servicing a different IRQ. How this is done is up to you.

Because interrupts range from 0x20 to 0xFF (where 0x20 is the lowest priority interrupt), any TPR value below 0x20 will allow all interrupts but still effect the "lowest priority delivery". Because of this, I'd only use TPR values below 0x20. For example:
  • 0x18 to 0x1F = used when the CPU is in different sleep states, where the value depends on the latency of leaving the sleep state
    0x10 to 0x17 = used when the CPU has acquired different kernel locks, where the value depends on which kernel lock
    0x00 to 0x0F = used in all other cases, where the value depends on the current thread's priority
You'd also want to arrange the interrupt vectors in a prioritised way. For example, vectors 0xF0 to 0xFF (the highest priority interrupt vectors) might be reserved for IPIs and 0x20 to 0x23 might be used for the spurious interrupts. That leaves you with 13 priority levels for IRQs (e.g. 0x24 to 0x2F, 0x30 to 0x3F, 0x40 to 0x4F, etc).

Also note that you can combine this with "logical destination mode", to send the IRQ to the lowest priority CPU within a specific group of CPUs. For example, you might have an IRQ that occurs very often and you might want that IRQ to be handled by CPUs that happen to share the same L2/L3 cache (to avoid cache-line bouncing); or you might have a NUMA system and want all IRQs that originate from an I/O hub to be handled by CPUs that are "close" to that I/O hub (to avoid extra latency/hops when the IRQ handler/device driver accesses the devices). The main trick here is how you setup the "logical destination register" (e.g. you could set bit 7 in the logical destination register for all CPUs that are "close" to an I/O hub, then use logical destination mode to send an IRQ to the lowest priority CPU that has bit 7 set in it's logical destination register; and set bit 6 in the logical destination register for some CPUs that share L2/L3 caches).

For x2APIC most of this is mostly the same, except you have no control over the contents of the logical destination register - the highest 16-bits are used to select the NUMA domain and the lowest 16 bits are used to select between 1 and 16 CPUs within that NUMA domain, and therefore you can only send an interrupt to CPUs within one specific NUMA domain using logical delivery mode.


Cheers,

Brendan

Re: IOAPIC redirection entries

Posted: Sun Mar 21, 2010 3:49 pm
by mutex
Hi Brendan,

Thanks for your comprehensive reply. Not bad at 0530 in the morning ;)

I think the Intel Manual is a little bit unclear in how the IOAPIC and LOAPIC should be programmed to work together.

The prioritization in an important role as you describe especially when considering systems with NUMA architecture where a miss in the selection process for handling interrupts and events might have severe impact on performance because of each cpus memory access.

Its clear to me how the LOAPIC work from the Intel Manuals, but i still think the docs for the IOAPIC and are missing some info that i sure would like to have atleast where im at now with things not working... The only thing i have found is a "preliminary paper" for it and i miss something around the communication with the loapic.. Atleast now when i have problems that i think is related to how the APIC is communicating and ACKing the IOAPIC delivered interrupts probably due to some misinterpretation of how things should work...

Note to self;
Need to find out how this prioritized selection process and how the LOAPIC is telling each other who took the interrupt for delivery to cpu.. The issue with [IOAP ] vector 0x21 stuck?? is probably related to the LOAPIC not telling the IOAPIC that its ACKing the interrupt so the IOAPIC constantly retries.. Unsure...

-
Thomas