LAPIC will stop during C3, and resume to work after exit from
C3. Considering below case:
The LAPIC timer was programmed to expire after 1000us, but CPU enter
C3 after 100us and exit C3 at 9xxus.
0us: reprogram_timer(1000us)
100us: entry C3, LAPIC timer stop
9xxus: exit C3 due to unexpected event, LAPIC timer continue running
10xxus: reprogram_timer(1000us), fail due to the past expiring time.
......: no timer softirq raised, no change to LAPIC timer.
......: if entry C3 again, HPET will be forced reprogramed to
now+small_slop.
......: if entry C2, no change to LAPIC.
18xxus: LAPIC timer expires unexpectedly if no C3 entries after
10xxus.
Signed-off-by: Wei Gang <gang.wei@intel.com>
if ( cpu_test_and_clear(cpu, ch->cpumask) )
{
- reprogram_timer(per_cpu(timer_deadline, cpu));
+ if ( !reprogram_timer(per_cpu(timer_deadline, cpu)) )
+ {
+ /*
+ * The deadline must have passed -- trigger timer work now.
+ * Also cancel any outstanding LAPIC event.
+ */
+ reprogram_timer(0);
+ raise_softirq(TIMER_SOFTIRQ);
+ }
if ( cpus_empty(ch->cpumask) && ch->next_event != STIME_MAX )
reprogram_hpet_evt_channel(ch, STIME_MAX, 0, 0);