Message ID | 1666168845-67690-2-git-send-email-guanjun@linux.alibaba.com |
---|---|
State | New |
Headers | show |
Series | cpufreq: Fix show()/store() issue for hotplugging | expand |
Hi Rafael, > 2022年10月19日 下午7:47,Rafael J. Wysocki <rafael@kernel.org> 写道: > > On Wed, Oct 19, 2022 at 10:40 AM Guanjun <guanjun@linux.alibaba.com> wrote: >> >> From: Zelin Deng <zelin.deng@linux.alibaba.com> >> >> After brought one CPU offline, lscpu returned failure: >> >> lscpu: cannot read /sys/devices/system/cpu/cpu64/cpufreq/cpuinfo_max_freq: Device or resource busy >> >> which had blocked all outputs of lscpu. > > OK, so the policy->cpus mask is empty and -EBUSY is returned. > > What's wrong? Here is all right. The problem is that when I offline one cpu manually and lscpu will fail. The reproduce process is as follows: 1. lscpu (success) 2. echo 0 > /sys/devices/system/cpu/cpu63/online (offline cpu63) 3. lscpu (fail, and print the error message, “lscpu: cannot read /sys/devices/system/cpu/cpu64/cpufreq/cpuinfo_max_freq: Device or resource busy”) I think this failure doesn’t make sense. Maybe I should make the commit message more readable. Thanks, Guanjun > >> This is not the case mentioned in commit d4627a287e251, as the policy >> had been created successfully but is inactive due to CPU gets offline. > > Yes, that's when policy_is_inactive(policy) returns "true" IIUC. > >> To fix this issue, just add an addtional check whether CPU is online or >> not. > > Which is racy. > > Please explain the problem in the first place. > >> Fixes: d4627a287e251 ("cpufreq: Abort show()/store() for half-initialized policies") >> Signed-off-by: Zelin Deng <zelin.deng@linux.alibaba.com> >> Signed-off-by: Guanjun <guanjun@linux.alibaba.com> >> --- >> drivers/cpufreq/cpufreq.c | 16 ++++++++++++---- >> 1 file changed, 12 insertions(+), 4 deletions(-) >> >> diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c >> index 69b3d61852ac..aa238ba7d2fe 100644 >> --- a/drivers/cpufreq/cpufreq.c >> +++ b/drivers/cpufreq/cpufreq.c >> @@ -956,8 +956,12 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) >> return -EIO; >> >> down_read(&policy->rwsem); >> - if (likely(!policy_is_inactive(policy))) >> - ret = fattr->show(policy, buf); >> + if (unlikely(policy_is_inactive(policy) && cpu_online(policy->cpu))) >> + goto err; >> + >> + ret = fattr->show(policy, buf); >> + >> +err: >> up_read(&policy->rwsem); >> >> return ret; >> @@ -974,8 +978,12 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, >> return -EIO; >> >> down_write(&policy->rwsem); >> - if (likely(!policy_is_inactive(policy))) >> - ret = fattr->store(policy, buf, count); >> + if (unlikely(policy_is_inactive(policy) && cpu_online(policy->cpu))) >> + goto err; >> + >> + ret = fattr->store(policy, buf, count); >> + >> +err: >> up_write(&policy->rwsem); >> >> return ret; >> -- >> 2.32.0.GIT
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 69b3d61852ac..aa238ba7d2fe 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -956,8 +956,12 @@ static ssize_t show(struct kobject *kobj, struct attribute *attr, char *buf) return -EIO; down_read(&policy->rwsem); - if (likely(!policy_is_inactive(policy))) - ret = fattr->show(policy, buf); + if (unlikely(policy_is_inactive(policy) && cpu_online(policy->cpu))) + goto err; + + ret = fattr->show(policy, buf); + +err: up_read(&policy->rwsem); return ret; @@ -974,8 +978,12 @@ static ssize_t store(struct kobject *kobj, struct attribute *attr, return -EIO; down_write(&policy->rwsem); - if (likely(!policy_is_inactive(policy))) - ret = fattr->store(policy, buf, count); + if (unlikely(policy_is_inactive(policy) && cpu_online(policy->cpu))) + goto err; + + ret = fattr->store(policy, buf, count); + +err: up_write(&policy->rwsem); return ret;