@@ -947,13 +947,14 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf)
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
- ssize_t ret;
+ ssize_t ret = -EBUSY;
if (!fattr->show)
return -EIO;
down_read(&policy->rwsem);
- ret = fattr->show(policy, buf);
+ if (likely(!policy_is_inactive(policy)))
+ ret = fattr->show(policy, buf);
up_read(&policy->rwsem);
return ret;
@@ -964,7 +965,7 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
{
struct cpufreq_policy *policy = to_policy(kobj);
struct freq_attr *fattr = to_attr(attr);
- ssize_t ret = -EINVAL;
+ ssize_t ret = -EBUSY;
if (!fattr->store)
return -EIO;
@@ -978,7 +979,8 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr,
if (cpu_online(policy->cpu)) {
down_write(&policy->rwsem);
- ret = fattr->store(policy, buf, count);
+ if (likely(!policy_is_inactive(policy)))
+ ret = fattr->store(policy, buf, count);
up_write(&policy->rwsem);
}
@@ -1533,6 +1535,7 @@ static int cpufreq_online(unsigned int cpu)
for_each_cpu(j, policy->real_cpus)
remove_cpu_dev_symlink(policy, get_cpu_device(j));
+ cpumask_clear(policy->cpus);
up_write(&policy->rwsem);
out_offline_policy:
If policy initialization fails after the sysfs files are created, there is a possibility that we may end up running show()/store() callbacks for half initialized policies, which may have unpredictable outcomes. Abort show/store in such a case by making sure the policy is active. Also inactivate the policy on such failures. Signed-off-by: Schspa Shi <schspa@gmail.com> --- Changelog: v1 -> v2: - Fix bad critical region enlarge which causes uninitialized unlock. - Move cpumask_clear(policy->cpus); before out_offline_policy v2 -> v3: - Remove the missed down_write() before cpumask_and(policy->cpus, policy->cpus, cpu_online_mask); v3 -> v4: - Seprate to two patchs. - Add policy_is_inactive check before sysfs access v4 -> v5: - Change the commit message as Viresh advised. - Initialize ret to -EBUSY to get rid of the else part. --- drivers/cpufreq/cpufreq.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)