diff mbox

[3/3] cpufreq: Prevent problems in update_policy_cpu() if last_cpu == new_cpu

Message ID 20130911201334.7832.49714.stgit@srivatsabhat.in.ibm.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Srivatsa S. Bhat Sept. 11, 2013, 8:13 p.m. UTC
If update_policy_cpu() is invoked with the existing policy->cpu itself
as the new-cpu parameter, then a lot of things can go terribly wrong.

In its present form, update_policy_cpu() always assumes that the new-cpu
is different from policy->cpu and invokes other functions to perform their
respective updates. And those functions implement the actual update like
this:

per_cpu(..., new_cpu) = per_cpu(..., last_cpu);
per_cpu(..., last_cpu) = NULL;

Thus, when new_cpu == last_cpu, the final NULL assignment makes the per-cpu
references vanish into thin air! (memory leak). From there, it leads to more
problems: cpufreq_stats_create_table() now doesn't find the per-cpu reference
and hence tries to create a new sysfs-group; but sysfs already had created
the group earlier, so it complains that it cannot create a duplicate filename.
In short, the repercussions of a rather innocuous invocation of
update_policy_cpu() can turn out to be pretty nasty.

Ideally update_policy_cpu() should handle this situation (new == last)
gracefully, and not lead to such severe problems. So fix it by adding an
appropriate check.

Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
Tested-by: Stephen Warren <swarren@nvidia.com>
---

 drivers/cpufreq/cpufreq.c |    3 +++
 1 file changed, 3 insertions(+)


--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Comments

Viresh Kumar Sept. 12, 2013, 6:09 a.m. UTC | #1
On 12 September 2013 01:43, Srivatsa S. Bhat
<srivatsa.bhat@linux.vnet.ibm.com> wrote:
> If update_policy_cpu() is invoked with the existing policy->cpu itself
> as the new-cpu parameter, then a lot of things can go terribly wrong.
>
> In its present form, update_policy_cpu() always assumes that the new-cpu
> is different from policy->cpu and invokes other functions to perform their
> respective updates. And those functions implement the actual update like
> this:
>
> per_cpu(..., new_cpu) = per_cpu(..., last_cpu);
> per_cpu(..., last_cpu) = NULL;
>
> Thus, when new_cpu == last_cpu, the final NULL assignment makes the per-cpu
> references vanish into thin air! (memory leak). From there, it leads to more
> problems: cpufreq_stats_create_table() now doesn't find the per-cpu reference
> and hence tries to create a new sysfs-group; but sysfs already had created
> the group earlier, so it complains that it cannot create a duplicate filename.
> In short, the repercussions of a rather innocuous invocation of
> update_policy_cpu() can turn out to be pretty nasty.
>
> Ideally update_policy_cpu() should handle this situation (new == last)
> gracefully, and not lead to such severe problems. So fix it by adding an
> appropriate check.
>
> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
> Tested-by: Stephen Warren <swarren@nvidia.com>
> ---
>
>  drivers/cpufreq/cpufreq.c |    3 +++
>  1 file changed, 3 insertions(+)

We don't need this patch for the reasons that I outlined in other thread.
We should never call this routine when cpu == policy->cpu
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Srivatsa S. Bhat Sept. 12, 2013, 6:21 a.m. UTC | #2
On 09/12/2013 11:39 AM, Viresh Kumar wrote:
> On 12 September 2013 01:43, Srivatsa S. Bhat
> <srivatsa.bhat@linux.vnet.ibm.com> wrote:
>> If update_policy_cpu() is invoked with the existing policy->cpu itself
>> as the new-cpu parameter, then a lot of things can go terribly wrong.
>>
>> In its present form, update_policy_cpu() always assumes that the new-cpu
>> is different from policy->cpu and invokes other functions to perform their
>> respective updates. And those functions implement the actual update like
>> this:
>>
>> per_cpu(..., new_cpu) = per_cpu(..., last_cpu);
>> per_cpu(..., last_cpu) = NULL;
>>
>> Thus, when new_cpu == last_cpu, the final NULL assignment makes the per-cpu
>> references vanish into thin air! (memory leak). From there, it leads to more
>> problems: cpufreq_stats_create_table() now doesn't find the per-cpu reference
>> and hence tries to create a new sysfs-group; but sysfs already had created
>> the group earlier, so it complains that it cannot create a duplicate filename.
>> In short, the repercussions of a rather innocuous invocation of
>> update_policy_cpu() can turn out to be pretty nasty.
>>
>> Ideally update_policy_cpu() should handle this situation (new == last)
>> gracefully, and not lead to such severe problems. So fix it by adding an
>> appropriate check.
>>
>> Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
>> Tested-by: Stephen Warren <swarren@nvidia.com>
>> ---
>>
>>  drivers/cpufreq/cpufreq.c |    3 +++
>>  1 file changed, 3 insertions(+)
> 
> We don't need this patch for the reasons that I outlined in other thread.

