ACPI: Reevaluate whether the T-state is supported or not after cpu is online/offline
authorZhao Yakui <yakui.zhao@intel.com>
Mon, 10 Jan 2011 08:35:45 +0000 (16:35 +0800)
committerLen Brown <len.brown@intel.com>
Mon, 10 Jan 2011 17:35:28 +0000 (12:35 -0500)
After one CPU is offlined, it is unnecessary to switch T-state for it.
So it will be better that the throttling is disabled after the cpu
is offline.
At the same time after one cpu is online, we should check whether
the T-state is supported and then set the corresponding T-state
flag.

Signed-off-by: Zhao Yakui <yakui.zhao@intel.com>
Signed-off-by: Len Brown <len.brown@intel.com>
drivers/acpi/processor_driver.c
drivers/acpi/processor_throttling.c
include/acpi/processor.h

index 85e48047d7b0fd8f549fca988f96ed0f1770a9ae..c8a0ca2af839993bde9c9d849cdc6fdccec5ef04 100644 (file)
@@ -478,8 +478,13 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb,
        if (action == CPU_ONLINE && pr) {
                acpi_processor_ppc_has_changed(pr, 0);
                acpi_processor_cst_has_changed(pr);
+               acpi_processor_reevaluate_tstate(pr, action);
                acpi_processor_tstate_has_changed(pr);
        }
+       if (action == CPU_DEAD && pr) {
+               /* invalidate the flag.throttling after one CPU is offline */
+               acpi_processor_reevaluate_tstate(pr, action);
+       }
        return NOTIFY_OK;
 }
 
index ffc859c61393d55fb65bf5b713535b8d6a1492c4..4305d560b065973bc40fdcb9ccd33f150aa5638a 100644 (file)
@@ -369,6 +369,58 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr)
        return acpi_processor_set_throttling(pr, target_state, false);
 }
 
+/*
+ * This function is used to reevaluate whether the T-state is valid
+ * after one CPU is onlined/offlined.
+ * It is noted that it won't reevaluate the following properties for
+ * the T-state.
+ *     1. Control method.
+ *     2. the number of supported T-state
+ *     3. TSD domain
+ */
+void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
+                                       unsigned long action)
+{
+       int result = 0;
+
+       if (action == CPU_DEAD) {
+               /* When one CPU is offline, the T-state throttling
+                * will be invalidated.
+                */
+               pr->flags.throttling = 0;
+               return;
+       }
+       /* the following is to recheck whether the T-state is valid for
+        * the online CPU
+        */
+       if (!pr->throttling.state_count) {
+               /* If the number of T-state is invalid, it is
+                * invalidated.
+                */
+               pr->flags.throttling = 0;
+               return;
+       }
+       pr->flags.throttling = 1;
+
+       /* Disable throttling (if enabled).  We'll let subsequent
+        * policy (e.g.thermal) decide to lower performance if it
+        * so chooses, but for now we'll crank up the speed.
+        */
+
+       result = acpi_processor_get_throttling(pr);
+       if (result)
+               goto end;
+
+       if (pr->throttling.state) {
+               result = acpi_processor_set_throttling(pr, 0, false);
+               if (result)
+                       goto end;
+       }
+
+end:
+       if (result)
+               pr->flags.throttling = 0;
+}
 /*
  * _PTC - Processor Throttling Control (and status) register location
  */
index 1b62102fbb67e8b34e28dacf4bb323d424380c25..55192ac0cede7e019e4f4617efd53eefa87424c6 100644 (file)
@@ -324,6 +324,12 @@ int acpi_processor_tstate_has_changed(struct acpi_processor *pr);
 int acpi_processor_get_throttling_info(struct acpi_processor *pr);
 extern int acpi_processor_set_throttling(struct acpi_processor *pr,
                                         int state, bool force);
+/*
+ * Reevaluate whether the T-state is invalid after one cpu is
+ * onlined/offlined. In such case the flags.throttling will be updated.
+ */
+extern void acpi_processor_reevaluate_tstate(struct acpi_processor *pr,
+                       unsigned long action);
 extern const struct file_operations acpi_processor_throttling_fops;
 extern void acpi_processor_throttling_init(void);
 /* in processor_idle.c */