aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/time/timekeeping.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/time/timekeeping.c')
-rw-r--r--kernel/time/timekeeping.c38
1 files changed, 33 insertions, 5 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ec1791fae965..a693270efafb 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -417,7 +417,8 @@ EXPORT_SYMBOL_GPL(pvclock_gtod_unregister_notifier);
417 */ 417 */
418static inline void tk_update_ktime_data(struct timekeeper *tk) 418static inline void tk_update_ktime_data(struct timekeeper *tk)
419{ 419{
420 s64 nsec; 420 u64 seconds;
421 u32 nsec;
421 422
422 /* 423 /*
423 * The xtime based monotonic readout is: 424 * The xtime based monotonic readout is:
@@ -426,13 +427,22 @@ static inline void tk_update_ktime_data(struct timekeeper *tk)
426 * nsec = base_mono + now(); 427 * nsec = base_mono + now();
427 * ==> base_mono = (xtime_sec + wtm_sec) * 1e9 + wtm_nsec 428 * ==> base_mono = (xtime_sec + wtm_sec) * 1e9 + wtm_nsec
428 */ 429 */
429 nsec = (s64)(tk->xtime_sec + tk->wall_to_monotonic.tv_sec); 430 seconds = (u64)(tk->xtime_sec + tk->wall_to_monotonic.tv_sec);
430 nsec *= NSEC_PER_SEC; 431 nsec = (u32) tk->wall_to_monotonic.tv_nsec;
431 nsec += tk->wall_to_monotonic.tv_nsec; 432 tk->tkr.base_mono = ns_to_ktime(seconds * NSEC_PER_SEC + nsec);
432 tk->tkr.base_mono = ns_to_ktime(nsec);
433 433
434 /* Update the monotonic raw base */ 434 /* Update the monotonic raw base */
435 tk->base_raw = timespec64_to_ktime(tk->raw_time); 435 tk->base_raw = timespec64_to_ktime(tk->raw_time);
436
437 /*
438 * The sum of the nanoseconds portions of xtime and
439 * wall_to_monotonic can be greater/equal one second. Take
440 * this into account before updating tk->ktime_sec.
441 */
442 nsec += (u32)(tk->tkr.xtime_nsec >> tk->tkr.shift);
443 if (nsec >= NSEC_PER_SEC)
444 seconds++;
445 tk->ktime_sec = seconds;
436} 446}
437 447
438/* must hold timekeeper_lock */ 448/* must hold timekeeper_lock */
@@ -648,6 +658,24 @@ void ktime_get_ts64(struct timespec64 *ts)
648} 658}
649EXPORT_SYMBOL_GPL(ktime_get_ts64); 659EXPORT_SYMBOL_GPL(ktime_get_ts64);
650 660
661/**
662 * ktime_get_seconds - Get the seconds portion of CLOCK_MONOTONIC
663 *
664 * Returns the seconds portion of CLOCK_MONOTONIC with a single non
665 * serialized read. tk->ktime_sec is of type 'unsigned long' so this
666 * works on both 32 and 64 bit systems. On 32 bit systems the readout
667 * covers ~136 years of uptime which should be enough to prevent
668 * premature wrap arounds.
669 */
670time64_t ktime_get_seconds(void)
671{
672 struct timekeeper *tk = &tk_core.timekeeper;
673
674 WARN_ON(timekeeping_suspended);
675 return tk->ktime_sec;
676}
677EXPORT_SYMBOL_GPL(ktime_get_seconds);
678
651#ifdef CONFIG_NTP_PPS 679#ifdef CONFIG_NTP_PPS
652 680
653/** 681/**