All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] cpuidle: Fix last_residency division
@ 2016-06-24  8:23 Shreyas B. Prabhu
  2016-06-24  9:00   ` David Laight
                   ` (3 more replies)
  0 siblings, 4 replies; 16+ messages in thread
From: Shreyas B. Prabhu @ 2016-06-24  8:23 UTC (permalink / raw)
  To: rjw
  Cc: daniel.lezcano, linux-pm, linuxppc-dev, anton, mpe, bsingharora,
	Shreyas B. Prabhu

Snooze is a poll idle state in powernv and pseries platforms. Snooze
has a timeout so that if a cpu stays in snooze for more than target
residency of the next available idle state, then it would exit thereby
giving chance to the cpuidle governor to re-evaluate and
promote the cpu to a deeper idle state. Therefore whenever snooze exits
due to this timeout, its last_residency will be target_residency of next
deeper state.

commit e93e59ce5b85 ("cpuidle: Replace ktime_get() with local_clock()")
changed the math around last_residency calculation. Specifically, while
converting last_residency value from nanoseconds to microseconds it does
right shift by 10. Due to this, in snooze timeout exit scenarios
last_residency calculated is roughly 2.3% less than target_residency of
next available state. This pattern is picked up get_typical_interval()
in the menu governor and therefore expected_interval in menu_select() is
frequently less than the target_residency of any state but snooze.

Due to this we are entering snooze at a higher rate, thereby affecting
the single thread performance.

Fix this by replacing right shift by 10 with /1000 while calculating
last_residency.

Reported-by: Anton Blanchard <anton@samba.org>
Bisected-by: Shilpasri G Bhat <shilpa.bhat@linux.vnet.ibm.com>
Signed-off-by: Shreyas B. Prabhu <shreyas@linux.vnet.ibm.com>
---
Changes in v2
=============
 - Fixing it in the cpuidle core code instead of driver code.

 drivers/cpuidle/cpuidle.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index a4d0059..30d67a8 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -218,10 +218,10 @@ int cpuidle_enter_state(struct cpuidle_device *dev, struct cpuidle_driver *drv,
 		local_irq_enable();
 
 	/*
-	 * local_clock() returns the time in nanosecond, let's shift
-	 * by 10 (divide by 1024) to have microsecond based time.
+	 * local_clock() returns the time in nanosecond, let's
+	 * divide by 1000 to have microsecond based time.
 	 */
-	diff = (time_end - time_start) >> 10;
+	diff = (time_end - time_start) / 1000;
 	if (diff > INT_MAX)
 		diff = INT_MAX;
 
-- 
2.1.4


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

end of thread, other threads:[~2016-06-29  7:00 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-24  8:23 [PATCH v2] cpuidle: Fix last_residency division Shreyas B. Prabhu
2016-06-24  9:00 ` David Laight
2016-06-24  9:00   ` David Laight
2016-06-24 10:05   ` Daniel Lezcano
2016-06-24 10:11   ` Arnd Bergmann
2016-06-24 16:01     ` Shreyas B Prabhu
2016-06-24 19:43       ` Arnd Bergmann
2016-06-27  8:59         ` David Laight
2016-06-27  8:59           ` David Laight
2016-06-29  7:00           ` Shreyas B Prabhu
2016-06-24  9:30 ` kbuild test robot
2016-06-24  9:30   ` kbuild test robot
2016-06-24 10:27 ` kbuild test robot
2016-06-24 10:27   ` kbuild test robot
2016-06-24 12:10 ` kbuild test robot
2016-06-24 12:10   ` kbuild test robot

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.