All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
@ 2018-05-08  6:42 Viresh Kumar
  2018-05-08 20:54 ` Rafael J. Wysocki
  2018-05-09  9:44 ` [PATCH] cpufreq: schedutil: Avoid using invalid next_freq Rafael J. Wysocki
  0 siblings, 2 replies; 13+ messages in thread
From: Viresh Kumar @ 2018-05-08  6:42 UTC (permalink / raw)
  To: Rafael Wysocki, Ingo Molnar, Peter Zijlstra
  Cc: Viresh Kumar, linux-pm, Vincent Guittot, claudio,
	patrick.bellasi, juri.lelli, joelaf, 4 . 12+,
	linux-kernel

The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
occasions:
- In sugov_start(), when the schedutil governor is started for a group
  of CPUs.
- And whenever we need to force a freq update before rate-limit
  duration, which happens when:
  - there is an update in cpufreq policy limits.
  - Or when the utilization of DL scheduling class increases.

In return, get_next_freq() doesn't return a cached next_freq value but
instead recalculates the next frequency. This has some side effects
though and may significantly delay a required increase in frequency.

In sugov_update_single() we try to avoid decreasing frequency if the CPU
has not been idle recently. Consider this scenario, the available range
of frequencies for a CPU are from 800 MHz to 2.5 GHz and current
frequency is 800 MHz. From one of the call paths
sg_policy->need_freq_update is set to true and hence
sg_policy->next_freq is set to UINT_MAX. Now if the CPU had been busy,
next_f will always be less than UINT_MAX, whatever the value of next_f
is. And so even when we wanted to increase the frequency, we will
overwrite next_f with UINT_MAX and will not change the frequency
eventually. This will continue until the time CPU stays busy. This isn't
cross checked with any specific test cases, but rather based on general
code review.

Fix that by not resetting the sg_policy->need_freq_update flag from
sugov_should_update_freq() but get_next_freq() and we wouldn't need to
overwrite sg_policy->next_freq anymore.

Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
Fixes: b7eaf1aab9f8 ("cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely")
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
 kernel/sched/cpufreq_schedutil.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index d2c6083304b4..daaca23697dc 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -95,15 +95,8 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
 	if (sg_policy->work_in_progress)
 		return false;
 
-	if (unlikely(sg_policy->need_freq_update)) {
-		sg_policy->need_freq_update = false;
-		/*
-		 * This happens when limits change, so forget the previous
-		 * next_freq value and force an update.
-		 */
-		sg_policy->next_freq = UINT_MAX;
+	if (unlikely(sg_policy->need_freq_update))
 		return true;
-	}
 
 	delta_ns = time - sg_policy->last_freq_update_time;
 
@@ -165,8 +158,10 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
 
 	freq = (freq + (freq >> 2)) * util / max;
 
-	if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX)
+	if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update)
 		return sg_policy->next_freq;
+
+	sg_policy->need_freq_update = false;
 	sg_policy->cached_raw_freq = freq;
 	return cpufreq_driver_resolve_freq(policy, freq);
 }
@@ -670,7 +665,7 @@ static int sugov_start(struct cpufreq_policy *policy)
 
 	sg_policy->freq_update_delay_ns	= sg_policy->tunables->rate_limit_us * NSEC_PER_USEC;
 	sg_policy->last_freq_update_time	= 0;
-	sg_policy->next_freq			= UINT_MAX;
+	sg_policy->next_freq			= 0;
 	sg_policy->work_in_progress		= false;
 	sg_policy->need_freq_update		= false;
 	sg_policy->cached_raw_freq		= 0;
-- 
2.15.0.194.g9af6a3dea062

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-08  6:42 [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
@ 2018-05-08 20:54 ` Rafael J. Wysocki
  2018-05-09  8:41   ` Viresh Kumar
  2018-05-09  9:44 ` [PATCH] cpufreq: schedutil: Avoid using invalid next_freq Rafael J. Wysocki
  1 sibling, 1 reply; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-08 20:54 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, Ingo Molnar, Peter Zijlstra, Linux PM,
	Vincent Guittot, Claudio Scordino, Patrick Bellasi, Juri Lelli,
	Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On Tue, May 8, 2018 at 8:42 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
> occasions:
> - In sugov_start(), when the schedutil governor is started for a group
>   of CPUs.
> - And whenever we need to force a freq update before rate-limit
>   duration, which happens when:
>   - there is an update in cpufreq policy limits.
>   - Or when the utilization of DL scheduling class increases.
>
> In return, get_next_freq() doesn't return a cached next_freq value but
> instead recalculates the next frequency. This has some side effects
> though and may significantly delay a required increase in frequency.
>
> In sugov_update_single() we try to avoid decreasing frequency if the CPU
> has not been idle recently. Consider this scenario, the available range
> of frequencies for a CPU are from 800 MHz to 2.5 GHz and current
> frequency is 800 MHz. From one of the call paths
> sg_policy->need_freq_update is set to true and hence
> sg_policy->next_freq is set to UINT_MAX. Now if the CPU had been busy,
> next_f will always be less than UINT_MAX, whatever the value of next_f
> is. And so even when we wanted to increase the frequency, we will
> overwrite next_f with UINT_MAX and will not change the frequency
> eventually. This will continue until the time CPU stays busy. This isn't
> cross checked with any specific test cases, but rather based on general
> code review.
>
> Fix that by not resetting the sg_policy->need_freq_update flag from
> sugov_should_update_freq() but get_next_freq() and we wouldn't need to
> overwrite sg_policy->next_freq anymore.
>
> Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
> Fixes: b7eaf1aab9f8 ("cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely")

The rest of the chantelog is totally disconnected from this commit.

So the problem is that sugov_update_single() doesn't check the special
UNIT_MAX value before assigning sg_policy->next_freq to next_f.  Fair
enough.

I don't see why the patch is the right fix for that, however.

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-08 20:54 ` Rafael J. Wysocki
@ 2018-05-09  8:41   ` Viresh Kumar
  2018-05-09  8:56     ` Rafael J. Wysocki
  0 siblings, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2018-05-09  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael Wysocki, Ingo Molnar, Peter Zijlstra, Linux PM,
	Vincent Guittot, Claudio Scordino, Patrick Bellasi, Juri Lelli,
	Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On 08-05-18, 22:54, Rafael J. Wysocki wrote:
> On Tue, May 8, 2018 at 8:42 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
> > occasions:
> > - In sugov_start(), when the schedutil governor is started for a group
> >   of CPUs.
> > - And whenever we need to force a freq update before rate-limit
> >   duration, which happens when:
> >   - there is an update in cpufreq policy limits.
> >   - Or when the utilization of DL scheduling class increases.
> >
> > In return, get_next_freq() doesn't return a cached next_freq value but
> > instead recalculates the next frequency. This has some side effects
> > though and may significantly delay a required increase in frequency.
> >
> > In sugov_update_single() we try to avoid decreasing frequency if the CPU
> > has not been idle recently. Consider this scenario, the available range
> > of frequencies for a CPU are from 800 MHz to 2.5 GHz and current
> > frequency is 800 MHz. From one of the call paths
> > sg_policy->need_freq_update is set to true and hence
> > sg_policy->next_freq is set to UINT_MAX. Now if the CPU had been busy,
> > next_f will always be less than UINT_MAX, whatever the value of next_f
> > is. And so even when we wanted to increase the frequency, we will
> > overwrite next_f with UINT_MAX and will not change the frequency
> > eventually. This will continue until the time CPU stays busy. This isn't
> > cross checked with any specific test cases, but rather based on general
> > code review.
> >
> > Fix that by not resetting the sg_policy->need_freq_update flag from
> > sugov_should_update_freq() but get_next_freq() and we wouldn't need to
> > overwrite sg_policy->next_freq anymore.
> >
> > Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
> > Fixes: b7eaf1aab9f8 ("cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely")
> 
> The rest of the chantelog is totally disconnected from this commit.

I added the "Fixes" tag because this is exactly the commit after which
this problem started, isn't it?

> So the problem is that sugov_update_single() doesn't check the special
> UNIT_MAX value before assigning sg_policy->next_freq to next_f.  Fair
> enough.
> 
> I don't see why the patch is the right fix for that, however.

I thought not overwriting next_freq makes things much simpler and easy
to review. What else do you have in mind to solve this problem ?

-- 
viresh

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  8:41   ` Viresh Kumar
@ 2018-05-09  8:56     ` Rafael J. Wysocki
  2018-05-09  9:15       ` Viresh Kumar
  0 siblings, 1 reply; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-09  8:56 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Rafael Wysocki, Ingo Molnar, Peter Zijlstra,
	Linux PM, Vincent Guittot, Claudio Scordino, Patrick Bellasi,
	Juri Lelli, Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On Wed, May 9, 2018 at 10:41 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 08-05-18, 22:54, Rafael J. Wysocki wrote:
>> On Tue, May 8, 2018 at 8:42 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> > The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
>> > occasions:
>> > - In sugov_start(), when the schedutil governor is started for a group
>> >   of CPUs.
>> > - And whenever we need to force a freq update before rate-limit
>> >   duration, which happens when:
>> >   - there is an update in cpufreq policy limits.
>> >   - Or when the utilization of DL scheduling class increases.
>> >
>> > In return, get_next_freq() doesn't return a cached next_freq value but
>> > instead recalculates the next frequency. This has some side effects
>> > though and may significantly delay a required increase in frequency.
>> >
>> > In sugov_update_single() we try to avoid decreasing frequency if the CPU
>> > has not been idle recently. Consider this scenario, the available range
>> > of frequencies for a CPU are from 800 MHz to 2.5 GHz and current
>> > frequency is 800 MHz. From one of the call paths
>> > sg_policy->need_freq_update is set to true and hence
>> > sg_policy->next_freq is set to UINT_MAX. Now if the CPU had been busy,
>> > next_f will always be less than UINT_MAX, whatever the value of next_f
>> > is. And so even when we wanted to increase the frequency, we will
>> > overwrite next_f with UINT_MAX and will not change the frequency
>> > eventually. This will continue until the time CPU stays busy. This isn't
>> > cross checked with any specific test cases, but rather based on general
>> > code review.
>> >
>> > Fix that by not resetting the sg_policy->need_freq_update flag from
>> > sugov_should_update_freq() but get_next_freq() and we wouldn't need to
>> > overwrite sg_policy->next_freq anymore.
>> >
>> > Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
>> > Fixes: b7eaf1aab9f8 ("cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely")
>>
>> The rest of the chantelog is totally disconnected from this commit.
>
> I added the "Fixes" tag because this is exactly the commit after which
> this problem started, isn't it?
>
>> So the problem is that sugov_update_single() doesn't check the special
>> UNIT_MAX value before assigning sg_policy->next_freq to next_f.  Fair
>> enough.
>>
>> I don't see why the patch is the right fix for that, however.
>
> I thought not overwriting next_freq makes things much simpler and easy
> to review.

I'm kind of concerned about updating the limits via sysfs in which
case the cached next frequency may be out of range, so it's better to
invalidate it right away then.

> What else do you have in mind to solve this problem ?

Something like the below?

---
 kernel/sched/cpufreq_schedutil.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Index: linux-pm/kernel/sched/cpufreq_schedutil.c
===================================================================
--- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
+++ linux-pm/kernel/sched/cpufreq_schedutil.c
@@ -305,7 +305,8 @@ static void sugov_update_single(struct u
      * Do not reduce the frequency if the CPU has not been idle
      * recently, as the reduction is likely to be premature then.
      */
-    if (busy && next_f < sg_policy->next_freq) {
+    if (busy && next_f < sg_policy->next_freq &&
+        sg_policy->next_freq != UINT_MAX) {
         next_f = sg_policy->next_freq;

         /* Reset cached freq as next_freq has changed */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  8:56     ` Rafael J. Wysocki
@ 2018-05-09  9:15       ` Viresh Kumar
  2018-05-09  9:23         ` Rafael J. Wysocki
  0 siblings, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2018-05-09  9:15 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael Wysocki, Ingo Molnar, Peter Zijlstra, Linux PM,
	Vincent Guittot, Claudio Scordino, Patrick Bellasi, Juri Lelli,
	Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On 09-05-18, 10:56, Rafael J. Wysocki wrote:
> I'm kind of concerned about updating the limits via sysfs in which
> case the cached next frequency may be out of range, so it's better to
> invalidate it right away then.

That should not be a problem as __cpufreq_driver_target() will anyway
clamp the target frequency to be within limits, whatever the cached
value of next_freq is.

And we aren't invalidating the cached next freq immediately currently
as well, as we are waiting until the next time the util update handler
is called to set sg_policy->next_freq to UINT_MAX.

> > What else do you have in mind to solve this problem ?
> 
> Something like the below?
> 
> ---
>  kernel/sched/cpufreq_schedutil.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
> @@ -305,7 +305,8 @@ static void sugov_update_single(struct u
>       * Do not reduce the frequency if the CPU has not been idle
>       * recently, as the reduction is likely to be premature then.
>       */
> -    if (busy && next_f < sg_policy->next_freq) {
> +    if (busy && next_f < sg_policy->next_freq &&
> +        sg_policy->next_freq != UINT_MAX) {
>          next_f = sg_policy->next_freq;
> 
>          /* Reset cached freq as next_freq has changed */

This will fix the problem we have identified currently, but adding a
special meaning to next_freq == UINT_MAX invites more hidden corner
cases like the one we just found. IMHO, using next_freq only for the
*real* frequency values makes its usage more transparent and readable.
And we already have the need_freq_update flag which we can use for
this special purpose, as is done in my patch.

-- 
viresh

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  9:15       ` Viresh Kumar
@ 2018-05-09  9:23         ` Rafael J. Wysocki
  2018-05-09  9:30           ` Viresh Kumar
  0 siblings, 1 reply; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-09  9:23 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Rafael Wysocki, Ingo Molnar, Peter Zijlstra,
	Linux PM, Vincent Guittot, Claudio Scordino, Patrick Bellasi,
	Juri Lelli, Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On Wed, May 9, 2018 at 11:15 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 09-05-18, 10:56, Rafael J. Wysocki wrote:
>> I'm kind of concerned about updating the limits via sysfs in which
>> case the cached next frequency may be out of range, so it's better to
>> invalidate it right away then.
>
> That should not be a problem as __cpufreq_driver_target() will anyway
> clamp the target frequency to be within limits, whatever the cached
> value of next_freq is.

The fast switch case doesn't use it, though.

> And we aren't invalidating the cached next freq immediately currently
> as well, as we are waiting until the next time the util update handler
> is called to set sg_policy->next_freq to UINT_MAX.
>
>> > What else do you have in mind to solve this problem ?
>>
>> Something like the below?
>>
>> ---
>>  kernel/sched/cpufreq_schedutil.c |    3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
>> ===================================================================
>> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
>> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
>> @@ -305,7 +305,8 @@ static void sugov_update_single(struct u
>>       * Do not reduce the frequency if the CPU has not been idle
>>       * recently, as the reduction is likely to be premature then.
>>       */
>> -    if (busy && next_f < sg_policy->next_freq) {
>> +    if (busy && next_f < sg_policy->next_freq &&
>> +        sg_policy->next_freq != UINT_MAX) {
>>          next_f = sg_policy->next_freq;
>>
>>          /* Reset cached freq as next_freq has changed */
>
> This will fix the problem we have identified currently, but adding a
> special meaning to next_freq == UINT_MAX invites more hidden corner
> cases like the one we just found. IMHO, using next_freq only for the
> *real* frequency values makes its usage more transparent and readable.
> And we already have the need_freq_update flag which we can use for
> this special purpose, as is done in my patch.

So I prefer to do the above as a -stable fix and make the UNIT_MAX
change on top of that.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  9:23         ` Rafael J. Wysocki
@ 2018-05-09  9:30           ` Viresh Kumar
  2018-05-09  9:32             ` Rafael J. Wysocki
  0 siblings, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2018-05-09  9:30 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Rafael Wysocki, Ingo Molnar, Peter Zijlstra, Linux PM,
	Vincent Guittot, Claudio Scordino, Patrick Bellasi, Juri Lelli,
	Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On 09-05-18, 11:23, Rafael J. Wysocki wrote:
> On Wed, May 9, 2018 at 11:15 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> > On 09-05-18, 10:56, Rafael J. Wysocki wrote:
> >> I'm kind of concerned about updating the limits via sysfs in which
> >> case the cached next frequency may be out of range, so it's better to
> >> invalidate it right away then.
> >
> > That should not be a problem as __cpufreq_driver_target() will anyway
> > clamp the target frequency to be within limits, whatever the cached
> > value of next_freq is.
> 
> The fast switch case doesn't use it, though.

cpufreq_driver_fast_switch() does the same clamping :)

> > And we aren't invalidating the cached next freq immediately currently
> > as well, as we are waiting until the next time the util update handler
> > is called to set sg_policy->next_freq to UINT_MAX.
> >
> >> > What else do you have in mind to solve this problem ?
> >>
> >> Something like the below?
> >>
> >> ---
> >>  kernel/sched/cpufreq_schedutil.c |    3 ++-
> >>  1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
> >> ===================================================================
> >> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
> >> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
> >> @@ -305,7 +305,8 @@ static void sugov_update_single(struct u
> >>       * Do not reduce the frequency if the CPU has not been idle
> >>       * recently, as the reduction is likely to be premature then.
> >>       */
> >> -    if (busy && next_f < sg_policy->next_freq) {
> >> +    if (busy && next_f < sg_policy->next_freq &&
> >> +        sg_policy->next_freq != UINT_MAX) {
> >>          next_f = sg_policy->next_freq;
> >>
> >>          /* Reset cached freq as next_freq has changed */
> >
> > This will fix the problem we have identified currently, but adding a
> > special meaning to next_freq == UINT_MAX invites more hidden corner
> > cases like the one we just found. IMHO, using next_freq only for the
> > *real* frequency values makes its usage more transparent and readable.
> > And we already have the need_freq_update flag which we can use for
> > this special purpose, as is done in my patch.
> 
> So I prefer to do the above as a -stable fix and make the UNIT_MAX
> change on top of that.

Okay, that's fine with me. Will send the next version now :)

Just to make sure, you are fine with the "Fixes" tag now (since you
objected to that earlier) ?

-- 
viresh

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  9:30           ` Viresh Kumar
@ 2018-05-09  9:32             ` Rafael J. Wysocki
  0 siblings, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-09  9:32 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael J. Wysocki, Rafael Wysocki, Ingo Molnar, Peter Zijlstra,
	Linux PM, Vincent Guittot, Claudio Scordino, Patrick Bellasi,
	Juri Lelli, Joel Fernandes, 4 . 12+,
	Linux Kernel Mailing List

On Wed, May 9, 2018 at 11:30 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
> On 09-05-18, 11:23, Rafael J. Wysocki wrote:
>> On Wed, May 9, 2018 at 11:15 AM, Viresh Kumar <viresh.kumar@linaro.org> wrote:
>> > On 09-05-18, 10:56, Rafael J. Wysocki wrote:
>> >> I'm kind of concerned about updating the limits via sysfs in which
>> >> case the cached next frequency may be out of range, so it's better to
>> >> invalidate it right away then.
>> >
>> > That should not be a problem as __cpufreq_driver_target() will anyway
>> > clamp the target frequency to be within limits, whatever the cached
>> > value of next_freq is.
>>
>> The fast switch case doesn't use it, though.
>
> cpufreq_driver_fast_switch() does the same clamping :)
>
>> > And we aren't invalidating the cached next freq immediately currently
>> > as well, as we are waiting until the next time the util update handler
>> > is called to set sg_policy->next_freq to UINT_MAX.
>> >
>> >> > What else do you have in mind to solve this problem ?
>> >>
>> >> Something like the below?
>> >>
>> >> ---
>> >>  kernel/sched/cpufreq_schedutil.c |    3 ++-
>> >>  1 file changed, 2 insertions(+), 1 deletion(-)
>> >>
>> >> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
>> >> ===================================================================
>> >> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
>> >> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
>> >> @@ -305,7 +305,8 @@ static void sugov_update_single(struct u
>> >>       * Do not reduce the frequency if the CPU has not been idle
>> >>       * recently, as the reduction is likely to be premature then.
>> >>       */
>> >> -    if (busy && next_f < sg_policy->next_freq) {
>> >> +    if (busy && next_f < sg_policy->next_freq &&
>> >> +        sg_policy->next_freq != UINT_MAX) {
>> >>          next_f = sg_policy->next_freq;
>> >>
>> >>          /* Reset cached freq as next_freq has changed */
>> >
>> > This will fix the problem we have identified currently, but adding a
>> > special meaning to next_freq == UINT_MAX invites more hidden corner
>> > cases like the one we just found. IMHO, using next_freq only for the
>> > *real* frequency values makes its usage more transparent and readable.
>> > And we already have the need_freq_update flag which we can use for
>> > this special purpose, as is done in my patch.
>>
>> So I prefer to do the above as a -stable fix and make the UNIT_MAX
>> change on top of that.
>
> Okay, that's fine with me. Will send the next version now :)
>
> Just to make sure, you are fine with the "Fixes" tag now (since you
> objected to that earlier) ?

OK, so to be clear, I'm going to queue up the simple patch I posted
with a FIxes: tag.  I'll resend it with a changelog shortly.

Then please send a UINT_MAX change on top of that and it won't be an
urgent fix any more.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] cpufreq: schedutil: Avoid using invalid next_freq
  2018-05-08  6:42 [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
  2018-05-08 20:54 ` Rafael J. Wysocki
@ 2018-05-09  9:44 ` Rafael J. Wysocki
  2018-05-09  9:46   ` Viresh Kumar
  2018-05-09 10:35   ` [PATCH V2] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
  1 sibling, 2 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-09  9:44 UTC (permalink / raw)
  To: linux-pm
  Cc: Viresh Kumar, Ingo Molnar, Peter Zijlstra, Vincent Guittot,
	claudio, patrick.bellasi, juri.lelli, joelaf, linux-kernel

From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

If the next_freq field of struct sugov_policy is set to UINT_MAX,
it shouldn't be used for updating the CPU frequency (this is a
special "invalid" value), but after commit b7eaf1aab9f8 (cpufreq:
schedutil: Avoid reducing frequency of busy CPUs prematurely) it
may be passed as the new frequency to sugov_update_commit() in
sugov_update_single().

Fix that by adding an extra check for the special UINT_MAX value
of next_freq to sugov_update_single().

Fixes: b7eaf1aab9f8 (cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely)
Reported-by: Viresh Kumar <viresh.kumar@linaro.org>
Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 kernel/sched/cpufreq_schedutil.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Index: linux-pm/kernel/sched/cpufreq_schedutil.c
===================================================================
--- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
+++ linux-pm/kernel/sched/cpufreq_schedutil.c
@@ -305,7 +305,8 @@ static void sugov_update_single(struct u
 	 * Do not reduce the frequency if the CPU has not been idle
 	 * recently, as the reduction is likely to be premature then.
 	 */
-	if (busy && next_f < sg_policy->next_freq) {
+	if (busy && next_f < sg_policy->next_freq &&
+	    sg_policy->next_freq != UINT_MAX) {
 		next_f = sg_policy->next_freq;
 
 		/* Reset cached freq as next_freq has changed */

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] cpufreq: schedutil: Avoid using invalid next_freq
  2018-05-09  9:44 ` [PATCH] cpufreq: schedutil: Avoid using invalid next_freq Rafael J. Wysocki
@ 2018-05-09  9:46   ` Viresh Kumar
  2018-05-09 10:35   ` [PATCH V2] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
  1 sibling, 0 replies; 13+ messages in thread
From: Viresh Kumar @ 2018-05-09  9:46 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: linux-pm, Ingo Molnar, Peter Zijlstra, Vincent Guittot, claudio,
	patrick.bellasi, juri.lelli, joelaf, linux-kernel

On 09-05-18, 11:44, Rafael J. Wysocki wrote:
> From: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> 
> If the next_freq field of struct sugov_policy is set to UINT_MAX,
> it shouldn't be used for updating the CPU frequency (this is a
> special "invalid" value), but after commit b7eaf1aab9f8 (cpufreq:
> schedutil: Avoid reducing frequency of busy CPUs prematurely) it
> may be passed as the new frequency to sugov_update_commit() in
> sugov_update_single().
> 
> Fix that by adding an extra check for the special UINT_MAX value
> of next_freq to sugov_update_single().
> 
> Fixes: b7eaf1aab9f8 (cpufreq: schedutil: Avoid reducing frequency of busy CPUs prematurely)
> Reported-by: Viresh Kumar <viresh.kumar@linaro.org>
> Cc: 4.12+ <stable@vger.kernel.org> # 4.12+
> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
> ---
>  kernel/sched/cpufreq_schedutil.c |    3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> Index: linux-pm/kernel/sched/cpufreq_schedutil.c
> ===================================================================
> --- linux-pm.orig/kernel/sched/cpufreq_schedutil.c
> +++ linux-pm/kernel/sched/cpufreq_schedutil.c
> @@ -305,7 +305,8 @@ static void sugov_update_single(struct u
>  	 * Do not reduce the frequency if the CPU has not been idle
>  	 * recently, as the reduction is likely to be premature then.
>  	 */
> -	if (busy && next_f < sg_policy->next_freq) {
> +	if (busy && next_f < sg_policy->next_freq &&
> +	    sg_policy->next_freq != UINT_MAX) {
>  		next_f = sg_policy->next_freq;
>  
>  		/* Reset cached freq as next_freq has changed */

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

-- 
viresh

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH V2] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09  9:44 ` [PATCH] cpufreq: schedutil: Avoid using invalid next_freq Rafael J. Wysocki
  2018-05-09  9:46   ` Viresh Kumar
@ 2018-05-09 10:35   ` Viresh Kumar
  2018-05-11 20:47     ` [V2] " Joel Fernandes
  1 sibling, 1 reply; 13+ messages in thread
From: Viresh Kumar @ 2018-05-09 10:35 UTC (permalink / raw)
  To: Rafael Wysocki, Ingo Molnar, Peter Zijlstra
  Cc: Viresh Kumar, linux-pm, Vincent Guittot, linux-kernel

The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
occasions to discard the cached value of next freq:
- In sugov_start(), when the schedutil governor is started for a group
  of CPUs.
- And whenever we need to force a freq update before rate-limit
  duration, which happens when:
  - there is an update in cpufreq policy limits.
  - Or when the utilization of DL scheduling class increases.

In return, get_next_freq() doesn't return a cached next_freq value but
recalculates the next frequency instead.

But having special meaning for a particular value of frequency makes the
code less readable and error prone. We recently fixed a bug where the
UINT_MAX value was considered as valid frequency in
sugov_update_single().

All we need is a flag which can be used to discard the value of
sg_policy->next_freq and we already have need_freq_update for that. Lets
reuse it instead of setting next_freq to UINT_MAX.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
---
V2:
- Rebased over the fix sent by Rafael

  lkml.kernel.org/r/2276196.ev9rMjHTR0@aspire.rjw.lan

- Remove the additional check from sugov_update_single() as well.
- This is for 4.18 now instead of stable kernels.

 kernel/sched/cpufreq_schedutil.c | 18 ++++++------------
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index e23e84724f39..daaca23697dc 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -95,15 +95,8 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
 	if (sg_policy->work_in_progress)
 		return false;
 
-	if (unlikely(sg_policy->need_freq_update)) {
-		sg_policy->need_freq_update = false;
-		/*
-		 * This happens when limits change, so forget the previous
-		 * next_freq value and force an update.
-		 */
-		sg_policy->next_freq = UINT_MAX;
+	if (unlikely(sg_policy->need_freq_update))
 		return true;
-	}
 
 	delta_ns = time - sg_policy->last_freq_update_time;
 
@@ -165,8 +158,10 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
 
 	freq = (freq + (freq >> 2)) * util / max;
 
-	if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX)
+	if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update)
 		return sg_policy->next_freq;
+
+	sg_policy->need_freq_update = false;
 	sg_policy->cached_raw_freq = freq;
 	return cpufreq_driver_resolve_freq(policy, freq);
 }
@@ -305,8 +300,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
 	 * Do not reduce the frequency if the CPU has not been idle
 	 * recently, as the reduction is likely to be premature then.
 	 */
-	if (busy && next_f < sg_policy->next_freq &&
-	    sg_policy->next_freq != UINT_MAX) {
+	if (busy && next_f < sg_policy->next_freq) {
 		next_f = sg_policy->next_freq;
 
 		/* Reset cached freq as next_freq has changed */
@@ -671,7 +665,7 @@ static int sugov_start(struct cpufreq_policy *policy)
 
 	sg_policy->freq_update_delay_ns	= sg_policy->tunables->rate_limit_us * NSEC_PER_USEC;
 	sg_policy->last_freq_update_time	= 0;
-	sg_policy->next_freq			= UINT_MAX;
+	sg_policy->next_freq			= 0;
 	sg_policy->work_in_progress		= false;
 	sg_policy->need_freq_update		= false;
 	sg_policy->cached_raw_freq		= 0;
-- 
2.15.0.194.g9af6a3dea062

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [V2] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-09 10:35   ` [PATCH V2] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
@ 2018-05-11 20:47     ` Joel Fernandes
  2018-05-17 10:33       ` Rafael J. Wysocki
  0 siblings, 1 reply; 13+ messages in thread
From: Joel Fernandes @ 2018-05-11 20:47 UTC (permalink / raw)
  To: Viresh Kumar
  Cc: Rafael Wysocki, Ingo Molnar, Peter Zijlstra, linux-pm,
	Vincent Guittot, linux-kernel

On Wed, May 09, 2018 at 04:05:24PM +0530, Viresh Kumar wrote:
> The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
> occasions to discard the cached value of next freq:
> - In sugov_start(), when the schedutil governor is started for a group
>   of CPUs.
> - And whenever we need to force a freq update before rate-limit
>   duration, which happens when:
>   - there is an update in cpufreq policy limits.
>   - Or when the utilization of DL scheduling class increases.
> 
> In return, get_next_freq() doesn't return a cached next_freq value but
> recalculates the next frequency instead.
> 
> But having special meaning for a particular value of frequency makes the
> code less readable and error prone. We recently fixed a bug where the
> UINT_MAX value was considered as valid frequency in
> sugov_update_single().
> 
> All we need is a flag which can be used to discard the value of
> sg_policy->next_freq and we already have need_freq_update for that. Lets
> reuse it instead of setting next_freq to UINT_MAX.
> 
> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> ---
> V2:
> - Rebased over the fix sent by Rafael
> 
>   lkml.kernel.org/r/2276196.ev9rMjHTR0@aspire.rjw.lan
> 
> - Remove the additional check from sugov_update_single() as well.
> - This is for 4.18 now instead of stable kernels.

Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>

(please note my email address change as well in your contact/address-book).

thanks,

- Joel


> 
>  kernel/sched/cpufreq_schedutil.c | 18 ++++++------------
>  1 file changed, 6 insertions(+), 12 deletions(-)
> 
> diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
> index e23e84724f39..daaca23697dc 100644
> --- a/kernel/sched/cpufreq_schedutil.c
> +++ b/kernel/sched/cpufreq_schedutil.c
> @@ -95,15 +95,8 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time)
>  	if (sg_policy->work_in_progress)
>  		return false;
>  
> -	if (unlikely(sg_policy->need_freq_update)) {
> -		sg_policy->need_freq_update = false;
> -		/*
> -		 * This happens when limits change, so forget the previous
> -		 * next_freq value and force an update.
> -		 */
> -		sg_policy->next_freq = UINT_MAX;
> +	if (unlikely(sg_policy->need_freq_update))
>  		return true;
> -	}
>  
>  	delta_ns = time - sg_policy->last_freq_update_time;
>  
> @@ -165,8 +158,10 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy,
>  
>  	freq = (freq + (freq >> 2)) * util / max;
>  
> -	if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX)
> +	if (freq == sg_policy->cached_raw_freq && !sg_policy->need_freq_update)
>  		return sg_policy->next_freq;
> +
> +	sg_policy->need_freq_update = false;
>  	sg_policy->cached_raw_freq = freq;
>  	return cpufreq_driver_resolve_freq(policy, freq);
>  }
> @@ -305,8 +300,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
>  	 * Do not reduce the frequency if the CPU has not been idle
>  	 * recently, as the reduction is likely to be premature then.
>  	 */
> -	if (busy && next_f < sg_policy->next_freq &&
> -	    sg_policy->next_freq != UINT_MAX) {
> +	if (busy && next_f < sg_policy->next_freq) {
>  		next_f = sg_policy->next_freq;
>  
>  		/* Reset cached freq as next_freq has changed */
> @@ -671,7 +665,7 @@ static int sugov_start(struct cpufreq_policy *policy)
>  
>  	sg_policy->freq_update_delay_ns	= sg_policy->tunables->rate_limit_us * NSEC_PER_USEC;
>  	sg_policy->last_freq_update_time	= 0;
> -	sg_policy->next_freq			= UINT_MAX;
> +	sg_policy->next_freq			= 0;
>  	sg_policy->work_in_progress		= false;
>  	sg_policy->need_freq_update		= false;
>  	sg_policy->cached_raw_freq		= 0;

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [V2] sched/schedutil: Don't set next_freq to UINT_MAX
  2018-05-11 20:47     ` [V2] " Joel Fernandes
@ 2018-05-17 10:33       ` Rafael J. Wysocki
  0 siblings, 0 replies; 13+ messages in thread
From: Rafael J. Wysocki @ 2018-05-17 10:33 UTC (permalink / raw)
  To: Joel Fernandes, Viresh Kumar
  Cc: Ingo Molnar, Peter Zijlstra, linux-pm, Vincent Guittot, linux-kernel

On Friday, May 11, 2018 10:47:12 PM CEST Joel Fernandes wrote:
> On Wed, May 09, 2018 at 04:05:24PM +0530, Viresh Kumar wrote:
> > The schedutil driver sets sg_policy->next_freq to UINT_MAX on certain
> > occasions to discard the cached value of next freq:
> > - In sugov_start(), when the schedutil governor is started for a group
> >   of CPUs.
> > - And whenever we need to force a freq update before rate-limit
> >   duration, which happens when:
> >   - there is an update in cpufreq policy limits.
> >   - Or when the utilization of DL scheduling class increases.
> > 
> > In return, get_next_freq() doesn't return a cached next_freq value but
> > recalculates the next frequency instead.
> > 
> > But having special meaning for a particular value of frequency makes the
> > code less readable and error prone. We recently fixed a bug where the
> > UINT_MAX value was considered as valid frequency in
> > sugov_update_single().
> > 
> > All we need is a flag which can be used to discard the value of
> > sg_policy->next_freq and we already have need_freq_update for that. Lets
> > reuse it instead of setting next_freq to UINT_MAX.
> > 
> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
> > ---
> > V2:
> > - Rebased over the fix sent by Rafael
> > 
> >   lkml.kernel.org/r/2276196.ev9rMjHTR0@aspire.rjw.lan
> > 
> > - Remove the additional check from sugov_update_single() as well.
> > - This is for 4.18 now instead of stable kernels.
> 
> Reviewed-by: Joel Fernandes (Google) <joel@joelfernandes.org>

Applied, thanks!

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2018-05-17 10:34 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-08  6:42 [PATCH] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
2018-05-08 20:54 ` Rafael J. Wysocki
2018-05-09  8:41   ` Viresh Kumar
2018-05-09  8:56     ` Rafael J. Wysocki
2018-05-09  9:15       ` Viresh Kumar
2018-05-09  9:23         ` Rafael J. Wysocki
2018-05-09  9:30           ` Viresh Kumar
2018-05-09  9:32             ` Rafael J. Wysocki
2018-05-09  9:44 ` [PATCH] cpufreq: schedutil: Avoid using invalid next_freq Rafael J. Wysocki
2018-05-09  9:46   ` Viresh Kumar
2018-05-09 10:35   ` [PATCH V2] sched/schedutil: Don't set next_freq to UINT_MAX Viresh Kumar
2018-05-11 20:47     ` [V2] " Joel Fernandes
2018-05-17 10:33       ` Rafael J. Wysocki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.