[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] x86: Make offlined CPU enter deepest C state
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1235992279 0 # Node ID 35baf43f271363c7b71d3fba44a469590841df3a # Parent 5e34a89662515c21e686e8a7906d140b470bcb99 x86: 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> Signed-off-by: Wei Gang <gang.wei@xxxxxxxxx> Signed-off-by: Tian Kevin <kevin.tian@xxxxxxxxx> --- xen/arch/x86/acpi/cpu_idle.c | 43 +++++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/domain.c | 11 +++++++++-- 2 files changed, 52 insertions(+), 2 deletions(-) diff -r 5e34a8966251 -r 35baf43f2713 xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Mon Mar 02 11:04:43 2009 +0000 +++ b/xen/arch/x86/acpi/cpu_idle.c Mon Mar 02 11:11:19 2009 +0000 @@ -55,6 +55,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; @@ -369,6 +370,43 @@ static void acpi_processor_idle(void) 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) { int i; @@ -740,6 +778,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 5e34a8966251 -r 35baf43f2713 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Mon Mar 02 11:04:43 2009 +0000 +++ b/xen/arch/x86/domain.c Mon Mar 02 11:11:19 2009 +0000 @@ -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); @@ -82,6 +84,12 @@ static void default_idle(void) safe_halt(); else 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) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |