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>
This commit is contained in:
@@ -876,7 +876,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
|
|||||||
*/
|
*/
|
||||||
cpumask_copy(saved_mask, ¤t->cpus_allowed);
|
cpumask_copy(saved_mask, ¤t->cpus_allowed);
|
||||||
/* FIXME: use work_on_cpu() */
|
/* FIXME: use work_on_cpu() */
|
||||||
set_cpus_allowed_ptr(current, cpumask_of(pr->id));
|
if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
|
||||||
|
/* Can't migrate to the target pr->id CPU. Exit */
|
||||||
|
free_cpumask_var(saved_mask);
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
ret = pr->throttling.acpi_processor_get_throttling(pr);
|
ret = pr->throttling.acpi_processor_get_throttling(pr);
|
||||||
/* restore the previous state */
|
/* restore the previous state */
|
||||||
set_cpus_allowed_ptr(current, saved_mask);
|
set_cpus_allowed_ptr(current, saved_mask);
|
||||||
@@ -1051,6 +1055,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cpu_is_offline(pr->id)) {
|
||||||
|
/*
|
||||||
|
* the cpu pointed by pr->id is offline. Unnecessary to change
|
||||||
|
* the throttling state any more.
|
||||||
|
*/
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
cpumask_copy(saved_mask, ¤t->cpus_allowed);
|
cpumask_copy(saved_mask, ¤t->cpus_allowed);
|
||||||
t_state.target_state = state;
|
t_state.target_state = state;
|
||||||
p_throttling = &(pr->throttling);
|
p_throttling = &(pr->throttling);
|
||||||
@@ -1074,7 +1086,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|||||||
*/
|
*/
|
||||||
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
|
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
|
||||||
/* FIXME: use work_on_cpu() */
|
/* FIXME: use work_on_cpu() */
|
||||||
set_cpus_allowed_ptr(current, cpumask_of(pr->id));
|
if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
|
||||||
|
/* Can't migrate to the pr->id CPU. Exit */
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
ret = p_throttling->acpi_processor_set_throttling(pr,
|
ret = p_throttling->acpi_processor_set_throttling(pr,
|
||||||
t_state.target_state, force);
|
t_state.target_state, force);
|
||||||
} else {
|
} else {
|
||||||
@@ -1106,7 +1122,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|||||||
}
|
}
|
||||||
t_state.cpu = i;
|
t_state.cpu = i;
|
||||||
/* FIXME: use work_on_cpu() */
|
/* FIXME: use work_on_cpu() */
|
||||||
set_cpus_allowed_ptr(current, cpumask_of(i));
|
if (set_cpus_allowed_ptr(current, cpumask_of(i)))
|
||||||
|
continue;
|
||||||
ret = match_pr->throttling.
|
ret = match_pr->throttling.
|
||||||
acpi_processor_set_throttling(
|
acpi_processor_set_throttling(
|
||||||
match_pr, t_state.target_state, force);
|
match_pr, t_state.target_state, force);
|
||||||
@@ -1126,6 +1143,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
|||||||
/* restore the previous state */
|
/* restore the previous state */
|
||||||
/* FIXME: use work_on_cpu() */
|
/* FIXME: use work_on_cpu() */
|
||||||
set_cpus_allowed_ptr(current, saved_mask);
|
set_cpus_allowed_ptr(current, saved_mask);
|
||||||
|
exit:
|
||||||
free_cpumask_var(online_throttling_cpus);
|
free_cpumask_var(online_throttling_cpus);
|
||||||
free_cpumask_var(saved_mask);
|
free_cpumask_var(saved_mask);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
Reference in New Issue
Block a user