linux/kernel/time
John Stultz 0bcdc0987c time: Fix ktime_get_raw() incorrect base accumulation
In comqit fc6eead7c1 ("time: Clean up CLOCK_MONOTONIC_RAW time
handling"), the following code got mistakenly added to the update of the
raw timekeeper:

 /* Update the monotonic raw base */
 seconds = tk->raw_sec;
 nsec = (u32)(tk->tkr_raw.xtime_nsec >> tk->tkr_raw.shift);
 tk->tkr_raw.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);

Which adds the raw_sec value and the shifted down raw xtime_nsec to the
base value.

But the read function adds the shifted down tk->tkr_raw.xtime_nsec value
another time, The result of this is that ktime_get_raw() users (which are
all internal users) see the raw time move faster then it should (the rate
at which can vary with the current size of tkr_raw.xtime_nsec), which has
resulted in at least problems with graphics rendering performance.

The change tried to match the monotonic base update logic:

 seconds = (u64)(tk->xtime_sec + tk->wall_to_monotonic.tv_sec);
 nsec = (u32) tk->wall_to_monotonic.tv_nsec;
 tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);

Which adds the wall_to_monotonic.tv_nsec value, but not the
tk->tkr_mono.xtime_nsec value to the base.

To fix this, simplify the tkr_raw.base accumulation to only accumulate the
raw_sec portion, and do not include the tkr_raw.xtime_nsec portion, which
will be added at read time.

Fixes: fc6eead7c1 ("time: Clean up CLOCK_MONOTONIC_RAW time handling")
Reported-and-tested-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Kevin Brodsky <kevin.brodsky@arm.com>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Stephen Boyd <stephen.boyd@linaro.org>
Cc: Will Deacon <will.deacon@arm.com>
Cc: Miroslav Lichvar <mlichvar@redhat.com>
Cc: Daniel Mentz <danielmentz@google.com>
Link: http://lkml.kernel.org/r/1503701824-1645-1-git-send-email-john.stultz@linaro.org
2017-08-26 16:06:12 +02:00
..
alarmtimer.c nanosleep: Use get_timespec64() and put_timespec64() 2017-06-30 04:14:14 -04:00
clockevents.c clockevents: Make clockevents_config() static 2017-03-23 12:14:05 -07:00
clocksource.c x86/tsc, sched/clock, clocksource: Use clocksource watchdog to provide stable sync points 2017-05-15 10:15:18 +02:00
hrtimer.c nanosleep: Use get_timespec64() and put_timespec64() 2017-06-30 04:14:14 -04:00
itimer.c itimer: Make timeval to nsec conversion range limited 2017-06-20 21:33:56 +02:00
jiffies.c jiffies: Revert bogus conversion of NSEC_PER_SEC to TICK_NSEC 2017-03-07 11:03:28 +01:00
Kconfig rcu: Remove nohz_full full-system-idle state machine 2017-06-08 18:52:39 -07:00
Makefile time: Remove CONFIG_TIMER_STATS 2017-02-10 11:15:08 +01:00
ntp_internal.h
ntp.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
posix-clock.c posix-timers: Move posix-timer internals to core 2017-06-04 15:40:23 +02:00
posix-cpu-timers.c Merge branch 'timers-compat' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs 2017-07-05 15:34:35 -07:00
posix-stubs.c posix-timers: Use get_timespec64() and put_timespec64() 2017-06-30 04:13:19 -04:00
posix-timers.c posix_clocks: Use get_itimerspec64() and put_itimerspec64() 2017-06-30 04:15:02 -04:00
posix-timers.h posix-timers: Make nanosleep timespec argument const 2017-06-14 00:00:47 +02:00
sched_clock.c timers, sched_clock: Update timeout for clock wrap 2017-03-23 12:30:27 -07:00
test_udelay.c time: Avoid timespec in udelay_test 2016-06-20 12:47:26 -07:00
tick-broadcast-hrtimer.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
tick-broadcast.c tick/broadcast: Make tick_broadcast_setup_oneshot() static 2017-06-12 18:56:01 +02:00
tick-common.c ktime: Cleanup ktime_set() usage 2016-12-25 17:21:22 +01:00
tick-internal.h tick/broadcast: Make tick_broadcast_setup_oneshot() static 2017-06-12 18:56:01 +02:00
tick-oneshot.c ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
tick-sched.c Merge branch 'timers-nohz-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip 2017-07-03 13:33:57 -07:00
tick-sched.h nohz: Fix collision between tick and other hrtimers, again 2017-05-17 08:19:47 +02:00
time.c time: introduce {get,put}_itimerspec64 2017-06-25 21:58:46 -04:00
timeconst.bc time: Introduce jiffies64_to_nsecs() 2017-02-01 09:13:45 +01:00
timeconv.c time: Add time64_to_tm() 2016-06-20 12:47:15 -07:00
timecounter.c clocksource: Use a plain u64 instead of cycle_t 2016-12-25 11:04:12 +01:00
timekeeping_debug.c timekeeping: Use deferred printk() in debug code 2017-02-15 11:46:08 +01:00
timekeeping_internal.h clocksource: Use a plain u64 instead of cycle_t 2016-12-25 11:04:12 +01:00
timekeeping.c time: Fix ktime_get_raw() incorrect base accumulation 2017-08-26 16:06:12 +02:00
timekeeping.h timekeeping: Remove unused timekeeping_{get,set}_tai_offset() 2017-01-06 16:47:28 -08:00
timer_list.c sysrq: Reset the watchdog timers while displaying high-resolution timers 2017-03-23 12:46:53 -07:00
timer.c timers: Fix excessive granularity of new timers after a nohz idle 2017-08-24 11:40:18 +02:00