Skip to content

Commit

Permalink
ACPI: Check the returned value of set_cpus_allowed_ptr before T-state…
Browse files Browse the repository at this point in the history
… 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 <[email protected]>
Signed-off-by: Len Brown <[email protected]>
  • Loading branch information
yakuizhao authored and lenb committed Jan 10, 2011
1 parent 3c0eee3 commit daef1f3
Showing 1 changed file with 21 additions and 3 deletions.
24 changes: 21 additions & 3 deletions drivers/acpi/processor_throttling.c
Original file line number Diff line number Diff line change
Expand Up @@ -876,7 +876,11 @@ static int acpi_processor_get_throttling(struct acpi_processor *pr)
*/
cpumask_copy(saved_mask, &current->cpus_allowed);
/* 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);
/* restore the previous state */
set_cpus_allowed_ptr(current, saved_mask);
Expand Down Expand Up @@ -1051,6 +1055,14 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
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, &current->cpus_allowed);
t_state.target_state = state;
p_throttling = &(pr->throttling);
Expand All @@ -1074,7 +1086,11 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
*/
if (p_throttling->shared_type == DOMAIN_COORD_TYPE_SW_ANY) {
/* 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,
t_state.target_state, force);
} else {
Expand Down Expand Up @@ -1106,7 +1122,8 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
}
t_state.cpu = i;
/* 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.
acpi_processor_set_throttling(
match_pr, t_state.target_state, force);
Expand All @@ -1126,6 +1143,7 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
/* restore the previous state */
/* FIXME: use work_on_cpu() */
set_cpus_allowed_ptr(current, saved_mask);
exit:
free_cpumask_var(online_throttling_cpus);
free_cpumask_var(saved_mask);
return ret;
Expand Down

0 comments on commit daef1f3

Please sign in to comment.