ia64/xen-unstable

changeset 18470:9ee24da5a488

CPUIDLE: Avoid remnant HPET intr while force hpetbroadcast

Exit from C3 is mainly caused by HPET intr if force enable
hpetbroadcast. But it is still probably caused by other unexpected
events. In this case the HPET timer may still be alive while there is
no CPU in C3. Avoid those remnant HPET intr can save cpu handling time
and increase idle time.

Signed-off-by: Wei Gang <gang.wei@intel.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Sep 10 11:09:08 2008 +0100 (2008-09-10)
parents 6a37b3d966f9
children 020b8340e839
files xen/arch/x86/hpet.c
line diff
     1.1 --- a/xen/arch/x86/hpet.c	Wed Sep 10 10:53:09 2008 +0100
     1.2 +++ b/xen/arch/x86/hpet.c	Wed Sep 10 11:09:08 2008 +0100
     1.3 @@ -100,6 +100,13 @@ static int reprogram_hpet_evt_channel(
     1.4  
     1.5      ch->next_event = expire;
     1.6  
     1.7 +    if ( expire == STIME_MAX )
     1.8 +    {
     1.9 +        /* We assume it will take a long time for the timer to wrap. */
    1.10 +        hpet_write32(0, HPET_T0_CMP);
    1.11 +        return 0;
    1.12 +    }
    1.13 +
    1.14      delta = min_t(int64_t, delta, MAX_DELTA_NS);
    1.15      delta = max_t(int64_t, delta, MIN_DELTA_NS);
    1.16      delta = ns2ticks(delta, ch->shift, ch->mult);
    1.17 @@ -206,10 +213,10 @@ void hpet_broadcast_enter(void)
    1.18  {
    1.19      struct hpet_event_channel *ch = &hpet_event;
    1.20  
    1.21 +    spin_lock(&ch->lock);
    1.22 +
    1.23      cpu_set(smp_processor_id(), ch->cpumask);
    1.24  
    1.25 -    spin_lock(&ch->lock);
    1.26 -
    1.27      /* reprogram if current cpu expire time is nearer */
    1.28      if ( this_cpu(timer_deadline) < ch->next_event )
    1.29          reprogram_hpet_evt_channel(ch, this_cpu(timer_deadline), NOW(), 1);
    1.30 @@ -222,8 +229,17 @@ void hpet_broadcast_exit(void)
    1.31      struct hpet_event_channel *ch = &hpet_event;
    1.32      int cpu = smp_processor_id();
    1.33  
    1.34 +    spin_lock_irq(&ch->lock);
    1.35 +
    1.36      if ( cpu_test_and_clear(cpu, ch->cpumask) )
    1.37 +    {
    1.38          reprogram_timer(per_cpu(timer_deadline, cpu));
    1.39 +
    1.40 +        if ( cpus_empty(ch->cpumask) && ch->next_event != STIME_MAX )
    1.41 +            reprogram_hpet_evt_channel(ch, STIME_MAX, 0, 0);
    1.42 +    }
    1.43 +
    1.44 +    spin_unlock_irq(&ch->lock);
    1.45  }
    1.46  
    1.47  int hpet_broadcast_is_available(void)