CPUIDLE: Write to ARB_DISABLE conditionally to reduce some idle overheads.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Sep 2008 10:19:17 +0000 (11:19 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 4 Sep 2008 10:19:17 +0000 (11:19 +0100)
By protecting entry/exit with a spinlock we can safely determine
precisely when it is required that we assert/deassert ARB_DISABLE.

Signed-off-by: Wei Gang <gang.wei@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/acpi/cpu_idle.c

index a8d182b3aaabcee327e5f91aa703c9e119d72b05..cd597b0b11c5962ed80229b3e61158d8ab77e200 100644 (file)
@@ -263,7 +263,10 @@ static void acpi_idle_do_entry(struct acpi_processor_cx *cx)
     }
 }
 
-static atomic_t c3_cpu_count;
+static struct {
+    spinlock_t lock;
+    unsigned int count;
+} c3_cpu_status = { .lock = SPIN_LOCK_UNLOCKED };
 
 static void acpi_processor_idle(void)
 {
@@ -416,8 +419,8 @@ static void acpi_processor_idle(void)
          */
         if ( power->flags.bm_check && power->flags.bm_control )
         {
-            atomic_inc(&c3_cpu_count);
-            if ( atomic_read(&c3_cpu_count) == num_online_cpus() )
+            spin_lock(&c3_cpu_status.lock);
+            if ( ++c3_cpu_status.count == num_online_cpus() )
             {
                 /*
                  * All CPUs are trying to go to C3
@@ -425,6 +428,7 @@ static void acpi_processor_idle(void)
                  */
                 acpi_set_register(ACPI_BITREG_ARB_DISABLE, 1);
             }
+            spin_unlock(&c3_cpu_status.lock);
         }
         else if ( !power->flags.bm_check )
         {
@@ -455,8 +459,10 @@ static void acpi_processor_idle(void)
         if ( power->flags.bm_check && power->flags.bm_control )
         {
             /* Enable bus master arbitration */
-            atomic_dec(&c3_cpu_count);
-            acpi_set_register(ACPI_BITREG_ARB_DISABLE, 0);
+            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 */