Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1336939 > unrolled thread
| Started by | "Rafael J. Wysocki" <rjw@rjwysocki.net> |
|---|---|
| First post | 2016-02-18 02:40 +0100 |
| Last post | 2016-02-19 04:20 +0100 |
| Articles | 6 — 3 participants |
Back to article view | Back to linux.kernel
This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by
below is the oldest one visible, not the original post.
[PATCH 1/12] cpufreq: governor: Close dbs_data update race condition "Rafael J. Wysocki" <rjw@rjwysocki.net> - 2016-02-18 02:40 +0100
Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition Viresh Kumar <viresh.kumar@linaro.org> - 2016-02-18 06:30 +0100
Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition "Rafael J. Wysocki" <rafael@kernel.org> - 2016-02-18 17:30 +0100
Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition Viresh Kumar <viresh.kumar@linaro.org> - 2016-02-19 03:30 +0100
Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition "Rafael J. Wysocki" <rafael@kernel.org> - 2016-02-19 03:40 +0100
Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition Viresh Kumar <viresh.kumar@linaro.org> - 2016-02-19 04:20 +0100
| From | "Rafael J. Wysocki" <rjw@rjwysocki.net> |
|---|---|
| Date | 2016-02-18 02:40 +0100 |
| Subject | [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition |
| Message-ID | <r3lJv-6xI-1@gated-at.bofh.it> |
From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> It is possible for a dbs_data object to be updated after its usage counter has become 0. That may happen if governor_store() runs (via a govenor tunable sysfs attribute write) in parallel with cpufreq_governor_exit() called for the last cpufreq policy associated with the dbs_data in question. In that case, if governor_store() acquires dbs_data->mutex right after cpufreq_governor_exit() has released it, the ->store() callback invoked by it may operate on dbs_data with no users. Although sysfs will cause the kobject_put() in cpufreq_governor_exit() to block until governor_store() has returned, that situation may lead to some unexpected results, depending on the implementation of the ->store callback, and therefore it should be avoided. To that end, modify governor_store() to check the dbs_data's usage count before invoking the ->store() callback and return an error if it is 0 at that point. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> --- drivers/cpufreq/cpufreq_governor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) Index: linux-pm/drivers/cpufreq/cpufreq_governor.c =================================================================== --- linux-pm.orig/drivers/cpufreq/cpufreq_governor.c +++ linux-pm/drivers/cpufreq/cpufreq_governor.c @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob mutex_lock(&dbs_data->mutex); - if (gattr->store) + if (dbs_data->usage_count && gattr->store) ret = gattr->store(dbs_data, buf, count); mutex_unlock(&dbs_data->mutex);
[toc] | [next] | [standalone]
| From | Viresh Kumar <viresh.kumar@linaro.org> |
|---|---|
| Date | 2016-02-18 06:30 +0100 |
| Subject | Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition |
| Message-ID | <r3pk6-MU-17@gated-at.bofh.it> |
| In reply to | #1336939 |
On 18-02-16, 02:19, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > It is possible for a dbs_data object to be updated after its > usage counter has become 0. That may happen if governor_store() > runs (via a govenor tunable sysfs attribute write) in parallel > with cpufreq_governor_exit() called for the last cpufreq policy > associated with the dbs_data in question. In that case, if > governor_store() acquires dbs_data->mutex right after > cpufreq_governor_exit() has released it, the ->store() callback > invoked by it may operate on dbs_data with no users. Although > sysfs will cause the kobject_put() in cpufreq_governor_exit() to > block until governor_store() has returned, that situation may > lead to some unexpected results, depending on the implementation > of the ->store callback, and therefore it should be avoided. > > To that end, modify governor_store() to check the dbs_data's > usage count before invoking the ->store() callback and return > an error if it is 0 at that point. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > --- > drivers/cpufreq/cpufreq_governor.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > Index: linux-pm/drivers/cpufreq/cpufreq_governor.c > =================================================================== > --- linux-pm.orig/drivers/cpufreq/cpufreq_governor.c > +++ linux-pm/drivers/cpufreq/cpufreq_governor.c > @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob > > mutex_lock(&dbs_data->mutex); > > - if (gattr->store) > + if (dbs_data->usage_count && gattr->store) That's not gonna be enough. The above lock doesn't guarantee protection with any such races. And so usage_count can become zero just after this check. Btw, we should also kill the gattr->store checks here as well, as we did it in cpufreq-core. > ret = gattr->store(dbs_data, buf, count); > > mutex_unlock(&dbs_data->mutex); -- viresh
[toc] | [prev] | [next] | [standalone]
| From | "Rafael J. Wysocki" <rafael@kernel.org> |
|---|---|
| Date | 2016-02-18 17:30 +0100 |
| Message-ID | <r3zCP-8go-17@gated-at.bofh.it> |
| In reply to | #1337045 |
On Thu, Feb 18, 2016 at 6:24 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote: > On 18-02-16, 02:19, Rafael J. Wysocki wrote: >> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> >> >> It is possible for a dbs_data object to be updated after its >> usage counter has become 0. That may happen if governor_store() >> runs (via a govenor tunable sysfs attribute write) in parallel >> with cpufreq_governor_exit() called for the last cpufreq policy >> associated with the dbs_data in question. In that case, if >> governor_store() acquires dbs_data->mutex right after >> cpufreq_governor_exit() has released it, the ->store() callback >> invoked by it may operate on dbs_data with no users. Although >> sysfs will cause the kobject_put() in cpufreq_governor_exit() to >> block until governor_store() has returned, that situation may >> lead to some unexpected results, depending on the implementation >> of the ->store callback, and therefore it should be avoided. >> >> To that end, modify governor_store() to check the dbs_data's >> usage count before invoking the ->store() callback and return >> an error if it is 0 at that point. >> >> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> >> --- >> drivers/cpufreq/cpufreq_governor.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> Index: linux-pm/drivers/cpufreq/cpufreq_governor.c >> =================================================================== >> --- linux-pm.orig/drivers/cpufreq/cpufreq_governor.c >> +++ linux-pm/drivers/cpufreq/cpufreq_governor.c >> @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob >> >> mutex_lock(&dbs_data->mutex); >> >> - if (gattr->store) >> + if (dbs_data->usage_count && gattr->store) > > That's not gonna be enough. The above lock doesn't guarantee > protection with any such races. I'm not really sure what you're talking about to be honest, so please be more specific. You can say "For example, function X decrements the usage count without locking" or similar. Such vague comments are quite difficult to address, especially if they don't hold any water. :-) > And so usage_count can become zero > just after this check. But how? The only place it is decremented is cpufreq_governor_exit() and there it is done under dbs_data->mutex (at my direct request, BTW). So we are guaranteed that it won't go down to zero while we're holding dbs_data->mutex, aren't we? > Btw, we should also kill the gattr->store checks here as well, as we > did it in cpufreq-core. > >> ret = gattr->store(dbs_data, buf, count); >> >> mutex_unlock(&dbs_data->mutex); Yeah, they are quite useless. But not in this patch. Thanks, Rafael
[toc] | [prev] | [next] | [standalone]
| From | Viresh Kumar <viresh.kumar@linaro.org> |
|---|---|
| Date | 2016-02-19 03:30 +0100 |
| Subject | Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition |
| Message-ID | <r3IZs-6yl-5@gated-at.bofh.it> |
| In reply to | #1337507 |
On 18-02-16, 17:20, Rafael J. Wysocki wrote: > On Thu, Feb 18, 2016 at 6:24 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote: > > On 18-02-16, 02:19, Rafael J. Wysocki wrote: > >> @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob > >> > >> mutex_lock(&dbs_data->mutex); > >> > >> - if (gattr->store) > >> + if (dbs_data->usage_count && gattr->store) > > > > That's not gonna be enough. The above lock doesn't guarantee > > protection with any such races. Oops, I completely misread it. Really sorry about that. But now that I have read the code again, I wonder why we need this protection at all. The first thing we do after decrementing the usage_count counter, is we put the kobject. Which will ensure that the sysfs files are all gone. So, what is the race we are trying to fix then? > Yeah, they are quite useless. But not in this patch. Sure. -- viresh
[toc] | [prev] | [next] | [standalone]
| From | "Rafael J. Wysocki" <rafael@kernel.org> |
|---|---|
| Date | 2016-02-19 03:40 +0100 |
| Message-ID | <r3J97-6Cc-9@gated-at.bofh.it> |
| In reply to | #1337838 |
On Fri, Feb 19, 2016 at 3:27 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote: > On 18-02-16, 17:20, Rafael J. Wysocki wrote: >> On Thu, Feb 18, 2016 at 6:24 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote: >> > On 18-02-16, 02:19, Rafael J. Wysocki wrote: > >> >> @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob >> >> >> >> mutex_lock(&dbs_data->mutex); >> >> >> >> - if (gattr->store) >> >> + if (dbs_data->usage_count && gattr->store) >> > >> > That's not gonna be enough. The above lock doesn't guarantee >> > protection with any such races. > > Oops, I completely misread it. Really sorry about that. > > But now that I have read the code again, I wonder why we need this protection at > all. The first thing we do after decrementing the usage_count counter, is we put > the kobject. Which will ensure that the sysfs files are all gone. So, what is > the race we are trying to fix then? The ->store() callbacks for different attributes may do silly stuff like walking all CPUs in the system and updating per-CPU data for them. If the dbs_data the callback has been called for is going away, this is pointless at best and may be actually harmful depending on what the callback is really doing. Thanks, Rafael
[toc] | [prev] | [next] | [standalone]
| From | Viresh Kumar <viresh.kumar@linaro.org> |
|---|---|
| Date | 2016-02-19 04:20 +0100 |
| Subject | Re: [PATCH 1/12] cpufreq: governor: Close dbs_data update race condition |
| Message-ID | <r3JLP-7bz-13@gated-at.bofh.it> |
| In reply to | #1336939 |
On 18-02-16, 02:19, Rafael J. Wysocki wrote: > From: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > It is possible for a dbs_data object to be updated after its > usage counter has become 0. That may happen if governor_store() > runs (via a govenor tunable sysfs attribute write) in parallel > with cpufreq_governor_exit() called for the last cpufreq policy > associated with the dbs_data in question. In that case, if > governor_store() acquires dbs_data->mutex right after > cpufreq_governor_exit() has released it, the ->store() callback > invoked by it may operate on dbs_data with no users. Although > sysfs will cause the kobject_put() in cpufreq_governor_exit() to > block until governor_store() has returned, that situation may > lead to some unexpected results, depending on the implementation > of the ->store callback, and therefore it should be avoided. > > To that end, modify governor_store() to check the dbs_data's > usage count before invoking the ->store() callback and return > an error if it is 0 at that point. > > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > --- > drivers/cpufreq/cpufreq_governor.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > Index: linux-pm/drivers/cpufreq/cpufreq_governor.c > =================================================================== > --- linux-pm.orig/drivers/cpufreq/cpufreq_governor.c > +++ linux-pm/drivers/cpufreq/cpufreq_governor.c > @@ -112,7 +112,7 @@ static ssize_t governor_store(struct kob > > mutex_lock(&dbs_data->mutex); > > - if (gattr->store) > + if (dbs_data->usage_count && gattr->store) > ret = gattr->store(dbs_data, buf, count); > > mutex_unlock(&dbs_data->mutex); Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -- viresh
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web