linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] powerpc/timebase_read: don't return time older than cycle_last
@ 2011-06-27 21:56 Scott Wood
  2011-06-28  0:45 ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 8+ messages in thread
From: Scott Wood @ 2011-06-27 21:56 UTC (permalink / raw)
  To: benh; +Cc: linuxppc-dev

As is done in read_tsc() on x86, make sure that we don't return a timebase
value smaller than cycle_last, which can happen on SMP if the timebases are
not perfectly synchronized.  It is less expensive than total enforcement of
monotonicity, since we don't need to add another variable and update it on
each read, but it will prevent core timekeeping functions from translating
a small timebase regression into a large jump forward.

Based on commit d8bb6f4c1670c8324e4135c61ef07486f7f17379 for x86.

Signed-off-by: Scott Wood <scottwood@freescale.com>
---
 arch/powerpc/kernel/time.c |   15 ++++++++++++++-
 1 files changed, 14 insertions(+), 1 deletions(-)

diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index f33acfd..b66ce41 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -806,9 +806,22 @@ static cycle_t rtc_read(struct clocksource *cs)
 	return (cycle_t)get_rtc();
 }
 
+/*
+ * We compare the timebase to the cycle_last value in the clocksource
+ * structure to avoid a nasty time-warp.  This can be observed in a very
+ * small window right after one CPU updated cycle_last under the xtime lock,
+ * and the other CPU reads a TSC value which is smaller than the cycle_last
+ * reference value due to a TSC which is slighty behind.  This delta is
+ * nowhere else observable, but in that case it results in a large forward
+ * time jump due to the unsigned delta calculation of the time keeping core
+ * code, which is necessary to support wrapping clocksources like pm timer.
+ */
 static cycle_t timebase_read(struct clocksource *cs)
 {
-	return (cycle_t)get_tb();
+	cycle_t ret = (cycle_t)get_tb();
+
+	return ret >= clocksource_timebase.cycle_last ?
+	       ret : clocksource_timebase.cycle_last;
 }
 
 void update_vsyscall(struct timespec *wall_time, struct timespec *wtm,
-- 
1.7.4.1

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

end of thread, other threads:[~2011-06-30  0:29 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-27 21:56 [PATCH] powerpc/timebase_read: don't return time older than cycle_last Scott Wood
2011-06-28  0:45 ` Benjamin Herrenschmidt
2011-06-28 16:14   ` Scott Wood
2011-06-28 23:25     ` Benjamin Herrenschmidt
2011-06-29  0:08       ` Scott Wood
2011-06-29  1:06         ` Benjamin Herrenschmidt
2011-06-29 19:19           ` Scott Wood
2011-06-30  0:29             ` Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).