[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] CPUIDLE: Avoid remnant HPET intr while force hpetbroadcast



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1221041348 -3600
# Node ID 9ee24da5a488c2899026df0ad4172fe497f631fb
# Parent  6a37b3d966f90f3c1604c9a3045d033cc5eeb4ea
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@xxxxxxxxx>
---
 xen/arch/x86/hpet.c |   20 ++++++++++++++++++--
 1 files changed, 18 insertions(+), 2 deletions(-)

diff -r 6a37b3d966f9 -r 9ee24da5a488 xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c       Wed Sep 10 10:53:09 2008 +0100
+++ b/xen/arch/x86/hpet.c       Wed Sep 10 11:09:08 2008 +0100
@@ -100,6 +100,13 @@ static int reprogram_hpet_evt_channel(
 
     ch->next_event = expire;
 
+    if ( expire == STIME_MAX )
+    {
+        /* We assume it will take a long time for the timer to wrap. */
+        hpet_write32(0, HPET_T0_CMP);
+        return 0;
+    }
+
     delta = min_t(int64_t, delta, MAX_DELTA_NS);
     delta = max_t(int64_t, delta, MIN_DELTA_NS);
     delta = ns2ticks(delta, ch->shift, ch->mult);
@@ -206,9 +213,9 @@ void hpet_broadcast_enter(void)
 {
     struct hpet_event_channel *ch = &hpet_event;
 
+    spin_lock(&ch->lock);
+
     cpu_set(smp_processor_id(), ch->cpumask);
-
-    spin_lock(&ch->lock);
 
     /* reprogram if current cpu expire time is nearer */
     if ( this_cpu(timer_deadline) < ch->next_event )
@@ -222,8 +229,17 @@ void hpet_broadcast_exit(void)
     struct hpet_event_channel *ch = &hpet_event;
     int cpu = smp_processor_id();
 
+    spin_lock_irq(&ch->lock);
+
     if ( cpu_test_and_clear(cpu, ch->cpumask) )
+    {
         reprogram_timer(per_cpu(timer_deadline, cpu));
+
+        if ( cpus_empty(ch->cpumask) && ch->next_event != STIME_MAX )
+            reprogram_hpet_evt_channel(ch, STIME_MAX, 0, 0);
+    }
+
+    spin_unlock_irq(&ch->lock);
 }
 
 int hpet_broadcast_is_available(void)

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.