From: "Rafael J. Wysocki" <rjw@rjwysocki.net>
To: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Linux PM list <linux-pm@vger.kernel.org>,
Linux Kernel Mailing List <linux-kernel@vger.kernel.org>,
Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Subject: Re: [PATCH v2] cpufreq: stats: Walk online CPUs with CPU offline/online locked
Date: Fri, 20 May 2016 14:13:26 +0200 [thread overview]
Message-ID: <3805651.Y4agxXsfkM@vostro.rjw.lan> (raw)
In-Reply-To: <20160520022247.GS32001@vireshk-i7>
On Friday, May 20, 2016 07:52:47 AM Viresh Kumar wrote:
> On 20-05-16, 03:41, Rafael J. Wysocki wrote:
> > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> >
> > Loops over online CPUs in cpufreq_stats_init() and cpufreq_stats_exit()
> > should be carried out with CPU offline/online locked or races are
> > possible otherwise, so make that happen.
> >
> > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> > ---
> >
> > v1 -> v2: On a second thought, add the policy notifier in cpufreq_stats_init()
> > with CPU offline/online locked too.
> >
> > ---
> > drivers/cpufreq/cpufreq_stats.c | 16 +++++++++++++---
> > 1 file changed, 13 insertions(+), 3 deletions(-)
> >
> > Index: linux-pm/drivers/cpufreq/cpufreq_stats.c
> > ===================================================================
> > --- linux-pm.orig/drivers/cpufreq/cpufreq_stats.c
> > +++ linux-pm/drivers/cpufreq/cpufreq_stats.c
> > @@ -317,10 +317,13 @@ static int __init cpufreq_stats_init(voi
> > unsigned int cpu;
> >
> > spin_lock_init(&cpufreq_stats_lock);
> > +
> > + get_online_cpus();
> > +
> > ret = cpufreq_register_notifier(¬ifier_policy_block,
> > CPUFREQ_POLICY_NOTIFIER);
>
> Why is this required to be protected ?
Last night I thought I saw a scenario in which that notifier could run
in parallel with the loop below even with get_online_cpus() between them,
but I don't see it right now.
Maybe I should not look at stuff late in the night ...
> > if (ret)
> > - return ret;
> > + goto out;
> >
> > for_each_online_cpu(cpu)
> > cpufreq_stats_create_table(cpu);
> > @@ -332,21 +335,28 @@ static int __init cpufreq_stats_init(voi
> > CPUFREQ_POLICY_NOTIFIER);
> > for_each_online_cpu(cpu)
> > cpufreq_stats_free_table(cpu);
>
> Maybe we can make this for_each_possible_cpu() then, and so getting a
> policy will fail for CPUs which aren't online.
>
> And we wouldn't need to use get_online_cpus() then ?
That could be done, but then there would be nothing to prevent the
policy notifier from running in parallel with the loop.
Something like the patch below should do the trick, though.
---
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Subject: [PATCH] cpufreq: stats: Fix race conditions on init and cleanup
Loops over online CPUs in cpufreq_stats_init() and cpufreq_stats_exit()
are not carried out with CPU offline/online locked, so races are
possible with respect to policy initialization and cleanup.
To prevent that from happening, change the loops to walk all possible
CPUs, as cpufreq_stats_create_table() and cpufreq_stats_free_table()
handle the case when there's no policy for the given CPU cleanly,
but also use policy->rwsem in there to prevent those routines
from racing with the policy notifier.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
drivers/cpufreq/cpufreq_stats.c | 14 +++++++++-----
1 file changed, 9 insertions(+), 5 deletions(-)
Index: linux-pm/drivers/cpufreq/cpufreq_stats.c
===================================================================
--- linux-pm.orig/drivers/cpufreq/cpufreq_stats.c
+++ linux-pm/drivers/cpufreq/cpufreq_stats.c
@@ -154,7 +154,9 @@ static void cpufreq_stats_free_table(uns
if (!policy)
return;
+ down_write(&policy->rwsem);
__cpufreq_stats_free_table(policy);
+ up_write(&policy->rwsem);
cpufreq_cpu_put(policy);
}
@@ -238,7 +240,9 @@ static void cpufreq_stats_create_table(u
if (likely(!policy))
return;
+ down_write(&policy->rwsem);
__cpufreq_stats_create_table(policy);
+ up_write(&policy->rwsem);
cpufreq_cpu_put(policy);
}
@@ -322,7 +326,7 @@ static int __init cpufreq_stats_init(voi
if (ret)
return ret;
- for_each_online_cpu(cpu)
+ for_each_possible_cpu(cpu)
cpufreq_stats_create_table(cpu);
ret = cpufreq_register_notifier(¬ifier_trans_block,
@@ -330,12 +334,11 @@ static int __init cpufreq_stats_init(voi
if (ret) {
cpufreq_unregister_notifier(¬ifier_policy_block,
CPUFREQ_POLICY_NOTIFIER);
- for_each_online_cpu(cpu)
+ for_each_possible_cpu(cpu)
cpufreq_stats_free_table(cpu);
- return ret;
}
- return 0;
+ return ret;
}
static void __exit cpufreq_stats_exit(void)
{
@@ -345,7 +348,8 @@ static void __exit cpufreq_stats_exit(vo
CPUFREQ_POLICY_NOTIFIER);
cpufreq_unregister_notifier(¬ifier_trans_block,
CPUFREQ_TRANSITION_NOTIFIER);
- for_each_online_cpu(cpu)
+
+ for_each_possible_cpu(cpu)
cpufreq_stats_free_table(cpu);
}
next prev parent reply other threads:[~2016-05-20 12:09 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-05-20 1:34 [PATCH] " Rafael J. Wysocki
2016-05-20 1:41 ` [PATCH v2] " Rafael J. Wysocki
2016-05-20 2:22 ` Viresh Kumar
2016-05-20 12:13 ` Rafael J. Wysocki [this message]
2016-05-20 21:33 ` Rafael J. Wysocki
2016-05-23 3:57 ` Viresh Kumar
2016-05-23 13:40 ` Rafael J. Wysocki
2016-05-23 15:19 ` Viresh Kumar
2016-05-23 20:47 ` Rafael J. Wysocki
2016-05-24 4:56 ` Viresh Kumar
2016-05-24 12:13 ` Rafael J. Wysocki
2016-05-24 12:17 ` Viresh Kumar
2016-05-25 0:00 ` Rafael J. Wysocki
2016-05-25 0:48 ` Rafael J. Wysocki
2016-05-25 2:07 ` Viresh Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=3805651.Y4agxXsfkM@vostro.rjw.lan \
--to=rjw@rjwysocki.net \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pm@vger.kernel.org \
--cc=srinivas.pandruvada@linux.intel.com \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®