Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+31 -14
+31 -14
kernel/time/timekeeping.c
··· 1062 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 1093 * update_wall_time - Uses the current clocksource to increment the wall time 1067 1094 * ··· 1100 1073 cycle_t offset; 1101 1074 int shift = 0, maxshift; 1102 1075 unsigned long flags; 1103 - s64 remainder; 1104 1076 1105 1077 write_seqlock_irqsave(&tk->lock, flags); 1106 1078 ··· 1141 1115 /* correct the clock when NTP error is too big */ 1142 1116 timekeeping_adjust(tk, offset); 1143 1117 1144 - 1145 1118 /* 1146 - * Store only full nanoseconds into xtime_nsec after rounding 1147 - * it up and add the remainder to the error difference. 1148 - * XXX - This is necessary to avoid small 1ns inconsistnecies caused 1149 - * by truncating the remainder in vsyscalls. However, it causes 1150 - * additional work to be done in timekeeping_adjust(). Once 1151 - * the vsyscall implementations are converted to use xtime_nsec 1152 - * (shifted nanoseconds), this can be killed. 1153 - */ 1154 - remainder = tk->xtime_nsec & ((1ULL << tk->shift) - 1); 1155 - tk->xtime_nsec -= remainder; 1156 - tk->xtime_nsec += 1ULL << tk->shift; 1157 - tk->ntp_error += remainder << tk->ntp_error_shift; 1119 + * XXX This can be killed once everyone converts 1120 + * to the new update_vsyscall. 1121 + */ 1122 + old_vsyscall_fixup(tk); 1158 1123 1159 1124 /* 1160 1125 * Finally, make sure that after the rounding