Yeah, we don't need it, but its a good-to-have.

> We should never call this routine when cpu == policy->cpu
> 

Yeah, that's the rule. But no harm in having safe-guards to prevent catastrophes
when we have bugs (code which breaks the rule). Its the same as what we
regularly do in code that access pointers:

if (!ptr)
	return;
or

if (ptr)
	ptr->field = value;

Not having these checks crashes the kernel in case of a bug, which is far more
disastrous than surviving the erroneous input and returning an error code
gracefully. Same analogy applies to this patch as well.

That said, indeed currently there is no code in cpufreq that invokes the
function with last == new. So its not like we are masking an existing bug with
this patch. If you like, perhaps we can change this patch to print a warning
when it gets input values with last == new? That prevents disasters and also
warns when some code is buggy. Sounds like a win-win.

Regards,
Srivatsa S. Bhat

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Srivatsa S. Bhat Sept. 12, 2013, 6:30 a.m. UTC | #3
On 09/12/2013 12:01 PM, Viresh Kumar wrote:
> On 12 September 2013 11:51, Srivatsa S. Bhat
> <srivatsa.bhat@linux.vnet.ibm.com> wrote:
>> That said, indeed currently there is no code in cpufreq that invokes the
>> function with last == new. So its not like we are masking an existing bug with
>> this patch. If you like, perhaps we can change this patch to print a warning
>> when it gets input values with last == new? That prevents disasters and also
>> warns when some code is buggy. Sounds like a win-win.
> 
> Exactly what I thought while I was midway reading your mail :)
> Probably a WARN().. So that we don't miss any other bugs :)
> 

Looking at the rate at which we are bumping into each others thoughts, I think
maybe we should switch from email to IRC ;-) ;-)

Regards,
Srivatsa S. Bhat

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Viresh Kumar Sept. 12, 2013, 6:31 a.m. UTC | #4
On 12 September 2013 11:51, Srivatsa S. Bhat
<srivatsa.bhat@linux.vnet.ibm.com> wrote:
> That said, indeed currently there is no code in cpufreq that invokes the
> function with last == new. So its not like we are masking an existing bug with
> this patch. If you like, perhaps we can change this patch to print a warning
> when it gets input values with last == new? That prevents disasters and also
> warns when some code is buggy. Sounds like a win-win.

Exactly what I thought while I was midway reading your mail :)
Probably a WARN().. So that we don't miss any other bugs :)
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Viresh Kumar Sept. 12, 2013, 6:44 a.m. UTC | #5
On 12 September 2013 12:00, Srivatsa S. Bhat
<srivatsa.bhat@linux.vnet.ibm.com> wrote:
> Looking at the rate at which we are bumping into each others thoughts, I think
> maybe we should switch from email to IRC ;-) ;-)

Unbelievable, Even I thought so this morning :)

One more thing that I wanted to say for some other threads..
Your changelogs are simply superb.. The amount of information that you put in
them is fantastic.. I never do it that way and so get caught by Rafael a number
of times :)

Need to learn this from you for sure :)

Btw, I am on Freenode for many Linaro channels.... Where can I find you on
IRC? (Haven't sent this in a private mail as others might also find it useful)
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Srivatsa S. Bhat Sept. 12, 2013, 7:12 a.m. UTC | #6
On 09/12/2013 12:14 PM, Viresh Kumar wrote:
> On 12 September 2013 12:00, Srivatsa S. Bhat
> <srivatsa.bhat@linux.vnet.ibm.com> wrote:
>> Looking at the rate at which we are bumping into each others thoughts, I think
>> maybe we should switch from email to IRC ;-) ;-)
> 
> Unbelievable, Even I thought so this morning :)
> 
> One more thing that I wanted to say for some other threads..
> Your changelogs are simply superb.. The amount of information that you put in
> them is fantastic.. 

Thank you! :-) I'm glad to hear that!

Believe it or not, I spend almost an equal (if not more) amount of time ensuring
that I get the changelog absolutely right, compared to the time I spend actually
writing the code. The reason is that, I have been pleasantly surprised by the
power of the changelog in numerous occasions: the very act of composing a proper 
changelog forces me to think *much* more clearly than when writing code. And it
often gives me the opportunity to rethink the *entire* approach/solution and not
just the implementation, since I need to explain the full context in it, not
just what the code does. And *that* exercise can reveal more complex/subtle bugs
than mere code review can ever do. That's why I put so much emphasis on writing
a perfect changelog :-) [Believe it or not, I have had times when I figured out
that my entire solution was utterly nonsensical when I began writing the changelog,
*after* reviewing and testing the code! ... and of course I had to rework the
entire patch! ;-( ]

And to prevent myself from going overboard with writing the changelog (like making
it way too verbose or convoluted with too much detail), I have a simple mechanism/
handy rule in place:

The changelog should be such that, whoever reads the changelog should feel that
the time he spent reading it was totally worth it. IOW, it should not simply
regurgitate what is already obvious from the code. Instead it should provide
insights into the subtle aspects or tradeoffs relevant to the patch; in short, it
should explain the "_why_ behind the _what_" as clearly and in as few words as
possible :-)

Well, atleast I _try_ to stick to that rule :-)

> I never do it that way and so get caught by Rafael a number
> of times :)
> 

Hehe ;-)

> Need to learn this from you for sure :)
> 
> Btw, I am on Freenode for many Linaro channels.... Where can I find you on
> IRC? (Haven't sent this in a private mail as others might also find it useful)
> 

You can find me on ##kernel on freenode. Or, Rafael has a #pm channel for power
management discussions on tinc.sekrit.org.

Regards,
Srivatsa S. Bhat


--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Viresh Kumar Sept. 12, 2013, 10:30 a.m. UTC | #7
On 12 September 2013 16:10, Rafael J. Wysocki <rjw@sisk.pl> wrote:
> Can you please prepare a patch against Documentation/SubmittingPatches with the
> above paragraph in it?  Seriously.

+1

> There are people who don't really see a reason for writing good patch
> changelogs.

+1 for being one of those people :)
--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Rafael Wysocki Sept. 12, 2013, 10:40 a.m. UTC | #8
On Thursday, September 12, 2013 12:42:29 PM Srivatsa S. Bhat wrote:
> On 09/12/2013 12:14 PM, Viresh Kumar wrote:
> > On 12 September 2013 12:00, Srivatsa S. Bhat
> > <srivatsa.bhat@linux.vnet.ibm.com> wrote:
> >> Looking at the rate at which we are bumping into each others thoughts, I think
> >> maybe we should switch from email to IRC ;-) ;-)
> > 
> > Unbelievable, Even I thought so this morning :)
> > 
> > One more thing that I wanted to say for some other threads..
> > Your changelogs are simply superb.. The amount of information that you put in
> > them is fantastic.. 
> 
> Thank you! :-) I'm glad to hear that!
> 
> Believe it or not, I spend almost an equal (if not more) amount of time ensuring
> that I get the changelog absolutely right, compared to the time I spend actually
> writing the code. The reason is that, I have been pleasantly surprised by the
> power of the changelog in numerous occasions: the very act of composing a proper 
> changelog forces me to think *much* more clearly than when writing code. And it
> often gives me the opportunity to rethink the *entire* approach/solution and not
> just the implementation, since I need to explain the full context in it, not
> just what the code does. And *that* exercise can reveal more complex/subtle bugs
> than mere code review can ever do. That's why I put so much emphasis on writing
> a perfect changelog :-) [Believe it or not, I have had times when I figured out
> that my entire solution was utterly nonsensical when I began writing the changelog,
> *after* reviewing and testing the code! ... and of course I had to rework the
> entire patch! ;-( ]
> 
> And to prevent myself from going overboard with writing the changelog (like making
> it way too verbose or convoluted with too much detail), I have a simple mechanism/
> handy rule in place:
> 
> The changelog should be such that, whoever reads the changelog should feel that
> the time he spent reading it was totally worth it. IOW, it should not simply
> regurgitate what is already obvious from the code. Instead it should provide
> insights into the subtle aspects or tradeoffs relevant to the patch; in short, it
> should explain the "_why_ behind the _what_" as clearly and in as few words as
> possible :-)
> 
> Well, atleast I _try_ to stick to that rule :-)

