Merge branches 'pm-cpufreq', 'pm-hibernate' and 'acpi-processor'
* pm-cpufreq: intel_pstate: Change busy calculation to use fixed point math. * pm-hibernate: PM / hibernate: Fix restore hang in freeze_processes() * acpi-processor: ACPI / processor: Rework processor throttling with work_on_cpu()
This commit is contained in:
commit
6c09ea49ce
|
@ -56,6 +56,12 @@ struct throttling_tstate {
|
||||||
int target_state; /* target T-state */
|
int target_state; /* target T-state */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct acpi_processor_throttling_arg {
|
||||||
|
struct acpi_processor *pr;
|
||||||
|
int target_state;
|
||||||
|
bool force;
|
||||||
|
};
|
||||||
|
|
||||||
#define THROTTLING_PRECHANGE (1)
|
#define THROTTLING_PRECHANGE (1)
|
||||||
#define THROTTLING_POSTCHANGE (2)
|
#define THROTTLING_POSTCHANGE (2)
|
||||||
|
|
||||||
|
@ -1060,16 +1066,24 @@ static int acpi_processor_set_throttling_ptc(struct acpi_processor *pr,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static long acpi_processor_throttling_fn(void *data)
|
||||||
|
{
|
||||||
|
struct acpi_processor_throttling_arg *arg = data;
|
||||||
|
struct acpi_processor *pr = arg->pr;
|
||||||
|
|
||||||
|
return pr->throttling.acpi_processor_set_throttling(pr,
|
||||||
|
arg->target_state, arg->force);
|
||||||
|
}
|
||||||
|
|
||||||
int acpi_processor_set_throttling(struct acpi_processor *pr,
|
int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
int state, bool force)
|
int state, bool force)
|
||||||
{
|
{
|
||||||
cpumask_var_t saved_mask;
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
struct acpi_processor *match_pr;
|
struct acpi_processor *match_pr;
|
||||||
struct acpi_processor_throttling *p_throttling;
|
struct acpi_processor_throttling *p_throttling;
|
||||||
|
struct acpi_processor_throttling_arg arg;
|
||||||
struct throttling_tstate t_state;
|
struct throttling_tstate t_state;
|
||||||
cpumask_var_t online_throttling_cpus;
|
|
||||||
|
|
||||||
if (!pr)
|
if (!pr)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1080,14 +1094,6 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
if ((state < 0) || (state > (pr->throttling.state_count - 1)))
|
if ((state < 0) || (state > (pr->throttling.state_count - 1)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!alloc_cpumask_var(&saved_mask, GFP_KERNEL))
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
if (!alloc_cpumask_var(&online_throttling_cpus, GFP_KERNEL)) {
|
|
||||||
free_cpumask_var(saved_mask);
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cpu_is_offline(pr->id)) {
|
if (cpu_is_offline(pr->id)) {
|
||||||
/*
|
/*
|
||||||
* the cpu pointed by pr->id is offline. Unnecessary to change
|
* the cpu pointed by pr->id is offline. Unnecessary to change
|
||||||
|
@ -1096,17 +1102,15 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
cpumask_and(online_throttling_cpus, cpu_online_mask,
|
|
||||||
p_throttling->shared_cpu_map);
|
|
||||||
/*
|
/*
|
||||||
* The throttling notifier will be called for every
|
* The throttling notifier will be called for every
|
||||||
* affected cpu in order to get one proper T-state.
|
* affected cpu in order to get one proper T-state.
|
||||||
* The notifier event is THROTTLING_PRECHANGE.
|
* The notifier event is THROTTLING_PRECHANGE.
|
||||||
*/
|
*/
|
||||||
for_each_cpu(i, online_throttling_cpus) {
|
for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) {
|
||||||
t_state.cpu = i;
|
t_state.cpu = i;
|
||||||
acpi_processor_throttling_notifier(THROTTLING_PRECHANGE,
|
acpi_processor_throttling_notifier(THROTTLING_PRECHANGE,
|
||||||
&t_state);
|
&t_state);
|
||||||
|
@ -1118,21 +1122,18 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
* it can be called only for the cpu pointed by pr.
|
* it can be called only for the cpu pointed by 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() */
|
arg.pr = pr;
|
||||||
if (set_cpus_allowed_ptr(current, cpumask_of(pr->id))) {
|
arg.target_state = state;
|
||||||
/* Can't migrate to the pr->id CPU. Exit */
|
arg.force = force;
|
||||||
ret = -ENODEV;
|
ret = work_on_cpu(pr->id, acpi_processor_throttling_fn, &arg);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
ret = p_throttling->acpi_processor_set_throttling(pr,
|
|
||||||
t_state.target_state, force);
|
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* When the T-state coordination is SW_ALL or HW_ALL,
|
* When the T-state coordination is SW_ALL or HW_ALL,
|
||||||
* it is necessary to set T-state for every affected
|
* it is necessary to set T-state for every affected
|
||||||
* cpus.
|
* cpus.
|
||||||
*/
|
*/
|
||||||
for_each_cpu(i, online_throttling_cpus) {
|
for_each_cpu_and(i, cpu_online_mask,
|
||||||
|
p_throttling->shared_cpu_map) {
|
||||||
match_pr = per_cpu(processors, i);
|
match_pr = per_cpu(processors, i);
|
||||||
/*
|
/*
|
||||||
* If the pointer is invalid, we will report the
|
* If the pointer is invalid, we will report the
|
||||||
|
@ -1153,13 +1154,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
"on CPU %d\n", i));
|
"on CPU %d\n", i));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
t_state.cpu = i;
|
|
||||||
/* FIXME: use work_on_cpu() */
|
arg.pr = match_pr;
|
||||||
if (set_cpus_allowed_ptr(current, cpumask_of(i)))
|
arg.target_state = state;
|
||||||
continue;
|
arg.force = force;
|
||||||
ret = match_pr->throttling.
|
ret = work_on_cpu(pr->id, acpi_processor_throttling_fn,
|
||||||
acpi_processor_set_throttling(
|
&arg);
|
||||||
match_pr, t_state.target_state, force);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1168,17 +1168,12 @@ int acpi_processor_set_throttling(struct acpi_processor *pr,
|
||||||
* affected cpu to update the T-states.
|
* affected cpu to update the T-states.
|
||||||
* The notifier event is THROTTLING_POSTCHANGE
|
* The notifier event is THROTTLING_POSTCHANGE
|
||||||
*/
|
*/
|
||||||
for_each_cpu(i, online_throttling_cpus) {
|
for_each_cpu_and(i, cpu_online_mask, p_throttling->shared_cpu_map) {
|
||||||
t_state.cpu = i;
|
t_state.cpu = i;
|
||||||
acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
|
acpi_processor_throttling_notifier(THROTTLING_POSTCHANGE,
|
||||||
&t_state);
|
&t_state);
|
||||||
}
|
}
|
||||||
/* 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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1580,6 +1580,7 @@ static int fw_pm_notify(struct notifier_block *notify_block,
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PM_HIBERNATION_PREPARE:
|
case PM_HIBERNATION_PREPARE:
|
||||||
case PM_SUSPEND_PREPARE:
|
case PM_SUSPEND_PREPARE:
|
||||||
|
case PM_RESTORE_PREPARE:
|
||||||
kill_requests_without_uevent();
|
kill_requests_without_uevent();
|
||||||
device_cache_fw_images();
|
device_cache_fw_images();
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue