aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Yakui <yakui.zhao@intel.com>2011-01-10 03:35:44 -0500
committerLen Brown <len.brown@intel.com>2011-01-10 12:35:04 -0500
commitdaef1f35ea1e2cca125eecd5f078f40b55eb9105 (patch)
treeba3cfad2743cbd70a6d36dfe645c427a1634eeb1
parent3c0eee3fe6a3a1c745379547c7e7c904aa64f6d5 (diff)
ACPI: Check the returned value of set_cpus_allowed_ptr before T-state operation
Now before it executes the T-state operation on one CPU, it will try to migrate to the target CPU. Especially this is required on the system that uses the MSR_IA32_THERMAL_CONTROL register to switch T-state. But unfortunately it doesn't check whether the migration is successful or not. In such case we will get/set the incorrect T-state on the offline CPU as it fails in the migration to the offline CPU. Signed-off-by: Zhao Yakui <yakui.zhao@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
-rw-r--r--drivers/acpi/processor_throttling.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index ff3632717c51..ffc859c61393 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -876,7 +876,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
876 */ 876 */
877 cpumask_copy(saved_mask, &current->cpus_allowed); 877 cpumask_copy(saved_mask, &current->cpus_allowed);
878 /* FIXME: use work_on_cpu() */ 878 /* FIXME: use work_on_cpu() */
879 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 879 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
880 /* Can't migrate to the target pr->id CPU. Exit */
881 free_cpumask_var(saved_mask);
882 return -ENODEV;
883 }
880 ret = pr->throttling.acpi_processor_get_throttling(pr); 884 ret = pr->throttling.acpi_processor_get_throttling(pr);
881 /* restore the previous state */ 885 /* restore the previous state */
882 set_cpus_allowed_ptr(current, saved_mask); 886 set_cpus_allowed_ptr(current, saved_mask);
@@ -1051,6 +1055,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1051 return -ENOMEM; 1055 return -ENOMEM;
1052 } 1056 }
1053 1057
1058 if (cpu_is_offline(pr->id)) {
1059 /*
1060 * the cpu pointed by pr->id is offline. Unnecessary to change
1061 * the throttling state any more.
1062 */
1063 return -ENODEV;
1064 }
1065
1054 cpumask_copy(saved_mask, &current->cpus_allowed); 1066 cpumask_copy(saved_mask, &current->cpus_allowed);
1055 t_state.target_state = state; 1067 t_state.target_state = state;
1056 p_throttling = &(pr->throttling); 1068 p_throttling = &(pr->throttling);
@@ -1074,7 +1086,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1074 */ 1086 */
1075 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) { 1087 if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
1076 /* FIXME: use work_on_cpu() */ 1088 /* FIXME: use work_on_cpu() */
1077 set_cpus_allowed_ptr(current, cpumask_of(pr->id)); 1089 if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
1090 /* Can't migrate to the pr->id CPU. Exit */
1091 ret = -ENODEV;
1092 goto exit;
1093 }
1078 ret = p_throttling->acpi_processor_set_throttling(pr, 1094 ret = p_throttling->acpi_processor_set_throttling(pr,
1079 t_state.target_state, force); 1095 t_state.target_state, force);
1080 } else { 1096 } else {
@@ -1106,7 +1122,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1106 } 1122 }
1107 t_state.cpu = i; 1123 t_state.cpu = i;
1108 /* FIXME: use work_on_cpu() */ 1124 /* FIXME: use work_on_cpu() */
1109 set_cpus_allowed_ptr(current, cpumask_of(i)); 1125 if (set_cpus_allowed_ptr(current, cpumask_of(i)))
1126 continue;
1110 ret = match_pr->throttling. 1127 ret = match_pr->throttling.
1111 acpi_processor_set_throttling( 1128 acpi_processor_set_throttling(
1112 match_pr, t_state.target_state, force); 1129 match_pr, t_state.target_state, force);
@@ -1126,6 +1143,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
1126 /* restore the previous state */ 1143 /* restore the previous state */
1127 /* FIXME: use work_on_cpu() */ 1144 /* FIXME: use work_on_cpu() */
1128 set_cpus_allowed_ptr(current, saved_mask); 1145 set_cpus_allowed_ptr(current, saved_mask);
1146exit:
1129 free_cpumask_var(online_throttling_cpus); 1147 free_cpumask_var(online_throttling_cpus);
1130 free_cpumask_var(saved_mask); 1148 free_cpumask_var(saved_mask);
1131 return ret; 1149 return ret;