Re: [PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-12 Thread Dan Carpenter
Hi Rafael,

I love your patch! Perhaps something to improve:

url:
https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/cpuidle-menu-Handle-stopped-tick-more-aggressively/20180811-191914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next

smatch warnings:
drivers/cpuidle/governors/menu.c:374 menu_select() error: uninitialized symbol 
'first_idx'.

# 
https://github.com/0day-ci/linux/commit/5f9f09809ebd1b4f7820c9925a0cbd417bd3a823
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 5f9f09809ebd1b4f7820c9925a0cbd417bd3a823
vim +/first_idx +374 drivers/cpuidle/governors/menu.c

1f85f87d4 Arjan van de Ven  2010-05-24  276  
4f86d3a8e Len Brown 2007-10-03  277  /**
4f86d3a8e Len Brown 2007-10-03  278   * menu_select - 
selects the next idle state to enter
46bcfad7a Deepthi Dharwar   2011-10-28  279   * @drv: cpuidle 
driver containing state data
4f86d3a8e Len Brown 2007-10-03  280   * @dev: the CPU
45f1ff59e Rafael J. Wysocki 2018-03-22  281   * @stop_tick: 
indication on whether or not to stop the tick
4f86d3a8e Len Brown 2007-10-03  282   */
45f1ff59e Rafael J. Wysocki 2018-03-22  283  static int 
menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
45f1ff59e Rafael J. Wysocki 2018-03-22  284
bool *stop_tick)
4f86d3a8e Len Brown 2007-10-03  285  {
229b6863b Christoph Lameter 2014-08-17  286 struct 
menu_device *data = this_cpu_ptr(_devices);
0fc784fb0 Rafael J. Wysocki 2018-05-30  287 int latency_req 
= cpuidle_governor_latency_req(dev->cpu);
4f86d3a8e Len Brown 2007-10-03  288 int i;
3ed09c945 Nicholas Piggin   2017-06-26  289 int first_idx;
3ed09c945 Nicholas Piggin   2017-06-26  290 int idx;
96e95182e tuukka.tikka...@linaro.org2014-02-24  291 unsigned int 
interactivity_req;
e132b9b3b Rik van Riel  2016-03-16  292 unsigned int 
expected_interval;
372ba8cb4 Mel Gorman2014-08-06  293 unsigned long 
nr_iowaiters, cpu_load;
296bb1e51 Rafael J. Wysocki 2018-04-05  294 ktime_t 
delta_next;
4f86d3a8e Len Brown 2007-10-03  295  
672917dcc Corrado Zoccolo   2009-09-21  296 if 
(data->needs_update) {
46bcfad7a Deepthi Dharwar   2011-10-28  297 
menu_update(drv, dev);
672917dcc Corrado Zoccolo   2009-09-21  298 
data->needs_update = 0;
672917dcc Corrado Zoccolo   2009-09-21  299 }
672917dcc Corrado Zoccolo   2009-09-21  300  
69d25870f Arjan van de Ven  2009-09-21  301 /* Special case 
when user has set very strict latency requirement */
45f1ff59e Rafael J. Wysocki 2018-03-22  302 if 
(unlikely(latency_req == 0)) {
45f1ff59e Rafael J. Wysocki 2018-03-22  303 
*stop_tick = false;
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  304 return 
0;
45f1ff59e Rafael J. Wysocki 2018-03-22  305 }
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  306  
69d25870f Arjan van de Ven  2009-09-21  307 /* determine 
the expected residency time, round up */
296bb1e51 Rafael J. Wysocki 2018-04-05  308 
data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(_next));
69d25870f Arjan van de Ven  2009-09-21  309  
5f9f09809 Rafael J. Wysocki 2018-08-10  310 /*
5f9f09809 Rafael J. Wysocki 2018-08-10  311  * If the tick 
is already stopped, the cost of possible short idle
5f9f09809 Rafael J. Wysocki 2018-08-10  312  * duration 
misprediction is much higher, because the CPU may be stuck
5f9f09809 Rafael J. Wysocki 2018-08-10  313  * in a shallow 
idle state for a long time as a result of it.  In that
5f9f09809 Rafael J. Wysocki 2018-08-10  314  * case say we 
might mispredict and use the known time till the closest
5f9f09809 Rafael J. Wysocki 2018-08-10  315  * timer event 
for the idle state selection.
5f9f09809 Rafael J. Wysocki 2018-08-10  316  */
5f9f09809 Rafael J. Wysocki 2018-08-10  317 if 
(tick_nohz_tick_stopped()) {
5f9f09809 Rafael J. Wysocki 2018-08-10  318 
data->predicted_us = ktime_to_us(delta_next);
5f9f09809 Rafael J. Wysocki 2018-08-10  319 goto 
select;

^^^
We hit this goto

5f9f09809 Rafael J. Wysocki 2018-08-10  320 }
5f9f09809 Rafael J. 

