[xen-unstable] x86: Enhance Cx stability by adding softirq check before entry cstate

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

[xen-unstable] x86: Enhance Cx stability by adding softirq check before entry cstate

Xen patchbot-unstable
# HG changeset patch
# User Keir Fraser <[hidden email]>
# Date 1212482102 -3600
# Node ID 6b77c311fd3c90db5a0cbbcfc44bf8d99b709b2b
# Parent  420db89188caafa5ee453407dce010a901abc2b8
x86: Enhance Cx stability by adding softirq check before entry cstate

Without checking softirq_pending before entry Cx state, softirq such
as SCHEDULE_SOFTIRQ and TIMER_SOFTIRQ can't be handled timely. It may
cause severe failures such as disk I/O failure.

This patch addresses the issue above, meanwhile move timing points
closer to cstate entry/exit point to make C3 residency more accurate,
and enable irq a little earlier.

Signed-off-by: Wei Gang <[hidden email]>
Signed-off-by: Tian Kevin <[hidden email]>
---
 xen/arch/x86/acpi/cpu_idle.c |   21 ++++++++++++++-------
 1 files changed, 14 insertions(+), 7 deletions(-)

diff -r 420db89188ca -r 6b77c311fd3c xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c Tue Jun 03 09:33:41 2008 +0100
+++ b/xen/arch/x86/acpi/cpu_idle.c Tue Jun 03 09:35:02 2008 +0100
@@ -277,6 +277,13 @@ static void acpi_processor_idle(void)
      * for C2/C3 transitions.
      */
     local_irq_disable();
+
+    if ( softirq_pending(smp_processor_id()) )
+    {
+        local_irq_enable();
+        return;
+    }
+
     cx = power->state;
     if ( !cx )
     {
@@ -422,9 +429,6 @@ static void acpi_processor_idle(void)
             ACPI_FLUSH_CPU_CACHE();
         }
 
-        /* Get start time (ticks) */
-        t1 = inl(pmtmr_ioport);
-
         /*
          * Before invoking C3, be aware that TSC/APIC timer may be
          * stopped by H/W. Without carefully handling of TSC/APIC stop issues,
@@ -434,16 +438,19 @@ static void acpi_processor_idle(void)
         cstate_save_tsc();
         /* preparing APIC stop */
         hpet_broadcast_enter();
+
+        /* Get start time (ticks) */
+        t1 = inl(pmtmr_ioport);
         /* Invoke C3 */
         acpi_idle_do_entry(cx);
+        /* Get end time (ticks) */
+        t2 = inl(pmtmr_ioport);
 
         /* recovering APIC */
         hpet_broadcast_exit();
         /* recovering TSC */
         cstate_restore_tsc();
 
-        /* Get end time (ticks) */
-        t2 = inl(pmtmr_ioport);
         if ( power->flags.bm_check && power->flags.bm_control )
         {
             /* Enable bus master arbitration */
@@ -451,10 +458,10 @@ static void acpi_processor_idle(void)
             acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
         }
 
+        /* Re-enable interrupts */
+        local_irq_enable();
         /* Compute time (ticks) that we were actually asleep */
         sleep_ticks = ticks_elapsed(t1, t2);
-        /* Re-enable interrupts */
-        local_irq_enable();
         /* Do not account our idle-switching overhead: */
         sleep_ticks -= cx->latency_ticks + C3_OVERHEAD;
 

_______________________________________________
Xen-changelog mailing list
[hidden email]
http://lists.xensource.com/xen-changelog