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

[Xen-devel] [PATCH] Make offlined CPU enter deepest C state



Make offlined CPU enter deepest C state

Before cpuidle is introduced, offlined CPU only enter C1 (by HLT instruction). 
This is not optimal since C2/C3 can bring more power saving. Since now cpuidle 
is introduced, it is time for offlined CPU to enter more deeper C state.

This patch add the logic to make offlined CPU enter deepest C state, if cpuidle 
is enabled.

Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx>
               Wei Gang <gang.wei@xxxxxxxxx>
               Tian Kevin <kevin.tian@xxxxxxxxx>

diff -r ad6925fc2317 xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c
+++ b/xen/arch/x86/acpi/cpu_idle.c
@@ -60,6 +60,7 @@ static void (*lapic_timer_on)(void);
 
 extern u32 pmtmr_ioport;
 extern void (*pm_idle) (void);
+extern void (*dead_idle) (void);
 
 static void (*pm_idle_save) (void) __read_mostly;
 unsigned int max_cstate __read_mostly = ACPI_PROCESSOR_MAX_POWER - 1;
@@ -372,6 +373,43 @@ static void acpi_processor_idle(void)
 
     if ( cpuidle_current_governor->reflect )
         cpuidle_current_governor->reflect(power);
+}
+
+static void acpi_dead_idle(void)
+{
+    struct acpi_processor_power *power;
+    struct acpi_processor_cx *cx;
+    int unused;
+
+    if ( (power = processor_powers[smp_processor_id()]) == NULL )
+        goto default_halt;
+
+    if( (cx = &power->states[power->count-1]) == NULL )
+        goto default_halt;
+
+    for( ; ; )
+    {
+        if ( !power->flags.bm_check && cx->type == ACPI_STATE_C3 )
+            ACPI_FLUSH_CPU_CACHE();
+
+        switch ( cx->entry_method )
+        {
+            case ACPI_CSTATE_EM_FFH:
+                /* Not treat interrupt as break event */
+                mwait_idle_with_hints(cx->address, 0);
+                break;
+            case ACPI_CSTATE_EM_SYSIO:
+                inb(cx->address);
+                unused = inl(pmtmr_ioport);
+                break;
+            default:
+                goto default_halt;
+        }
+    }
+
+default_halt:
+    for( ; ; )
+        halt();
 }
 
 static int init_cx_pminfo(struct acpi_processor_power *acpi_power)
@@ -745,6 +783,11 @@ long set_cx_pminfo(uint32_t cpu, struct 
         pm_idle_save = pm_idle;
         pm_idle = acpi_processor_idle;
     }
+
+    if ( cpu_id == 0 )
+    {
+        dead_idle = acpi_dead_idle;
+    }
         
     return 0;
 }
diff -r ad6925fc2317 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c
+++ b/xen/arch/x86/domain.c
@@ -58,7 +58,9 @@ DEFINE_PER_CPU(unsigned long, cr4);
 DEFINE_PER_CPU(unsigned long, cr4);
 
 static void default_idle(void);
+static void default_dead_idle(void);
 void (*pm_idle) (void) = default_idle;
+void (*dead_idle) (void) =  default_dead_idle;
 
 static void paravirt_ctxt_switch_from(struct vcpu *v);
 static void paravirt_ctxt_switch_to(struct vcpu *v);
@@ -84,6 +86,12 @@ static void default_idle(void)
         local_irq_enable();
 }
 
+static void default_dead_idle(void)
+{
+    for( ; ; )
+        halt();
+}
+
 static void play_dead(void)
 {
     /*
@@ -102,8 +110,7 @@ static void play_dead(void)
 
     /* With physical CPU hotplug, we should halt the cpu. */
     local_irq_disable();
-    for ( ; ; )
-        halt();
+    (*dead_idle)();
 }
 
 void idle_loop(void)

Attachment: offline-deep-c-v2.patch
Description: offline-deep-c-v2.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®.