Re: [PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-12 Thread Dan Carpenter
Hi Rafael,

I love your patch! Perhaps something to improve:

url:
https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/cpuidle-menu-Handle-stopped-tick-more-aggressively/20180811-191914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next

smatch warnings:
drivers/cpuidle/governors/menu.c:374 menu_select() error: uninitialized symbol 
'first_idx'.

# 
https://github.com/0day-ci/linux/commit/5f9f09809ebd1b4f7820c9925a0cbd417bd3a823
git remote add linux-review https://github.com/0day-ci/linux
git remote update linux-review
git checkout 5f9f09809ebd1b4f7820c9925a0cbd417bd3a823
vim +/first_idx +374 drivers/cpuidle/governors/menu.c

1f85f87d4 Arjan van de Ven  2010-05-24  276  
4f86d3a8e Len Brown 2007-10-03  277  /**
4f86d3a8e Len Brown 2007-10-03  278   * menu_select - 
selects the next idle state to enter
46bcfad7a Deepthi Dharwar   2011-10-28  279   * @drv: cpuidle 
driver containing state data
4f86d3a8e Len Brown 2007-10-03  280   * @dev: the CPU
45f1ff59e Rafael J. Wysocki 2018-03-22  281   * @stop_tick: 
indication on whether or not to stop the tick
4f86d3a8e Len Brown 2007-10-03  282   */
45f1ff59e Rafael J. Wysocki 2018-03-22  283  static int 
menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
45f1ff59e Rafael J. Wysocki 2018-03-22  284
bool *stop_tick)
4f86d3a8e Len Brown 2007-10-03  285  {
229b6863b Christoph Lameter 2014-08-17  286 struct 
menu_device *data = this_cpu_ptr(_devices);
0fc784fb0 Rafael J. Wysocki 2018-05-30  287 int latency_req 
= cpuidle_governor_latency_req(dev->cpu);
4f86d3a8e Len Brown 2007-10-03  288 int i;
3ed09c945 Nicholas Piggin   2017-06-26  289 int first_idx;
3ed09c945 Nicholas Piggin   2017-06-26  290 int idx;
96e95182e tuukka.tikka...@linaro.org2014-02-24  291 unsigned int 
interactivity_req;
e132b9b3b Rik van Riel  2016-03-16  292 unsigned int 
expected_interval;
372ba8cb4 Mel Gorman2014-08-06  293 unsigned long 
nr_iowaiters, cpu_load;
296bb1e51 Rafael J. Wysocki 2018-04-05  294 ktime_t 
delta_next;
4f86d3a8e Len Brown 2007-10-03  295  
672917dcc Corrado Zoccolo   2009-09-21  296 if 
(data->needs_update) {
46bcfad7a Deepthi Dharwar   2011-10-28  297 
menu_update(drv, dev);
672917dcc Corrado Zoccolo   2009-09-21  298 
data->needs_update = 0;
672917dcc Corrado Zoccolo   2009-09-21  299 }
672917dcc Corrado Zoccolo   2009-09-21  300  
69d25870f Arjan van de Ven  2009-09-21  301 /* Special case 
when user has set very strict latency requirement */
45f1ff59e Rafael J. Wysocki 2018-03-22  302 if 
(unlikely(latency_req == 0)) {
45f1ff59e Rafael J. Wysocki 2018-03-22  303 
*stop_tick = false;
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  304 return 
0;
45f1ff59e Rafael J. Wysocki 2018-03-22  305 }
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  306  
69d25870f Arjan van de Ven  2009-09-21  307 /* determine 
the expected residency time, round up */
296bb1e51 Rafael J. Wysocki 2018-04-05  308 
data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(_next));
69d25870f Arjan van de Ven  2009-09-21  309  
5f9f09809 Rafael J. Wysocki 2018-08-10  310 /*
5f9f09809 Rafael J. Wysocki 2018-08-10  311  * If the tick 
is already stopped, the cost of possible short idle
5f9f09809 Rafael J. Wysocki 2018-08-10  312  * duration 
misprediction is much higher, because the CPU may be stuck
5f9f09809 Rafael J. Wysocki 2018-08-10  313  * in a shallow 
idle state for a long time as a result of it.  In that
5f9f09809 Rafael J. Wysocki 2018-08-10  314  * case say we 
might mispredict and use the known time till the closest
5f9f09809 Rafael J. Wysocki 2018-08-10  315  * timer event 
for the idle state selection.
5f9f09809 Rafael J. Wysocki 2018-08-10  316  */
5f9f09809 Rafael J. Wysocki 2018-08-10  317 if 
(tick_nohz_tick_stopped()) {
5f9f09809 Rafael J. Wysocki 2018-08-10  318 
data->predicted_us = ktime_to_us(delta_next);
5f9f09809 Rafael J. Wysocki 2018-08-10  319 goto 
select;

^^^
We hit this goto

5f9f09809 Rafael J. Wysocki 2018-08-10  320 }
5f9f09809 Rafael J. 

