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

[Xen-devel] [PATCH] cpuidle: Add support for Always Running APIC timer


  • To: "Xen-Devel (E-mail)" <xen-devel@xxxxxxxxxxxxxxxxxxx>
  • From: "Wei, Gang" <gang.wei@xxxxxxxxx>
  • Date: Fri, 17 Apr 2009 16:45:36 +0800
  • Accept-language: en-US
  • Acceptlanguage: en-US
  • Cc: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
  • Delivery-date: Fri, 17 Apr 2009 01:47:48 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>
  • Thread-index: Acm/OOCansyx5SeoQ4if/LySshNdcA==
  • Thread-topic: [PATCH] cpuidle: Add support for Always Running APIC timer

Keir,

This patch is try to simply disable the broadcast while always running apic 
timer is available and doesn't impact current code path. So is it still 
possible to put it in despite 3.4 is currently in RC3 pre phase?

Jimmy

cpuidle: Add support for Always Running APIC timer, CPUID_0x6_EAX_Bit2.

This bit means the APIC timer continues to run even when CPU is
in deep C-states.

The advantage is that we can use LAPIC timer on these CPUs
always, and there is no need for "slow to read and program"
external timers (HPET/PIT) and the timer broadcast logic
and related code in C-state entry and exit.

Refer to the latest Intel SDM Vol 2A
(http://www.intel.com/products/processor/manuals/index.htm)

Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx>

diff -r 655dc3bc1d8e xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c      Thu Apr 16 11:54:06 2009 +0100
+++ b/xen/arch/x86/acpi/cpu_idle.c      Fri Apr 17 15:32:27 2009 +0800
@@ -309,7 +309,8 @@ static void acpi_processor_idle(void)
          * deep C state can't work correctly.
          */
         /* preparing APIC stop */
-        lapic_timer_off();
+        if ( lapic_timer_off )
+            lapic_timer_off();
 
         /* Get start time (ticks) */
         t1 = inl(pmtmr_ioport);
@@ -337,7 +338,8 @@ static void acpi_processor_idle(void)
         /* Re-enable interrupts */
         local_irq_enable();
         /* recovering APIC */
-        lapic_timer_on();
+        if ( lapic_timer_on )
+            lapic_timer_on();
         /* Compute time (ticks) that we were actually asleep */
         sleep_ticks = ticks_elapsed(t1, t2);
 
@@ -538,20 +540,23 @@ static int check_cx(struct acpi_processo
         if ( local_apic_timer_c2_ok )
             break;
     case ACPI_STATE_C3:
-        /* We must be able to use HPET in place of LAPIC timers. */
-        if ( hpet_broadcast_is_available() )
-        {
-            lapic_timer_off = hpet_broadcast_enter;
-            lapic_timer_on = hpet_broadcast_exit;
-        }
-        else if ( pit_broadcast_is_available() )
-        {
-            lapic_timer_off = pit_broadcast_enter;
-            lapic_timer_on = pit_broadcast_exit;
-        }
-        else
-        {
-            return -EINVAL;
+        if ( !boot_cpu_has(X86_FEATURE_ARAT) )
+        {
+            /* We must be able to use HPET in place of LAPIC timers. */
+            if ( hpet_broadcast_is_available() )
+            {
+                lapic_timer_off = hpet_broadcast_enter;
+                lapic_timer_on = hpet_broadcast_exit;
+            }
+            else if ( pit_broadcast_is_available() )
+            {
+                lapic_timer_off = pit_broadcast_enter;
+                lapic_timer_on = pit_broadcast_exit;
+            }
+            else
+            {
+                return -EINVAL;
+            }
         }
 
         /* All the logic here assumes flags.bm_check is same across all CPUs */
diff -r 655dc3bc1d8e xen/arch/x86/cpu/intel.c
--- a/xen/arch/x86/cpu/intel.c  Thu Apr 16 11:54:06 2009 +0100
+++ b/xen/arch/x86/cpu/intel.c  Fri Apr 17 12:37:14 2009 +0800
@@ -222,6 +222,9 @@ static void __devinit init_intel(struct 
                set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
                set_bit(X86_FEATURE_NOSTOP_TSC, c->x86_capability);
        }
+       if (c->cpuid_level >= 0x00000006 &&
+               (cpuid_eax(0x00000006) & (1u<<2)))
+               set_bit(X86_FEATURE_ARAT, c->x86_capability);
 
        start_vmx();
 }
diff -r 655dc3bc1d8e xen/arch/x86/time.c
--- a/xen/arch/x86/time.c       Thu Apr 16 11:54:06 2009 +0100
+++ b/xen/arch/x86/time.c       Fri Apr 17 12:44:22 2009 +0800
@@ -1274,7 +1274,7 @@ static int disable_pit_irq(void)
      * XXX dom0 may rely on RTC interrupt delivery, so only enable
      * hpet_broadcast if FSB mode available or if force_hpet_broadcast.
      */
-    if ( xen_cpuidle )
+    if ( xen_cpuidle && !boot_cpu_has(X86_FEATURE_ARAT) )
     {
         hpet_broadcast_init();
         if ( !hpet_broadcast_is_available() )
diff -r 655dc3bc1d8e xen/include/asm-x86/cpufeature.h
--- a/xen/include/asm-x86/cpufeature.h  Thu Apr 16 11:54:06 2009 +0100
+++ b/xen/include/asm-x86/cpufeature.h  Fri Apr 17 15:20:35 2009 +0800
@@ -75,6 +75,7 @@
 #define X86_FEATURE_P4         (3*32+ 7) /* P4 */
 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
 #define X86_FEATURE_NOSTOP_TSC (3*32+ 9) /* TSC does not stop in C states */
+#define X86_FEATURE_ARAT       (3*32+ 10) /* Always running APIC timer */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */

Attachment: always_running_apic_timer.patch
Description: always_running_apic_timer.patch

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

 


Rackspace

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