cpufreq: Save state for entire cluster when the last CPU goes offline
When the last CPU within a cluster goes offline its cpufreq limits and the current governor are saved so that it can start with the same state (cpufreq min/max limits and scaling governor) when it comes back online later. However if a different CPU from the same cluster comes online after this it will restore the state that it saved when it went offline and which can be different from the state of the CPU last offlined. This can leave the system in incorrect (i.e. not the latest) state since the rest of the CPUs in the same cluster brought back online later will be associated with the CPU that first came online. To prevent such a scenario save the state for all CPUs in a cluster when the last CPU goes offline (since the last CPU holds the latest updates) so that it can be properly restored by any CPU that first comes online in that cluster. Change-Id: I67cd6bb219b7cc4fd18507ffb9b43ca37dcf0ae7 Signed-off-by: Rohit Gupta <rohgup@codeaurora.org>
This commit is contained in:
parent
9b352820cb
commit
d3884c7499
|
@ -1214,6 +1214,27 @@ static int cpufreq_nominate_new_policy_cpu(struct cpufreq_policy *policy,
|
|||
return cpu_dev->id;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
static void update_related_cpus(struct cpufreq_policy *policy)
|
||||
{
|
||||
unsigned int j;
|
||||
|
||||
for_each_cpu(j, policy->related_cpus) {
|
||||
if (!cpufreq_driver->setpolicy)
|
||||
strlcpy(per_cpu(cpufreq_policy_save, j).gov,
|
||||
policy->governor->name, CPUFREQ_NAME_LEN);
|
||||
per_cpu(cpufreq_policy_save, j).min = policy->user_policy.min;
|
||||
per_cpu(cpufreq_policy_save, j).max = policy->user_policy.max;
|
||||
pr_debug("Saving CPU%d user policy min %d and max %d\n",
|
||||
j, policy->user_policy.min, policy->user_policy.max);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void update_related_cpus(struct cpufreq_policy *policy)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __cpufreq_remove_dev_prepare(struct device *dev,
|
||||
struct subsys_interface *sif,
|
||||
bool frozen)
|
||||
|
@ -1249,20 +1270,13 @@ static int __cpufreq_remove_dev_prepare(struct device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HOTPLUG_CPU
|
||||
if (!cpufreq_driver->setpolicy)
|
||||
strlcpy(per_cpu(cpufreq_policy_save, cpu).gov,
|
||||
policy->governor->name, CPUFREQ_NAME_LEN);
|
||||
per_cpu(cpufreq_policy_save, cpu).min = policy->user_policy.min;
|
||||
per_cpu(cpufreq_policy_save, cpu).max = policy->user_policy.max;
|
||||
pr_debug("Saving CPU%d user policy min %d and max %d\n",
|
||||
cpu, policy->user_policy.min, policy->user_policy.max);
|
||||
#endif
|
||||
|
||||
down_read(&policy->rwsem);
|
||||
cpus = cpumask_weight(policy->cpus);
|
||||
up_read(&policy->rwsem);
|
||||
|
||||
if (cpus == 1)
|
||||
update_related_cpus(policy);
|
||||
|
||||
if (cpu != policy->cpu) {
|
||||
sysfs_remove_link(&dev->kobj, "cpufreq");
|
||||
} else if (cpus > 1) {
|
||||
|
|
Loading…
Reference in New Issue