Re: [PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-11 Thread kbuild test robot
Hi Rafael,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on v4.18-rc8 next-20180810]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/cpuidle-menu-Handle-stopped-tick-more-aggressively/20180811-191914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=mips 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/cpuidle/governors/menu.c: In function 'menu_select':
>> drivers/cpuidle/governors/menu.c:289:6: warning: 'first_idx' may be used 
>> uninitialized in this function [-Wmaybe-uninitialized]
 int first_idx;
 ^

vim +/first_idx +289 drivers/cpuidle/governors/menu.c

1f85f87d4 Arjan van de Ven  2010-05-24  276  
4f86d3a8e Len Brown 2007-10-03  277  /**
4f86d3a8e Len Brown 2007-10-03  278   * menu_select - 
selects the next idle state to enter
46bcfad7a Deepthi Dharwar   2011-10-28  279   * @drv: cpuidle 
driver containing state data
4f86d3a8e Len Brown 2007-10-03  280   * @dev: the CPU
45f1ff59e Rafael J. Wysocki 2018-03-22  281   * @stop_tick: 
indication on whether or not to stop the tick
4f86d3a8e Len Brown 2007-10-03  282   */
45f1ff59e Rafael J. Wysocki 2018-03-22  283  static int 
menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
45f1ff59e Rafael J. Wysocki 2018-03-22  284
bool *stop_tick)
4f86d3a8e Len Brown 2007-10-03  285  {
229b6863b Christoph Lameter 2014-08-17  286 struct 
menu_device *data = this_cpu_ptr(_devices);
0fc784fb0 Rafael J. Wysocki 2018-05-30  287 int latency_req 
= cpuidle_governor_latency_req(dev->cpu);
4f86d3a8e Len Brown 2007-10-03  288 int i;
3ed09c945 Nicholas Piggin   2017-06-26 @289 int first_idx;
3ed09c945 Nicholas Piggin   2017-06-26  290 int idx;
96e95182e tuukka.tikka...@linaro.org2014-02-24  291 unsigned int 
interactivity_req;
e132b9b3b Rik van Riel  2016-03-16  292 unsigned int 
expected_interval;
372ba8cb4 Mel Gorman2014-08-06  293 unsigned long 
nr_iowaiters, cpu_load;
296bb1e51 Rafael J. Wysocki 2018-04-05  294 ktime_t 
delta_next;
4f86d3a8e Len Brown 2007-10-03  295  
672917dcc Corrado Zoccolo   2009-09-21  296 if 
(data->needs_update) {
46bcfad7a Deepthi Dharwar   2011-10-28  297 
menu_update(drv, dev);
672917dcc Corrado Zoccolo   2009-09-21  298 
data->needs_update = 0;
672917dcc Corrado Zoccolo   2009-09-21  299 }
672917dcc Corrado Zoccolo   2009-09-21  300  
69d25870f Arjan van de Ven  2009-09-21  301 /* Special case 
when user has set very strict latency requirement */
45f1ff59e Rafael J. Wysocki 2018-03-22  302 if 
(unlikely(latency_req == 0)) {
45f1ff59e Rafael J. Wysocki 2018-03-22  303 
*stop_tick = false;
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  304 return 
0;
45f1ff59e Rafael J. Wysocki 2018-03-22  305 }
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  306  
69d25870f Arjan van de Ven  2009-09-21  307 /* determine 
the expected residency time, round up */
296bb1e51 Rafael J. Wysocki 2018-04-05  308 
data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(_next));
69d25870f Arjan van de Ven  2009-09-21  309  
5f9f09809 Rafael J. Wysocki 2018-08-10  310 /*
5f9f09809 Rafael J. Wysocki 2018-08-10  311  * If the tick 
is already stopped, the cost of possible short idle
5f9f09809 Rafael J. Wysocki 2018-08-10  312  * duration 
misprediction is much higher, because the CPU may be stuck
5f9f09809 Rafael J. Wysocki 2018-08-10  313  * in a shallow 
idle state for a long time as a result of it.  In that
5f9f09809 Rafael J. Wysocki 2018-08-10  314  * case say we 
might mispredict and use the known time till the closest
5f9f09809 Rafael J. Wysocki 

Re: [PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-11 Thread kbuild test robot
Hi Rafael,

I love your patch! Perhaps something to improve:

[auto build test WARNING on pm/linux-next]
[also build test WARNING on v4.18-rc8 next-20180810]
[if your patch is applied to the wrong git tree, please drop us a note to help 
improve the system]

url:
https://github.com/0day-ci/linux/commits/Rafael-J-Wysocki/cpuidle-menu-Handle-stopped-tick-more-aggressively/20180811-191914
base:   https://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm.git 
linux-next
config: mips-allyesconfig (attached as .config)
compiler: mips-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
wget 
https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O 
~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.2.0 make.cross ARCH=mips 

Note: it may well be a FALSE warning. FWIW you are at least aware of it now.
http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings

All warnings (new ones prefixed by >>):

   drivers/cpuidle/governors/menu.c: In function 'menu_select':
>> drivers/cpuidle/governors/menu.c:289:6: warning: 'first_idx' may be used 
>> uninitialized in this function [-Wmaybe-uninitialized]
 int first_idx;
 ^

vim +/first_idx +289 drivers/cpuidle/governors/menu.c

1f85f87d4 Arjan van de Ven  2010-05-24  276  
4f86d3a8e Len Brown 2007-10-03  277  /**
4f86d3a8e Len Brown 2007-10-03  278   * menu_select - 
selects the next idle state to enter
46bcfad7a Deepthi Dharwar   2011-10-28  279   * @drv: cpuidle 
driver containing state data
4f86d3a8e Len Brown 2007-10-03  280   * @dev: the CPU
45f1ff59e Rafael J. Wysocki 2018-03-22  281   * @stop_tick: 
indication on whether or not to stop the tick
4f86d3a8e Len Brown 2007-10-03  282   */
45f1ff59e Rafael J. Wysocki 2018-03-22  283  static int 
menu_select(struct cpuidle_driver *drv, struct cpuidle_device *dev,
45f1ff59e Rafael J. Wysocki 2018-03-22  284
bool *stop_tick)
4f86d3a8e Len Brown 2007-10-03  285  {
229b6863b Christoph Lameter 2014-08-17  286 struct 
menu_device *data = this_cpu_ptr(_devices);
0fc784fb0 Rafael J. Wysocki 2018-05-30  287 int latency_req 
= cpuidle_governor_latency_req(dev->cpu);
4f86d3a8e Len Brown 2007-10-03  288 int i;
3ed09c945 Nicholas Piggin   2017-06-26 @289 int first_idx;
3ed09c945 Nicholas Piggin   2017-06-26  290 int idx;
96e95182e tuukka.tikka...@linaro.org2014-02-24  291 unsigned int 
interactivity_req;
e132b9b3b Rik van Riel  2016-03-16  292 unsigned int 
expected_interval;
372ba8cb4 Mel Gorman2014-08-06  293 unsigned long 
nr_iowaiters, cpu_load;
296bb1e51 Rafael J. Wysocki 2018-04-05  294 ktime_t 
delta_next;
4f86d3a8e Len Brown 2007-10-03  295  
672917dcc Corrado Zoccolo   2009-09-21  296 if 
(data->needs_update) {
46bcfad7a Deepthi Dharwar   2011-10-28  297 
menu_update(drv, dev);
672917dcc Corrado Zoccolo   2009-09-21  298 
data->needs_update = 0;
672917dcc Corrado Zoccolo   2009-09-21  299 }
672917dcc Corrado Zoccolo   2009-09-21  300  
69d25870f Arjan van de Ven  2009-09-21  301 /* Special case 
when user has set very strict latency requirement */
45f1ff59e Rafael J. Wysocki 2018-03-22  302 if 
(unlikely(latency_req == 0)) {
45f1ff59e Rafael J. Wysocki 2018-03-22  303 
*stop_tick = false;
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  304 return 
0;
45f1ff59e Rafael J. Wysocki 2018-03-22  305 }
a2bd92023 venkatesh.pallip...@intel.com 2008-07-30  306  
69d25870f Arjan van de Ven  2009-09-21  307 /* determine 
the expected residency time, round up */
296bb1e51 Rafael J. Wysocki 2018-04-05  308 
data->next_timer_us = ktime_to_us(tick_nohz_get_sleep_length(_next));
69d25870f Arjan van de Ven  2009-09-21  309  
5f9f09809 Rafael J. Wysocki 2018-08-10  310 /*
5f9f09809 Rafael J. Wysocki 2018-08-10  311  * If the tick 
is already stopped, the cost of possible short idle
5f9f09809 Rafael J. Wysocki 2018-08-10  312  * duration 
misprediction is much higher, because the CPU may be stuck
5f9f09809 Rafael J. Wysocki 2018-08-10  313  * in a shallow 
idle state for a long time as a result of it.  In that
5f9f09809 Rafael J. Wysocki 2018-08-10  314  * case say we 
might mispredict and use the known time till the closest
5f9f09809 Rafael J. Wysocki 

[PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-10 Thread Rafael J. Wysocki
From: Rafael J. Wysocki 

Commit 87c9fe6ee495 (cpuidle: menu: Avoid selecting shallow states
with stopped tick) missed the case when the target residencies of
deep idle states of CPUs are above the tick boundary which may cause
the CPU to get stuck in a shallow idle state for a long time.

Say there are two CPU idle states available: one shallow, with the
target residency much below the tick boundary and one deep, with
the target residency significantly above the tick boundary.  In
that case, if the tick has been stopped already and the expected
next timer event is relatively far in the future, the governor will
assume the idle duration to be equal to TICK_USEC and it will select
the idle state for the CPU accordingly.  However, that will cause the
shallow state to be selected even though it would have been more
energy-efficient to select the deep one.

To address this issue, modify the governor to always assume idle
duration to be equal to the time till the closest timer event if
the tick is not running which will cause the selected idle states
to always match the known CPU wakeup time.

Also make it always indicate that the tick should be stopped in
that case for consistency.

Fixes: 87c9fe6ee495 (cpuidle: menu: Avoid selecting shallow states with stopped 
tick)
Reported-by: Leo Yan 
Signed-off-by: Rafael J. Wysocki 
---
 drivers/cpuidle/governors/menu.c |   49 ++-
 1 file changed, 23 insertions(+), 26 deletions(-)

Index: linux-pm/drivers/cpuidle/governors/menu.c
===
--- linux-pm.orig/drivers/cpuidle/governors/menu.c
+++ linux-pm/drivers/cpuidle/governors/menu.c
@@ -307,6 +307,18 @@ static int menu_select(struct cpuidle_dr
/* determine the expected residency time, round up */
data->next_timer_us = 
ktime_to_us(tick_nohz_get_sleep_length(_next));
 
+   /*
+* If the tick is already stopped, the cost of possible short idle
+* duration misprediction is much higher, because the CPU may be stuck
+* in a shallow idle state for a long time as a result of it.  In that
+* case say we might mispredict and use the known time till the closest
+* timer event for the idle state selection.
+*/
+   if (tick_nohz_tick_stopped()) {
+   data->predicted_us = ktime_to_us(delta_next);
+   goto select;
+   }
+
get_iowait_load(_iowaiters, _load);
data->bucket = which_bucket(data->next_timer_us, nr_iowaiters);
 
@@ -344,29 +356,15 @@ static int menu_select(struct cpuidle_dr
 */
data->predicted_us = min(data->predicted_us, expected_interval);
 
-   if (tick_nohz_tick_stopped()) {
-   /*
-* If the tick is already stopped, the cost of possible short
-* idle duration misprediction is much higher, because the CPU
-* may be stuck in a shallow idle state for a long time as a
-* result of it.  In that case say we might mispredict and try
-* to force the CPU into a state for which we would have stopped
-* the tick, unless a timer is going to expire really soon
-* anyway.
-*/
-   if (data->predicted_us < TICK_USEC)
-   data->predicted_us = min_t(unsigned int, TICK_USEC,
-  ktime_to_us(delta_next));
-   } else {
-   /*
-* Use the performance multiplier and the user-configurable
-* latency_req to determine the maximum exit latency.
-*/
-   interactivity_req = data->predicted_us / 
performance_multiplier(nr_iowaiters, cpu_load);
-   if (latency_req > interactivity_req)
-   latency_req = interactivity_req;
-   }
+   /*
+* Use the performance multiplier and the user-configurable latency_req
+* to determine the maximum exit latency.
+*/
+   interactivity_req = data->predicted_us / 
performance_multiplier(nr_iowaiters, cpu_load);
+   if (latency_req > interactivity_req)
+   latency_req = interactivity_req;
 
+select:
expected_interval = data->predicted_us;
/*
 * Find the idle state with the lowest power while satisfying
@@ -403,14 +401,13 @@ static int menu_select(struct cpuidle_dr
 * Don't stop the tick if the selected state is a polling one or if the
 * expected idle duration is shorter than the tick period length.
 */
-   if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
-   expected_interval < TICK_USEC) {
+   if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
+   expected_interval < TICK_USEC) && !tick_nohz_tick_stopped()) {
unsigned int delta_next_us = ktime_to_us(delta_next);
 
*stop_tick = false;
 
-   if 

[PATCH] cpuidle: menu: Handle stopped tick more aggressively

2018-08-10 Thread Rafael J. Wysocki
From: Rafael J. Wysocki 

Commit 87c9fe6ee495 (cpuidle: menu: Avoid selecting shallow states
with stopped tick) missed the case when the target residencies of
deep idle states of CPUs are above the tick boundary which may cause
the CPU to get stuck in a shallow idle state for a long time.

Say there are two CPU idle states available: one shallow, with the
target residency much below the tick boundary and one deep, with
the target residency significantly above the tick boundary.  In
that case, if the tick has been stopped already and the expected
next timer event is relatively far in the future, the governor will
assume the idle duration to be equal to TICK_USEC and it will select
the idle state for the CPU accordingly.  However, that will cause the
shallow state to be selected even though it would have been more
energy-efficient to select the deep one.

To address this issue, modify the governor to always assume idle
duration to be equal to the time till the closest timer event if
the tick is not running which will cause the selected idle states
to always match the known CPU wakeup time.

Also make it always indicate that the tick should be stopped in
that case for consistency.

Fixes: 87c9fe6ee495 (cpuidle: menu: Avoid selecting shallow states with stopped 
tick)
Reported-by: Leo Yan 
Signed-off-by: Rafael J. Wysocki 
---
 drivers/cpuidle/governors/menu.c |   49 ++-
 1 file changed, 23 insertions(+), 26 deletions(-)

Index: linux-pm/drivers/cpuidle/governors/menu.c
===
--- linux-pm.orig/drivers/cpuidle/governors/menu.c
+++ linux-pm/drivers/cpuidle/governors/menu.c
@@ -307,6 +307,18 @@ static int menu_select(struct cpuidle_dr
/* determine the expected residency time, round up */
data->next_timer_us = 
ktime_to_us(tick_nohz_get_sleep_length(_next));
 
+   /*
+* If the tick is already stopped, the cost of possible short idle
+* duration misprediction is much higher, because the CPU may be stuck
+* in a shallow idle state for a long time as a result of it.  In that
+* case say we might mispredict and use the known time till the closest
+* timer event for the idle state selection.
+*/
+   if (tick_nohz_tick_stopped()) {
+   data->predicted_us = ktime_to_us(delta_next);
+   goto select;
+   }
+
get_iowait_load(_iowaiters, _load);
data->bucket = which_bucket(data->next_timer_us, nr_iowaiters);
 
@@ -344,29 +356,15 @@ static int menu_select(struct cpuidle_dr
 */
data->predicted_us = min(data->predicted_us, expected_interval);
 
-   if (tick_nohz_tick_stopped()) {
-   /*
-* If the tick is already stopped, the cost of possible short
-* idle duration misprediction is much higher, because the CPU
-* may be stuck in a shallow idle state for a long time as a
-* result of it.  In that case say we might mispredict and try
-* to force the CPU into a state for which we would have stopped
-* the tick, unless a timer is going to expire really soon
-* anyway.
-*/
-   if (data->predicted_us < TICK_USEC)
-   data->predicted_us = min_t(unsigned int, TICK_USEC,
-  ktime_to_us(delta_next));
-   } else {
-   /*
-* Use the performance multiplier and the user-configurable
-* latency_req to determine the maximum exit latency.
-*/
-   interactivity_req = data->predicted_us / 
performance_multiplier(nr_iowaiters, cpu_load);
-   if (latency_req > interactivity_req)
-   latency_req = interactivity_req;
-   }
+   /*
+* Use the performance multiplier and the user-configurable latency_req
+* to determine the maximum exit latency.
+*/
+   interactivity_req = data->predicted_us / 
performance_multiplier(nr_iowaiters, cpu_load);
+   if (latency_req > interactivity_req)
+   latency_req = interactivity_req;
 
+select:
expected_interval = data->predicted_us;
/*
 * Find the idle state with the lowest power while satisfying
@@ -403,14 +401,13 @@ static int menu_select(struct cpuidle_dr
 * Don't stop the tick if the selected state is a polling one or if the
 * expected idle duration is shorter than the tick period length.
 */
-   if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
-   expected_interval < TICK_USEC) {
+   if (((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) ||
+   expected_interval < TICK_USEC) && !tick_nohz_tick_stopped()) {
unsigned int delta_next_us = ktime_to_us(delta_next);
 
*stop_tick = false;
 
-   if