@@ -164,17 +164,42 @@ static inline struct timespec64 tk_xtime(const struct timekeeper *tk)
164
164
return ts ;
165
165
}
166
166
167
+ static inline struct timespec64 tk_xtime_coarse (const struct timekeeper * tk )
168
+ {
169
+ struct timespec64 ts ;
170
+
171
+ ts .tv_sec = tk -> xtime_sec ;
172
+ ts .tv_nsec = tk -> coarse_nsec ;
173
+ return ts ;
174
+ }
175
+
176
+ /*
177
+ * Update the nanoseconds part for the coarse time keepers. They can't rely
178
+ * on xtime_nsec because xtime_nsec could be adjusted by a small negative
179
+ * amount when the multiplication factor of the clock is adjusted, which
180
+ * could cause the coarse clocks to go slightly backwards. See
181
+ * timekeeping_apply_adjustment(). Thus we keep a separate copy for the coarse
182
+ * clockids which only is updated when the clock has been set or we have
183
+ * accumulated time.
184
+ */
185
+ static inline void tk_update_coarse_nsecs (struct timekeeper * tk )
186
+ {
187
+ tk -> coarse_nsec = tk -> tkr_mono .xtime_nsec >> tk -> tkr_mono .shift ;
188
+ }
189
+
167
190
static void tk_set_xtime (struct timekeeper * tk , const struct timespec64 * ts )
168
191
{
169
192
tk -> xtime_sec = ts -> tv_sec ;
170
193
tk -> tkr_mono .xtime_nsec = (u64 )ts -> tv_nsec << tk -> tkr_mono .shift ;
194
+ tk_update_coarse_nsecs (tk );
171
195
}
172
196
173
197
static void tk_xtime_add (struct timekeeper * tk , const struct timespec64 * ts )
174
198
{
175
199
tk -> xtime_sec += ts -> tv_sec ;
176
200
tk -> tkr_mono .xtime_nsec += (u64 )ts -> tv_nsec << tk -> tkr_mono .shift ;
177
201
tk_normalize_xtime (tk );
202
+ tk_update_coarse_nsecs (tk );
178
203
}
179
204
180
205
static void tk_set_wall_to_mono (struct timekeeper * tk , struct timespec64 wtm )
@@ -708,6 +733,7 @@ static void timekeeping_forward_now(struct timekeeper *tk)
708
733
tk_normalize_xtime (tk );
709
734
delta -= incr ;
710
735
}
736
+ tk_update_coarse_nsecs (tk );
711
737
}
712
738
713
739
/**
@@ -804,16 +830,16 @@ EXPORT_SYMBOL_GPL(ktime_get_with_offset);
804
830
ktime_t ktime_get_coarse_with_offset (enum tk_offsets offs )
805
831
{
806
832
struct timekeeper * tk = & tk_core .timekeeper ;
807
- unsigned int seq ;
808
833
ktime_t base , * offset = offsets [offs ];
834
+ unsigned int seq ;
809
835
u64 nsecs ;
810
836
811
837
WARN_ON (timekeeping_suspended );
812
838
813
839
do {
814
840
seq = read_seqcount_begin (& tk_core .seq );
815
841
base = ktime_add (tk -> tkr_mono .base , * offset );
816
- nsecs = tk -> tkr_mono . xtime_nsec >> tk -> tkr_mono . shift ;
842
+ nsecs = tk -> coarse_nsec ;
817
843
818
844
} while (read_seqcount_retry (& tk_core .seq , seq ));
819
845
@@ -2161,7 +2187,7 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
2161
2187
struct timekeeper * real_tk = & tk_core .timekeeper ;
2162
2188
unsigned int clock_set = 0 ;
2163
2189
int shift = 0 , maxshift ;
2164
- u64 offset ;
2190
+ u64 offset , orig_offset ;
2165
2191
2166
2192
guard (raw_spinlock_irqsave )(& tk_core .lock );
2167
2193
@@ -2172,7 +2198,7 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
2172
2198
offset = clocksource_delta (tk_clock_read (& tk -> tkr_mono ),
2173
2199
tk -> tkr_mono .cycle_last , tk -> tkr_mono .mask ,
2174
2200
tk -> tkr_mono .clock -> max_raw_delta );
2175
-
2201
+ orig_offset = offset ;
2176
2202
/* Check if there's really nothing to do */
2177
2203
if (offset < real_tk -> cycle_interval && mode == TK_ADV_TICK )
2178
2204
return false;
@@ -2205,6 +2231,14 @@ static bool timekeeping_advance(enum timekeeping_adv_mode mode)
2205
2231
*/
2206
2232
clock_set |= accumulate_nsecs_to_secs (tk );
2207
2233
2234
+ /*
2235
+ * To avoid inconsistencies caused adjtimex TK_ADV_FREQ calls
2236
+ * making small negative adjustments to the base xtime_nsec
2237
+ * value, only update the coarse clocks if we accumulated time
2238
+ */
2239
+ if (orig_offset != offset )
2240
+ tk_update_coarse_nsecs (tk );
2241
+
2208
2242
timekeeping_update_from_shadow (& tk_core , clock_set );
2209
2243
2210
2244
return !!clock_set ;
@@ -2248,7 +2282,7 @@ void ktime_get_coarse_real_ts64(struct timespec64 *ts)
2248
2282
do {
2249
2283
seq = read_seqcount_begin (& tk_core .seq );
2250
2284
2251
- * ts = tk_xtime (tk );
2285
+ * ts = tk_xtime_coarse (tk );
2252
2286
} while (read_seqcount_retry (& tk_core .seq , seq ));
2253
2287
}
2254
2288
EXPORT_SYMBOL (ktime_get_coarse_real_ts64 );
@@ -2271,7 +2305,7 @@ void ktime_get_coarse_real_ts64_mg(struct timespec64 *ts)
2271
2305
2272
2306
do {
2273
2307
seq = read_seqcount_begin (& tk_core .seq );
2274
- * ts = tk_xtime (tk );
2308
+ * ts = tk_xtime_coarse (tk );
2275
2309
offset = tk_core .timekeeper .offs_real ;
2276
2310
} while (read_seqcount_retry (& tk_core .seq , seq ));
2277
2311
@@ -2350,12 +2384,12 @@ void ktime_get_coarse_ts64(struct timespec64 *ts)
2350
2384
do {
2351
2385
seq = read_seqcount_begin (& tk_core .seq );
2352
2386
2353
- now = tk_xtime (tk );
2387
+ now = tk_xtime_coarse (tk );
2354
2388
mono = tk -> wall_to_monotonic ;
2355
2389
} while (read_seqcount_retry (& tk_core .seq , seq ));
2356
2390
2357
2391
set_normalized_timespec64 (ts , now .tv_sec + mono .tv_sec ,
2358
- now .tv_nsec + mono .tv_nsec );
2392
+ now .tv_nsec + mono .tv_nsec );
2359
2393
}
2360
2394
EXPORT_SYMBOL (ktime_get_coarse_ts64 );
2361
2395
0 commit comments