aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2008-01-28 00:55:56 -0500
committerLen Brown <len.brown@intel.com>2008-02-02 02:31:43 -0500
commit33a2a529f7a2fb481812b99737176628fda457b0 (patch)
treea781c01302cc78f96118e4bb393d4543e0e2b390 /drivers/acpi
parente4aa5cb2138e7423a6edef6a76a3837b94c2f107 (diff)
ACPI: Update the t-state for every affected cpu when t-state is changed
According to ACPI spec, the _TSD object provides T-state control cross logical processor dependency information to OSPM. So the t-state coordination should be considered when T-state for one cpu is changed. According to ACPI spec, three types of coordination are defined. SW_ALL, SW_ANY and HW_ALL. SW_ALL: it means that OSPM needs to initiate T-state transition on all processors in the domain. It is necessary to call throttling set function for all affected cpus. SW_ANY: it means that OSPM may initiate T-state transition on any processor in the domain. HW_ALL: Spec only says that hardware will perform the coordination and doesn't recommend how OSPM coordinate T-state among the affected cpus. So it is treated as the type of SW_ALL. It means that OSPM needs to initiate t-state transition on all the processors in the domain. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi')
-rw-r--r--drivers/acpi/processor_throttling.c79
1 files changed, 74 insertions, 5 deletions
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 18a873a55256..86c790e9f4fc 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -68,7 +68,7 @@ static int acpi_processor_update_tsd_coord(void)
68 68
69 /* 69 /*
70 * Now that we have _TSD data from all CPUs, lets setup T-state 70 * Now that we have _TSD data from all CPUs, lets setup T-state
71 * coordination among all CPUs. 71 * coordination between all CPUs.
72 */ 72 */
73 for_each_possible_cpu(i) { 73 for_each_possible_cpu(i) {
74 pr = processors[i]; 74 pr = processors[i];
@@ -988,6 +988,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
988{ 988{
989 cpumask_t saved_mask; 989 cpumask_t saved_mask;
990 int ret; 990 int ret;
991 unsigned int i;
992 struct acpi_processor *match_pr;
993 struct acpi_processor_throttling *p_throttling;
994 struct throttling_tstate t_state;
995 cpumask_t online_throttling_cpus;
991 996
992 if (!pr) 997 if (!pr)
993 return -EINVAL; 998 return -EINVAL;
@@ -998,12 +1003,76 @@ int acpi_processor_set_throttling(struct acpi_processor *pr, int state)
998 if ((state < 0) || (state > (pr->throttling.state_count - 1))) 1003 if ((state < 0) || (state > (pr->throttling.state_count - 1)))
999 return -EINVAL; 1004 return -EINVAL;
1000 1005
1006 saved_mask = current->cpus_allowed;
1007 t_state.target_state = state;
1008 p_throttling = &(pr->throttling);
1009 cpus_and(online_throttling_cpus, cpu_online_map,
1010 p_throttling->shared_cpu_map);
1001 /* 1011 /*
1002 * Migrate task to the cpu pointed by pr. 1012 * The throttling notifier will be called for every
1013 * affected cpu in order to get one proper T-state.
1014 * The notifier event is THROTTLING_PRECHANGE.
1003 */ 1015 */
1004 saved_mask = current->cpus_allowed; 1016 for_each_cpu_mask(i, online_throttling_cpus) {
1005 set_cpus_allowed(current, cpumask_of_cpu(pr->id)); 1017 t_state.cpu = i;
1006 ret = pr->throttling.acpi_processor_set_throttling(pr, state); 1018 acpi_processor_throttling_notifier(THROTTLING_PRECHANGE,
1019 &t_state);
1020 }
1021 /*
1022 * The function of acpi_processor_set_throttling will be called
1023 * to switch T-state. If the coordination type is SW_ALL or HW_ALL,
1024 * it is necessary to call it for every affected cpu. Otherwise
1025 * it can be called only for the cpu pointed by pr.
1026 */
1027 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
1028 set_cpus_allowed(current, cpumask_of_cpu(pr->id));
1029 ret = p_throttling->acpi_processor_set_throttling(pr,
1030 t_state.target_state);
1031 } else {
1032 /*
1033 * When the T-state coordination is SW_ALL or HW_ALL,
1034 * it is necessary to set T-state for every affected
1035 * cpus.
1036 */
1037 for_each_cpu_mask(i, online_throttling_cpus) {
1038 match_pr = processors[i];
1039 /*
1040 * If the pointer is invalid, we will report the
1041 * error message and continue.
1042 */
1043 if (!match_pr) {
1044 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1045 "Invalid Pointer for CPU %d\n", i));
1046 continue;
1047 }
1048 /*
1049 * If the throttling control is unsupported on CPU i,
1050 * we will report the error message and continue.
1051 */
1052 if (!match_pr->flags.throttling) {
1053 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
1054 "Throttling Controll is unsupported "
1055 "on CPU %d\n", i));
1056 continue;
1057 }
1058 t_state.cpu = i;
1059 set_cpus_allowed(current, cpumask_of_cpu(i));
1060 ret = match_pr->throttling.
1061 acpi_processor_set_throttling(
1062 match_pr, t_state.target_state);
1063 }
1064 }
1065 /*
1066 * After the set_throttling is called, the
1067 * throttling notifier is called for every
1068 * affected cpu to update the T-states.
1069 * The notifier event is THROTTLING_POSTCHANGE
1070 */
1071 for_each_cpu_mask(i, online_throttling_cpus) {
1072 t_state.cpu = i;
1073 acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
1074 &t_state);
1075 }
1007 /* restore the previous state */ 1076 /* restore the previous state */
1008 set_cpus_allowed(current, saved_mask); 1077 set_cpus_allowed(current, saved_mask);
1009 return ret; 1078 return ret;