diff options
-rw-r--r-- | include/linux/timekeeper_internal.h | 4 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 41 |
2 files changed, 21 insertions, 24 deletions
diff --git a/include/linux/timekeeper_internal.h b/include/linux/timekeeper_internal.h index 73df17f1535f..fb86963859c7 100644 --- a/include/linux/timekeeper_internal.h +++ b/include/linux/timekeeper_internal.h | |||
@@ -41,6 +41,7 @@ struct tk_read_base { | |||
41 | /** | 41 | /** |
42 | * struct timekeeper - Structure holding internal timekeeping values. | 42 | * struct timekeeper - Structure holding internal timekeeping values. |
43 | * @tkr_mono: The readout base structure for CLOCK_MONOTONIC | 43 | * @tkr_mono: The readout base structure for CLOCK_MONOTONIC |
44 | * @tkr_raw: The readout base structure for CLOCK_MONOTONIC_RAW | ||
44 | * @xtime_sec: Current CLOCK_REALTIME time in seconds | 45 | * @xtime_sec: Current CLOCK_REALTIME time in seconds |
45 | * @ktime_sec: Current CLOCK_MONOTONIC time in seconds | 46 | * @ktime_sec: Current CLOCK_MONOTONIC time in seconds |
46 | * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset | 47 | * @wall_to_monotonic: CLOCK_REALTIME to CLOCK_MONOTONIC offset |
@@ -48,7 +49,6 @@ struct tk_read_base { | |||
48 | * @offs_boot: Offset clock monotonic -> clock boottime | 49 | * @offs_boot: Offset clock monotonic -> clock boottime |
49 | * @offs_tai: Offset clock monotonic -> clock tai | 50 | * @offs_tai: Offset clock monotonic -> clock tai |
50 | * @tai_offset: The current UTC to TAI offset in seconds | 51 | * @tai_offset: The current UTC to TAI offset in seconds |
51 | * @base_raw: Monotonic raw base time in ktime_t format | ||
52 | * @raw_time: Monotonic raw base time in timespec64 format | 52 | * @raw_time: Monotonic raw base time in timespec64 format |
53 | * @cycle_interval: Number of clock cycles in one NTP interval | 53 | * @cycle_interval: Number of clock cycles in one NTP interval |
54 | * @xtime_interval: Number of clock shifted nano seconds in one NTP | 54 | * @xtime_interval: Number of clock shifted nano seconds in one NTP |
@@ -77,6 +77,7 @@ struct tk_read_base { | |||
77 | */ | 77 | */ |
78 | struct timekeeper { | 78 | struct timekeeper { |
79 | struct tk_read_base tkr_mono; | 79 | struct tk_read_base tkr_mono; |
80 | struct tk_read_base tkr_raw; | ||
80 | u64 xtime_sec; | 81 | u64 xtime_sec; |
81 | unsigned long ktime_sec; | 82 | unsigned long ktime_sec; |
82 | struct timespec64 wall_to_monotonic; | 83 | struct timespec64 wall_to_monotonic; |
@@ -84,7 +85,6 @@ struct timekeeper { | |||
84 | ktime_t offs_boot; | 85 | ktime_t offs_boot; |
85 | ktime_t offs_tai; | 86 | ktime_t offs_tai; |
86 | s32 tai_offset; | 87 | s32 tai_offset; |
87 | ktime_t base_raw; | ||
88 | struct timespec64 raw_time; | 88 | struct timespec64 raw_time; |
89 | 89 | ||
90 | /* The following members are for timekeeping internal use */ | 90 | /* The following members are for timekeeping internal use */ |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index 1405091f3acb..cbb612ee813f 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -252,6 +252,11 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) | |||
252 | tk->tkr_mono.mask = clock->mask; | 252 | tk->tkr_mono.mask = clock->mask; |
253 | tk->tkr_mono.cycle_last = tk->tkr_mono.read(clock); | 253 | tk->tkr_mono.cycle_last = tk->tkr_mono.read(clock); |
254 | 254 | ||
255 | tk->tkr_raw.clock = clock; | ||
256 | tk->tkr_raw.read = clock->read; | ||
257 | tk->tkr_raw.mask = clock->mask; | ||
258 | tk->tkr_raw.cycle_last = tk->tkr_mono.cycle_last; | ||
259 | |||
255 | /* Do the ns -> cycle conversion first, using original mult */ | 260 | /* Do the ns -> cycle conversion first, using original mult */ |
256 | tmp = NTP_INTERVAL_LENGTH; | 261 | tmp = NTP_INTERVAL_LENGTH; |
257 | tmp <<= clock->shift; | 262 | tmp <<= clock->shift; |
@@ -278,7 +283,10 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) | |||
278 | else | 283 | else |
279 | tk->tkr_mono.xtime_nsec <<= shift_change; | 284 | tk->tkr_mono.xtime_nsec <<= shift_change; |
280 | } | 285 | } |
286 | tk->tkr_raw.xtime_nsec = 0; | ||
287 | |||
281 | tk->tkr_mono.shift = clock->shift; | 288 | tk->tkr_mono.shift = clock->shift; |
289 | tk->tkr_raw.shift = clock->shift; | ||
282 | 290 | ||
283 | tk->ntp_error = 0; | 291 | tk->ntp_error = 0; |
284 | tk->ntp_error_shift = NTP_SCALE_SHIFT - clock->shift; | 292 | tk->ntp_error_shift = NTP_SCALE_SHIFT - clock->shift; |
@@ -290,6 +298,7 @@ static void tk_setup_internals(struct timekeeper *tk, struct clocksource *clock) | |||
290 | * to counteract clock drifting. | 298 | * to counteract clock drifting. |
291 | */ | 299 | */ |
292 | tk->tkr_mono.mult = clock->mult; | 300 | tk->tkr_mono.mult = clock->mult; |
301 | tk->tkr_raw.mult = clock->mult; | ||
293 | tk->ntp_err_mult = 0; | 302 | tk->ntp_err_mult = 0; |
294 | } | 303 | } |
295 | 304 | ||
@@ -316,21 +325,6 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr) | |||
316 | return nsec + arch_gettimeoffset(); | 325 | return nsec + arch_gettimeoffset(); |
317 | } | 326 | } |
318 | 327 | ||
319 | static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) | ||
320 | { | ||
321 | struct clocksource *clock = tk->tkr_mono.clock; | ||
322 | cycle_t delta; | ||
323 | s64 nsec; | ||
324 | |||
325 | delta = timekeeping_get_delta(&tk->tkr_mono); | ||
326 | |||
327 | /* convert delta to nanoseconds. */ | ||
328 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); | ||
329 | |||
330 | /* If arch requires, add in get_arch_timeoffset() */ | ||
331 | return nsec + arch_gettimeoffset(); | ||
332 | } | ||
333 | |||
334 | /** | 328 | /** |
335 | * update_fast_timekeeper - Update the fast and NMI safe monotonic timekeeper. | 329 | * update_fast_timekeeper - Update the fast and NMI safe monotonic timekeeper. |
336 | * @tkr: Timekeeping readout base from which we take the update | 330 | * @tkr: Timekeeping readout base from which we take the update |
@@ -562,7 +556,7 @@ static inline void tk_update_ktime_data(struct timekeeper *tk) | |||
562 | tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); | 556 | tk->tkr_mono.base = ns_to_ktime(seconds * NSEC_PER_SEC + nsec); |
563 | 557 | ||
564 | /* Update the monotonic raw base */ | 558 | /* Update the monotonic raw base */ |
565 | tk->base_raw = timespec64_to_ktime(tk->raw_time); | 559 | tk->tkr_raw.base = timespec64_to_ktime(tk->raw_time); |
566 | 560 | ||
567 | /* | 561 | /* |
568 | * The sum of the nanoseconds portions of xtime and | 562 | * The sum of the nanoseconds portions of xtime and |
@@ -611,6 +605,7 @@ static void timekeeping_forward_now(struct timekeeper *tk) | |||
611 | cycle_now = tk->tkr_mono.read(clock); | 605 | cycle_now = tk->tkr_mono.read(clock); |
612 | delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask); | 606 | delta = clocksource_delta(cycle_now, tk->tkr_mono.cycle_last, tk->tkr_mono.mask); |
613 | tk->tkr_mono.cycle_last = cycle_now; | 607 | tk->tkr_mono.cycle_last = cycle_now; |
608 | tk->tkr_raw.cycle_last = cycle_now; | ||
614 | 609 | ||
615 | tk->tkr_mono.xtime_nsec += delta * tk->tkr_mono.mult; | 610 | tk->tkr_mono.xtime_nsec += delta * tk->tkr_mono.mult; |
616 | 611 | ||
@@ -619,7 +614,7 @@ static void timekeeping_forward_now(struct timekeeper *tk) | |||
619 | 614 | ||
620 | tk_normalize_xtime(tk); | 615 | tk_normalize_xtime(tk); |
621 | 616 | ||
622 | nsec = clocksource_cyc2ns(delta, clock->mult, clock->shift); | 617 | nsec = clocksource_cyc2ns(delta, tk->tkr_raw.mult, tk->tkr_raw.shift); |
623 | timespec64_add_ns(&tk->raw_time, nsec); | 618 | timespec64_add_ns(&tk->raw_time, nsec); |
624 | } | 619 | } |
625 | 620 | ||
@@ -748,8 +743,8 @@ ktime_t ktime_get_raw(void) | |||
748 | 743 | ||
749 | do { | 744 | do { |
750 | seq = read_seqcount_begin(&tk_core.seq); | 745 | seq = read_seqcount_begin(&tk_core.seq); |
751 | base = tk->base_raw; | 746 | base = tk->tkr_raw.base; |
752 | nsecs = timekeeping_get_ns_raw(tk); | 747 | nsecs = timekeeping_get_ns(&tk->tkr_raw); |
753 | 748 | ||
754 | } while (read_seqcount_retry(&tk_core.seq, seq)); | 749 | } while (read_seqcount_retry(&tk_core.seq, seq)); |
755 | 750 | ||
@@ -862,7 +857,7 @@ void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) | |||
862 | ts_real->tv_sec = tk->xtime_sec; | 857 | ts_real->tv_sec = tk->xtime_sec; |
863 | ts_real->tv_nsec = 0; | 858 | ts_real->tv_nsec = 0; |
864 | 859 | ||
865 | nsecs_raw = timekeeping_get_ns_raw(tk); | 860 | nsecs_raw = timekeeping_get_ns(&tk->tkr_raw); |
866 | nsecs_real = timekeeping_get_ns(&tk->tkr_mono); | 861 | nsecs_real = timekeeping_get_ns(&tk->tkr_mono); |
867 | 862 | ||
868 | } while (read_seqcount_retry(&tk_core.seq, seq)); | 863 | } while (read_seqcount_retry(&tk_core.seq, seq)); |
@@ -1096,7 +1091,7 @@ void getrawmonotonic64(struct timespec64 *ts) | |||
1096 | 1091 | ||
1097 | do { | 1092 | do { |
1098 | seq = read_seqcount_begin(&tk_core.seq); | 1093 | seq = read_seqcount_begin(&tk_core.seq); |
1099 | nsecs = timekeeping_get_ns_raw(tk); | 1094 | nsecs = timekeeping_get_ns(&tk->tkr_raw); |
1100 | ts64 = tk->raw_time; | 1095 | ts64 = tk->raw_time; |
1101 | 1096 | ||
1102 | } while (read_seqcount_retry(&tk_core.seq, seq)); | 1097 | } while (read_seqcount_retry(&tk_core.seq, seq)); |
@@ -1217,7 +1212,6 @@ void __init timekeeping_init(void) | |||
1217 | tk_set_xtime(tk, &now); | 1212 | tk_set_xtime(tk, &now); |
1218 | tk->raw_time.tv_sec = 0; | 1213 | tk->raw_time.tv_sec = 0; |
1219 | tk->raw_time.tv_nsec = 0; | 1214 | tk->raw_time.tv_nsec = 0; |
1220 | tk->base_raw.tv64 = 0; | ||
1221 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) | 1215 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) |
1222 | boot = tk_xtime(tk); | 1216 | boot = tk_xtime(tk); |
1223 | 1217 | ||
@@ -1367,6 +1361,8 @@ void timekeeping_resume(void) | |||
1367 | 1361 | ||
1368 | /* Re-base the last cycle value */ | 1362 | /* Re-base the last cycle value */ |
1369 | tk->tkr_mono.cycle_last = cycle_now; | 1363 | tk->tkr_mono.cycle_last = cycle_now; |
1364 | tk->tkr_raw.cycle_last = cycle_now; | ||
1365 | |||
1370 | tk->ntp_error = 0; | 1366 | tk->ntp_error = 0; |
1371 | timekeeping_suspended = 0; | 1367 | timekeeping_suspended = 0; |
1372 | timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); | 1368 | timekeeping_update(tk, TK_MIRROR | TK_CLOCK_WAS_SET); |
@@ -1681,6 +1677,7 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1681 | /* Accumulate one shifted interval */ | 1677 | /* Accumulate one shifted interval */ |
1682 | offset -= interval; | 1678 | offset -= interval; |
1683 | tk->tkr_mono.cycle_last += interval; | 1679 | tk->tkr_mono.cycle_last += interval; |
1680 | tk->tkr_raw.cycle_last += interval; | ||
1684 | 1681 | ||
1685 | tk->tkr_mono.xtime_nsec += tk->xtime_interval << shift; | 1682 | tk->tkr_mono.xtime_nsec += tk->xtime_interval << shift; |
1686 | *clock_set |= accumulate_nsecs_to_secs(tk); | 1683 | *clock_set |= accumulate_nsecs_to_secs(tk); |