[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] Merge
# HG changeset patch # User Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> # Date 1299867677 0 # Node ID 93c63adf348622a1d94e6dba4666a1e3d1efc9d4 # Parent 9070fc88309b5712d658ee19431f2df7647b8553 # Parent 929195d87ca65aae3382065e00268ffcda4261eb Merge --- diff -r 9070fc88309b -r 93c63adf3486 xen/arch/x86/acpi/cpu_idle.c --- a/xen/arch/x86/acpi/cpu_idle.c Fri Mar 11 18:20:53 2011 +0000 +++ b/xen/arch/x86/acpi/cpu_idle.c Fri Mar 11 18:21:17 2011 +0000 @@ -457,6 +457,19 @@ case ACPI_STATE_C3: /* + * Before invoking C3, be aware that TSC/APIC timer may be + * stopped by H/W. Without carefully handling of TSC/APIC stop issues, + * deep C state can't work correctly. + */ + /* preparing APIC stop */ + lapic_timer_off(); + + /* Get start time (ticks) */ + t1 = get_tick(); + /* Trace cpu idle entry */ + TRACE_4D(TRC_PM_IDLE_ENTRY, cx->idx, t1, exp, pred); + + /* * disable bus master * bm_check implies we need ARB_DIS * !bm_check implies we need cache flush @@ -485,20 +498,18 @@ ACPI_FLUSH_CPU_CACHE(); } - /* - * Before invoking C3, be aware that TSC/APIC timer may be - * stopped by H/W. Without carefully handling of TSC/APIC stop issues, - * deep C state can't work correctly. - */ - /* preparing APIC stop */ - lapic_timer_off(); - - /* Get start time (ticks) */ - t1 = get_tick(); - /* Trace cpu idle entry */ - TRACE_4D(TRC_PM_IDLE_ENTRY, cx->idx, t1, exp, pred); /* Invoke C3 */ acpi_idle_do_entry(cx); + + if ( power->flags.bm_check && power->flags.bm_control ) + { + /* Enable bus master arbitration */ + spin_lock(&c3_cpu_status.lock); + acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); + c3_cpu_status.count--; + spin_unlock(&c3_cpu_status.lock); + } + /* Get end time (ticks) */ t2 = get_tick(); @@ -509,15 +520,6 @@ TRACE_6D(TRC_PM_IDLE_EXIT, cx->idx, t2, irq_traced[0], irq_traced[1], irq_traced[2], irq_traced[3]); - if ( power->flags.bm_check && power->flags.bm_control ) - { - /* Enable bus master arbitration */ - spin_lock(&c3_cpu_status.lock); - if ( c3_cpu_status.count-- == num_online_cpus() ) - acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0); - spin_unlock(&c3_cpu_status.lock); - } - /* Re-enable interrupts */ local_irq_enable(); /* recovering APIC */ @@ -552,7 +554,7 @@ { struct acpi_processor_power *power; struct acpi_processor_cx *cx; - int unused; + void *mwait_ptr; if ( (power = processor_powers[smp_processor_id()]) == NULL ) goto default_halt; @@ -560,24 +562,33 @@ if ( (cx = &power->states[power->count-1]) == NULL ) goto default_halt; - for ( ; ; ) + mwait_ptr = (void *)&mwait_wakeup(smp_processor_id()); + + if ( cx->entry_method == ACPI_CSTATE_EM_FFH ) { - if ( !power->flags.bm_check && cx->type == ACPI_STATE_C3 ) - ACPI_FLUSH_CPU_CACHE(); + /* + * Cache must be flushed as the last operation before sleeping. + * Otherwise, CPU may still hold dirty data, breaking cache coherency, + * leading to strange errors. + */ + wbinvd(); - switch ( cx->entry_method ) + while ( 1 ) { - case ACPI_CSTATE_EM_FFH: - /* Not treat interrupt as break event */ - __monitor((void *)&mwait_wakeup(smp_processor_id()), 0, 0); - __mwait(cx->address, 0); - break; - case ACPI_CSTATE_EM_SYSIO: - inb(cx->address); - unused = inl(pmtmr_ioport); - break; - default: - goto default_halt; + /* + * 1. The CLFLUSH is a workaround for erratum AAI65 for + * the Xeon 7400 series. + * 2. The WBINVD is insufficient due to the spurious-wakeup + * case where we return around the loop. + * 3. Unlike wbinvd, clflush is a light weight but not serializing + * instruction, hence memory fence is necessary to make sure all + * load/store visible before flush cache line. + */ + mb(); + clflush(mwait_ptr); + __monitor(mwait_ptr, 0, 0); + mb(); + __mwait(cx->address, 0); } } diff -r 9070fc88309b -r 93c63adf3486 xen/arch/x86/domain.c --- a/xen/arch/x86/domain.c Fri Mar 11 18:20:53 2011 +0000 +++ b/xen/arch/x86/domain.c Fri Mar 11 18:21:17 2011 +0000 @@ -100,7 +100,6 @@ static void play_dead(void) { local_irq_disable(); - wbinvd(); /* * NOTE: After cpu_exit_clear, per-cpu variables are no longer accessible, _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |