The problem seems easy to define:
When the null loop for four cores looks like this the APIC timer will malfunction:
Code: Select all
null_loop:
hlt
jmp null_loop
Code: Select all
cli
stopl:
jmp stopl
On older PCs, using "hlt" when idle will conserve power, but on modern PCs (at least with AMD CPUs), this seems to interfere with power-management and APIC timer. I'm quite reluctant to change the null-loop to only busy loop, or perhaps use the pause instruction, but how else would I get timely interrupts from the APIC timer unit?
Another potential way to solve this would be to turn-off cores when load is low, and also inhibit them from being woken-up by ints, but regardless of this, it seems like at least one core must busy-loop when idle in order for APIC timer to work properly.
A third solution might be to let one core (probably BSP) maintain all timers and use the legacy timer. This is not an attractive option, but at least the legacy-timer always keeps it's frequency, and if only one core keeps time this would simplify time / timer management. Additionally, in this scenario, BSP should not receive device-interrupts in this scenario, rather it should only run ordinary code and handle timers. IPIs could be used from other cores when timers are started and stopped in order to reload timers on BSP. Also, since the legacy timer is a global resource, reading out current time could be done from any core, provided spinlocks are used to protect the timer.
A related question is how to manage an "interrupt on lowest priority" scheme when some cores are sleeping or excluded. Is this possible to do with destination specifications, or is it better done by setting TPR to the maximum value on cores that should not be interrupted?