cpufreq: make interface functions and lock holding state clear

cpufreq_offline() calls offline() and exit() under the policy rwsem
But they are called outside the rwsem in cpufreq_online().

Make cpufreq_online() call offline() and exit() as well as online() and
init() under the policy rwsem to achieve a clear lock relationship.

All of the init() and online() implementations in the tree only
initialize the policy object without attempting to acquire the policy
rwsem and they won't call cpufreq APIs attempting to acquire it.

Signed-off-by: Schspa Shi <schspa@gmail.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
[ rjw: Changelog edits ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
Schspa Shi 2022-05-16 11:02:51 +08:00 committed by Rafael J. Wysocki
parent d4627a287e
commit 514ff1bcd9

View file

@ -1341,12 +1341,12 @@ static int cpufreq_online(unsigned int cpu)
down_write(&policy->rwsem);
policy->cpu = cpu;
policy->governor = NULL;
up_write(&policy->rwsem);
} else {
new_policy = true;
policy = cpufreq_policy_alloc(cpu);
if (!policy)
return -ENOMEM;
down_write(&policy->rwsem);
}
if (!new_policy && cpufreq_driver->online) {
@ -1386,7 +1386,6 @@ static int cpufreq_online(unsigned int cpu)
cpumask_copy(policy->related_cpus, policy->cpus);
}
down_write(&policy->rwsem);
/*
* affected cpus must always be the one, which are online. We aren't
* managing offline cpus here.
@ -1538,7 +1537,6 @@ static int cpufreq_online(unsigned int cpu)
remove_cpu_dev_symlink(policy, j, get_cpu_device(j));
cpumask_clear(policy->cpus);
up_write(&policy->rwsem);
out_offline_policy:
if (cpufreq_driver->offline)
@ -1549,6 +1547,8 @@ static int cpufreq_online(unsigned int cpu)
cpufreq_driver->exit(policy);
out_free_policy:
up_write(&policy->rwsem);
cpufreq_policy_free(policy);
return ret;
}