WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

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

To: Keir Fraser <keir.fraser@xxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH] Make offlined CPU enter deepest C state
From: "Yu, Ke" <ke.yu@xxxxxxxxx>
Date: Tue, 24 Feb 2009 17:09:02 +0800
Accept-language: en-US
Acceptlanguage: en-US
Cc: "Tian, Kevin" <kevin.tian@xxxxxxxxx>, "xen-devel@xxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxx>, "Wei, Gang" <gang.wei@xxxxxxxxx>
Delivery-date: Tue, 24 Feb 2009 01:09:33 -0800
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Thread-index: AcmWX4lAzuvZPkBzRuKIszkElHwhEw==
Thread-topic: [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
<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] [PATCH] Make offlined CPU enter deepest C state, Yu, Ke <=