diff options
author | John Stultz <john.stultz@linaro.org> | 2012-07-13 01:21:56 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2012-07-15 04:39:07 -0400 |
commit | 2a8c0883c3cfffcc148ea606e2a4e7453cd75e73 (patch) | |
tree | 9a340aaef6785881ec0eab74c32ad35841441889 /kernel | |
parent | f2a5a0854efc62abe7f69e9947842cb135837f9a (diff) |
time: Move xtime_nsec adjustment underflow handling timekeeping_adjust
When we make adjustments speeding up the clock, its possible
for xtime_nsec to underflow. We already handle this properly,
but we do so from update_wall_time() instead of the more logical
timekeeping_adjust(), where the possible underflow actually
occurs.
Thus, move the correction logic to the timekeeping_adjust, which
is the function that causes the issue. Making update_wall_time()
more readable.
Signed-off-by: John Stultz <johnstul@us.ibm.com>
Reviewed-by: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Link: http://lkml.kernel.org/r/1342156917-25092-8-git-send-email-john.stultz@linaro.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/time/timekeeping.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index e43289df28c2..aeeaab8cba6e 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -980,6 +980,27 @@ static void timekeeping_adjust(s64 offset) | |||
980 | timekeeper.xtime_nsec -= offset; | 980 | timekeeper.xtime_nsec -= offset; |
981 | timekeeper.ntp_error -= (interval - offset) << | 981 | timekeeper.ntp_error -= (interval - offset) << |
982 | timekeeper.ntp_error_shift; | 982 | timekeeper.ntp_error_shift; |
983 | |||
984 | /* | ||
985 | * It may be possible that when we entered this function, xtime_nsec | ||
986 | * was very small. Further, if we're slightly speeding the clocksource | ||
987 | * in the code above, its possible the required corrective factor to | ||
988 | * xtime_nsec could cause it to underflow. | ||
989 | * | ||
990 | * Now, since we already accumulated the second, cannot simply roll | ||
991 | * the accumulated second back, since the NTP subsystem has been | ||
992 | * notified via second_overflow. So instead we push xtime_nsec forward | ||
993 | * by the amount we underflowed, and add that amount into the error. | ||
994 | * | ||
995 | * We'll correct this error next time through this function, when | ||
996 | * xtime_nsec is not as small. | ||
997 | */ | ||
998 | if (unlikely((s64)timekeeper.xtime_nsec < 0)) { | ||
999 | s64 neg = -(s64)timekeeper.xtime_nsec; | ||
1000 | timekeeper.xtime_nsec = 0; | ||
1001 | timekeeper.ntp_error += neg << timekeeper.ntp_error_shift; | ||
1002 | } | ||
1003 | |||
983 | } | 1004 | } |
984 | 1005 | ||
985 | 1006 | ||
@@ -1105,27 +1126,6 @@ static void update_wall_time(void) | |||
1105 | /* correct the clock when NTP error is too big */ | 1126 | /* correct the clock when NTP error is too big */ |
1106 | timekeeping_adjust(offset); | 1127 | timekeeping_adjust(offset); |
1107 | 1128 | ||
1108 | /* | ||
1109 | * Since in the loop above, we accumulate any amount of time | ||
1110 | * in xtime_nsec over a second into xtime.tv_sec, its possible for | ||
1111 | * xtime_nsec to be fairly small after the loop. Further, if we're | ||
1112 | * slightly speeding the clocksource up in timekeeping_adjust(), | ||
1113 | * its possible the required corrective factor to xtime_nsec could | ||
1114 | * cause it to underflow. | ||
1115 | * | ||
1116 | * Now, we cannot simply roll the accumulated second back, since | ||
1117 | * the NTP subsystem has been notified via second_overflow. So | ||
1118 | * instead we push xtime_nsec forward by the amount we underflowed, | ||
1119 | * and add that amount into the error. | ||
1120 | * | ||
1121 | * We'll correct this error next time through this function, when | ||
1122 | * xtime_nsec is not as small. | ||
1123 | */ | ||
1124 | if (unlikely((s64)timekeeper.xtime_nsec < 0)) { | ||
1125 | s64 neg = -(s64)timekeeper.xtime_nsec; | ||
1126 | timekeeper.xtime_nsec = 0; | ||
1127 | timekeeper.ntp_error += neg << timekeeper.ntp_error_shift; | ||
1128 | } | ||
1129 | 1129 | ||
1130 | /* | 1130 | /* |
1131 | * Store only full nanoseconds into xtime_nsec after rounding | 1131 | * Store only full nanoseconds into xtime_nsec after rounding |