From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: John Stultz <john.stultz@linaro.org>,
Thomas Gleixner <tglx@linutronix.de>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>,
Paul Mackerras <paulus@samba.org>,
Tony Luck <tony.luck@intel.com>,
Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-kernel@vger.kernel.org
Subject: Clock drift with GENERIC_TIME_VSYSCALL_OLD
Date: Fri, 22 Nov 2013 16:38:15 +0100 [thread overview]
Message-ID: <20131122163815.393ab1f2@mschwide> (raw)
Greetings,
I just hunted down a time related bug which caused the Linux internal
xtime to drift away from the precise hardware clock provided by the
TOD clock found in the s390 architecture.
After a long search I came along this lovely piece of code in
kernel/time/timekeeping.c:
#ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD
static inline void old_vsyscall_fixup(struct timekeeper *tk)
s64 remainder;
/*
* Store only full nanoseconds into xtime_nsec after rounding
* it up and add the remainder to the error difference.
* XXX - This is necessary to avoid small 1ns inconsistnecies caused
* by truncating the remainder in vsyscalls. However, it causes
* additional work to be done in timekeeping_adjust(). Once
* the vsyscall implementations are converted to use xtime_nsec
* (shifted nanoseconds), and CONFIG_GENERIC_TIME_VSYSCALL_OLD
* users are removed, this can be killed.
*/
remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1);
tk->xtime_nsec -= remainder;
tk->xtime_nsec += 1ULL << tk->shift;
tk->ntp_error += remainder << tk->ntp_error_shift;
}
#else
#define old_vsyscall_fixup(tk)
#endif
The highly precise result of our TOD clock source ends up in
tk->xtime_sec / tk->xtime_nsec where old_vsyscall_fixup just rounds
it up to the next nano-second (booo). To add insult to injury an
incorrect delta gets added to ntp_error, xtime has been forwarded by
((1ULL << tk->shift) - (tk->xtime_nsec & ((1ULL << tk->shift) - 1)))
and not set back by (tk->xtime_nsec & ((1ULL << tk->shift) - 1)).
xtime is too fast by one nano-second per tick. To verify that this
is indeed the problem I removed the line that adds the nano-second
to xtime_nsec and voila the clocks are in sync.
A possible patch to fix this would be:
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1347,6 +1347,7 @@ static inline void old_vsyscall_fixup(struct timekeeper *t
k)
tk->xtime_nsec -= remainder;
tk->xtime_nsec += 1ULL << tk->shift;
tk->ntp_error += remainder << tk->ntp_error_shift;
+ tk->ntp_error -= (1ULL << tk->shift) << tk->ntp_error_shift;
}
#else
But that has the downside that it creates a negative ntp_error that
can only be corrected with an adjustment of tk->mult which takes a
long time.
The fix I am going to use is to convert s390 to GENERIC_TIME_VSYSCALL,
you might want to think about doing that for powerpc and ia64 as well.
--
blue skies,
Martin.
"Reality continues to ruin my life." - Calvin.
next reply other threads:[~2013-11-22 15:39 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-22 15:38 Martin Schwidefsky [this message]
2013-11-22 19:15 ` Clock drift with GENERIC_TIME_VSYSCALL_OLD John Stultz
2013-11-23 10:22 ` Martin Schwidefsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20131122163815.393ab1f2@mschwide \
--to=schwidefsky@de.ibm.com \
--cc=benh@kernel.crashing.org \
--cc=fenghua.yu@intel.com \
--cc=john.stultz@linaro.org \
--cc=linux-kernel@vger.kernel.org \
--cc=paulus@samba.org \
--cc=tglx@linutronix.de \
--cc=tony.luck@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.