diff options
author | John Stultz <john.stultz@linaro.org> | 2012-09-04 15:38:12 -0400 |
---|---|---|
committer | John Stultz <john.stultz@linaro.org> | 2012-09-24 12:38:08 -0400 |
commit | 92bb1fcf57a0c2e45f7e67fbf0a8ed475a749236 (patch) | |
tree | f92496be64d01da6cf3ba54c31c4c4753c10bd59 /kernel/time/timekeeping.c | |
parent | 576094b7f0aaf41aadab9b7d4e5bd85faa432711 (diff) |
time: Only do nanosecond rounding on GENERIC_TIME_VSYSCALL_OLD systems
We only do rounding to the next nanosecond so we don't see minor
1ns inconsistencies in the vsyscall implementations. Since we're
changing the vsyscall implementations to avoid this, conditionalize
the rounding only to the GENERIC_TIME_VSYSCALL_OLD architectures.
Cc: Tony Luck <tony.luck@intel.com>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Paul Turner <pjt@google.com>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Prarit Bhargava <prarit@redhat.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: John Stultz <john.stultz@linaro.org>
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r-- | kernel/time/timekeeping.c | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index ce618010c373..16280ff3cf82 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -1062,6 +1062,33 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1062 | return offset; | 1062 | return offset; |
1063 | } | 1063 | } |
1064 | 1064 | ||
1065 | #ifdef CONFIG_GENERIC_TIME_VSYSCALL_OLD | ||
1066 | static inline void old_vsyscall_fixup(struct timekeeper *tk) | ||
1067 | { | ||
1068 | s64 remainder; | ||
1069 | |||
1070 | /* | ||
1071 | * Store only full nanoseconds into xtime_nsec after rounding | ||
1072 | * it up and add the remainder to the error difference. | ||
1073 | * XXX - This is necessary to avoid small 1ns inconsistnecies caused | ||
1074 | * by truncating the remainder in vsyscalls. However, it causes | ||
1075 | * additional work to be done in timekeeping_adjust(). Once | ||
1076 | * the vsyscall implementations are converted to use xtime_nsec | ||
1077 | * (shifted nanoseconds), and CONFIG_GENERIC_TIME_VSYSCALL_OLD | ||
1078 | * users are removed, this can be killed. | ||
1079 | */ | ||
1080 | remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1); | ||
1081 | tk->xtime_nsec -= remainder; | ||
1082 | tk->xtime_nsec += 1ULL << tk->shift; | ||
1083 | tk->ntp_error += remainder << tk->ntp_error_shift; | ||
1084 | |||
1085 | } | ||
1086 | #else | ||
1087 | #define old_vsyscall_fixup(tk) | ||
1088 | #endif | ||
1089 | |||
1090 | |||
1091 | |||
1065 | /** | 1092 | /** |
1066 | * update_wall_time - Uses the current clocksource to increment the wall time | 1093 | * update_wall_time - Uses the current clocksource to increment the wall time |
1067 | * | 1094 | * |
@@ -1073,7 +1100,6 @@ static void update_wall_time(void) | |||
1073 | cycle_t offset; | 1100 | cycle_t offset; |
1074 | int shift = 0, maxshift; | 1101 | int shift = 0, maxshift; |
1075 | unsigned long flags; | 1102 | unsigned long flags; |
1076 | s64 remainder; | ||
1077 | 1103 | ||
1078 | write_seqlock_irqsave(&tk->lock, flags); | 1104 | write_seqlock_irqsave(&tk->lock, flags); |
1079 | 1105 | ||
@@ -1115,20 +1141,11 @@ static void update_wall_time(void) | |||
1115 | /* correct the clock when NTP error is too big */ | 1141 | /* correct the clock when NTP error is too big */ |
1116 | timekeeping_adjust(tk, offset); | 1142 | timekeeping_adjust(tk, offset); |
1117 | 1143 | ||
1118 | |||
1119 | /* | 1144 | /* |
1120 | * Store only full nanoseconds into xtime_nsec after rounding | 1145 | * XXX This can be killed once everyone converts |
1121 | * it up and add the remainder to the error difference. | 1146 | * to the new update_vsyscall. |
1122 | * XXX - This is necessary to avoid small 1ns inconsistnecies caused | 1147 | */ |
1123 | * by truncating the remainder in vsyscalls. However, it causes | 1148 | old_vsyscall_fixup(tk); |
1124 | * additional work to be done in timekeeping_adjust(). Once | ||
1125 | * the vsyscall implementations are converted to use xtime_nsec | ||
1126 | * (shifted nanoseconds), this can be killed. | ||
1127 | */ | ||
1128 | remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1); | ||
1129 | tk->xtime_nsec -= remainder; | ||
1130 | tk->xtime_nsec += 1ULL << tk->shift; | ||
1131 | tk->ntp_error += remainder << tk->ntp_error_shift; | ||
1132 | 1149 | ||
1133 | /* | 1150 | /* |
1134 | * Finally, make sure that after the rounding | 1151 | * Finally, make sure that after the rounding |