Can you please prepare a patch against Documentation/SubmittingPatches with the
above paragraph in it?  Seriously.

There are people who don't really see a reason for writing good patch
changelogs.

Thanks,
Rafael

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Srivatsa S. Bhat Sept. 12, 2013, 10:41 a.m. UTC | #9
On 09/12/2013 04:10 PM, Rafael J. Wysocki wrote:
> On Thursday, September 12, 2013 12:42:29 PM Srivatsa S. Bhat wrote:
>> On 09/12/2013 12:14 PM, Viresh Kumar wrote:
>>> On 12 September 2013 12:00, Srivatsa S. Bhat
>>> <srivatsa.bhat@linux.vnet.ibm.com> wrote:
>>>> Looking at the rate at which we are bumping into each others thoughts, I think
>>>> maybe we should switch from email to IRC ;-) ;-)
>>>
>>> Unbelievable, Even I thought so this morning :)
>>>
>>> One more thing that I wanted to say for some other threads..
>>> Your changelogs are simply superb.. The amount of information that you put in
>>> them is fantastic.. 
>>
>> Thank you! :-) I'm glad to hear that!
>>
>> Believe it or not, I spend almost an equal (if not more) amount of time ensuring
>> that I get the changelog absolutely right, compared to the time I spend actually
>> writing the code. The reason is that, I have been pleasantly surprised by the
>> power of the changelog in numerous occasions: the very act of composing a proper 
>> changelog forces me to think *much* more clearly than when writing code. And it
>> often gives me the opportunity to rethink the *entire* approach/solution and not
>> just the implementation, since I need to explain the full context in it, not
>> just what the code does. And *that* exercise can reveal more complex/subtle bugs
>> than mere code review can ever do. That's why I put so much emphasis on writing
>> a perfect changelog :-) [Believe it or not, I have had times when I figured out
>> that my entire solution was utterly nonsensical when I began writing the changelog,
>> *after* reviewing and testing the code! ... and of course I had to rework the
>> entire patch! ;-( ]
>>
>> And to prevent myself from going overboard with writing the changelog (like making
>> it way too verbose or convoluted with too much detail), I have a simple mechanism/
>> handy rule in place:
>>
>> The changelog should be such that, whoever reads the changelog should feel that
>> the time he spent reading it was totally worth it. IOW, it should not simply
>> regurgitate what is already obvious from the code. Instead it should provide
>> insights into the subtle aspects or tradeoffs relevant to the patch; in short, it
>> should explain the "_why_ behind the _what_" as clearly and in as few words as
>> possible :-)
>>
>> Well, atleast I _try_ to stick to that rule :-)
> 
> Can you please prepare a patch against Documentation/SubmittingPatches with the
> above paragraph in it?  Seriously.
> 

Sure, I'd be delighted to :-)

> There are people who don't really see a reason for writing good patch
> changelogs.
> 

Regards,
Srivatsa S. Bhat

--
To unsubscribe from this list: send the line "unsubscribe linux-pm" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c
index 247842b..d32040c 100644
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -949,6 +949,9 @@  static void cpufreq_policy_free(struct cpufreq_policy *policy)
 
 static void update_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu)
 {
+	if (cpu == policy->cpu)
+		return;
+
 	policy->last_cpu = policy->cpu;
 	policy->cpu = cpu;