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.c59
1 files changed, 32 insertions, 27 deletions
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index ec1791fae965..2dc0646258ae 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -519,9 +519,9 @@ EXPORT_SYMBOL(__getnstimeofday64);
519 519
520/** 520/**
521 * getnstimeofday64 - Returns the time of day in a timespec64. 521 * getnstimeofday64 - Returns the time of day in a timespec64.
522 * @ts: pointer to the timespec to be set 522 * @ts: pointer to the timespec64 to be set
523 * 523 *
524 * Returns the time of day in a timespec (WARN if suspended). 524 * Returns the time of day in a timespec64 (WARN if suspended).
525 */ 525 */
526void getnstimeofday64(struct timespec64 *ts) 526void getnstimeofday64(struct timespec64 *ts)
527{ 527{
@@ -623,7 +623,7 @@ EXPORT_SYMBOL_GPL(ktime_get_raw);
623 * 623 *
624 * The function calculates the monotonic clock from the realtime 624 * The function calculates the monotonic clock from the realtime
625 * clock and the wall_to_monotonic offset and stores the result 625 * clock and the wall_to_monotonic offset and stores the result
626 * in normalized timespec format in the variable pointed to by @ts. 626 * in normalized timespec64 format in the variable pointed to by @ts.
627 */ 627 */
628void ktime_get_ts64(struct timespec64 *ts) 628void ktime_get_ts64(struct timespec64 *ts)
629{ 629{
@@ -703,18 +703,18 @@ void do_gettimeofday(struct timeval *tv)
703EXPORT_SYMBOL(do_gettimeofday); 703EXPORT_SYMBOL(do_gettimeofday);
704 704
705/** 705/**
706 * do_settimeofday - Sets the time of day 706 * do_settimeofday64 - Sets the time of day.
707 * @tv: pointer to the timespec variable containing the new time 707 * @ts: pointer to the timespec64 variable containing the new time
708 * 708 *
709 * Sets the time of day to the new time and update NTP and notify hrtimers 709 * Sets the time of day to the new time and update NTP and notify hrtimers
710 */ 710 */
711int do_settimeofday(const struct timespec *tv) 711int do_settimeofday64(const struct timespec64 *ts)
712{ 712{
713 struct timekeeper *tk = &tk_core.timekeeper; 713 struct timekeeper *tk = &tk_core.timekeeper;
714 struct timespec64 ts_delta, xt, tmp; 714 struct timespec64 ts_delta, xt;
715 unsigned long flags; 715 unsigned long flags;
716 716
717 if (!timespec_valid_strict(tv)) 717 if (!timespec64_valid_strict(ts))
718 return -EINVAL; 718 return -EINVAL;
719 719
720 raw_spin_lock_irqsave(&timekeeper_lock, flags); 720 raw_spin_lock_irqsave(&timekeeper_lock, flags);
@@ -723,13 +723,12 @@ int do_settimeofday(const struct timespec *tv)
723 timekeeping_forward_now(tk); 723 timekeeping_forward_now(tk);
724 724
725 xt = tk_xtime(tk); 725 xt = tk_xtime(tk);
726 ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; 726 ts_delta.tv_sec = ts->tv_sec - xt.tv_sec;
727 ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; 727 ts_delta.tv_nsec = ts->tv_nsec - xt.tv_nsec;
728 728
729 tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta)); 729 tk_set_wall_to_mono(tk, timespec64_sub(tk->wall_to_monotonic, ts_delta));
730 730
731 tmp = timespec_to_timespec64(*tv); 731 tk_set_xtime(tk, ts);
732 tk_set_xtime(tk, &tmp);
733 732
734 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); 733 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
735 734
@@ -741,7 +740,7 @@ int do_settimeofday(const struct timespec *tv)
741 740
742 return 0; 741 return 0;
743} 742}
744EXPORT_SYMBOL(do_settimeofday); 743EXPORT_SYMBOL(do_settimeofday64);
745 744
746/** 745/**
747 * timekeeping_inject_offset - Adds or subtracts from the current time. 746 * timekeeping_inject_offset - Adds or subtracts from the current time.
@@ -895,12 +894,12 @@ int timekeeping_notify(struct clocksource *clock)
895} 894}
896 895
897/** 896/**
898 * getrawmonotonic - Returns the raw monotonic time in a timespec 897 * getrawmonotonic64 - Returns the raw monotonic time in a timespec
899 * @ts: pointer to the timespec to be set 898 * @ts: pointer to the timespec64 to be set
900 * 899 *
901 * Returns the raw monotonic time (completely un-modified by ntp) 900 * Returns the raw monotonic time (completely un-modified by ntp)
902 */ 901 */
903void getrawmonotonic(struct timespec *ts) 902void getrawmonotonic64(struct timespec64 *ts)
904{ 903{
905 struct timekeeper *tk = &tk_core.timekeeper; 904 struct timekeeper *tk = &tk_core.timekeeper;
906 struct timespec64 ts64; 905 struct timespec64 ts64;
@@ -915,9 +914,10 @@ void getrawmonotonic(struct timespec *ts)
915 } while (read_seqcount_retry(&tk_core.seq, seq)); 914 } while (read_seqcount_retry(&tk_core.seq, seq));
916 915
917 timespec64_add_ns(&ts64, nsecs); 916 timespec64_add_ns(&ts64, nsecs);
918 *ts = timespec64_to_timespec(ts64); 917 *ts = ts64;
919} 918}
920EXPORT_SYMBOL(getrawmonotonic); 919EXPORT_SYMBOL(getrawmonotonic64);
920
921 921
922/** 922/**
923 * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres 923 * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres
@@ -1068,8 +1068,8 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
1068} 1068}
1069 1069
1070/** 1070/**
1071 * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values 1071 * timekeeping_inject_sleeptime64 - Adds suspend interval to timeekeeping values
1072 * @delta: pointer to a timespec delta value 1072 * @delta: pointer to a timespec64 delta value
1073 * 1073 *
1074 * This hook is for architectures that cannot support read_persistent_clock 1074 * This hook is for architectures that cannot support read_persistent_clock
1075 * because their RTC/persistent clock is only accessible when irqs are enabled. 1075 * because their RTC/persistent clock is only accessible when irqs are enabled.
@@ -1077,10 +1077,9 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk,
1077 * This function should only be called by rtc_resume(), and allows 1077 * This function should only be called by rtc_resume(), and allows
1078 * a suspend offset to be injected into the timekeeping values. 1078 * a suspend offset to be injected into the timekeeping values.
1079 */ 1079 */
1080void timekeeping_inject_sleeptime(struct timespec *delta) 1080void timekeeping_inject_sleeptime64(struct timespec64 *delta)
1081{ 1081{
1082 struct timekeeper *tk = &tk_core.timekeeper; 1082 struct timekeeper *tk = &tk_core.timekeeper;
1083 struct timespec64 tmp;
1084 unsigned long flags; 1083 unsigned long flags;
1085 1084
1086 /* 1085 /*
@@ -1095,8 +1094,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta)
1095 1094
1096 timekeeping_forward_now(tk); 1095 timekeeping_forward_now(tk);
1097 1096
1098 tmp = timespec_to_timespec64(*delta); 1097 __timekeeping_inject_sleeptime(tk, delta);
1099 __timekeeping_inject_sleeptime(tk, &tmp);
1100 1098
1101 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET); 1099 timekeeping_update(tk, TK_CLEAR_NTP | TK_MIRROR | TK_CLOCK_WAS_SET);
1102 1100
@@ -1332,6 +1330,12 @@ static __always_inline void timekeeping_apply_adjustment(struct timekeeper *tk,
1332 * 1330 *
1333 * XXX - TODO: Doc ntp_error calculation. 1331 * XXX - TODO: Doc ntp_error calculation.
1334 */ 1332 */
1333 if ((mult_adj > 0) && (tk->tkr.mult + mult_adj < mult_adj)) {
1334 /* NTP adjustment caused clocksource mult overflow */
1335 WARN_ON_ONCE(1);
1336 return;
1337 }
1338
1335 tk->tkr.mult += mult_adj; 1339 tk->tkr.mult += mult_adj;
1336 tk->xtime_interval += interval; 1340 tk->xtime_interval += interval;
1337 tk->tkr.xtime_nsec -= offset; 1341 tk->tkr.xtime_nsec -= offset;
@@ -1397,7 +1401,8 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset)
1397 } 1401 }
1398 1402
1399 if (unlikely(tk->tkr.clock->maxadj && 1403 if (unlikely(tk->tkr.clock->maxadj &&
1400 (tk->tkr.mult > tk->tkr.clock->mult + tk->tkr.clock->maxadj))) { 1404 (abs(tk->tkr.mult - tk->tkr.clock->mult)
1405 > tk->tkr.clock->maxadj))) {
1401 printk_once(KERN_WARNING 1406 printk_once(KERN_WARNING
1402 "Adjusting %s more than 11%% (%ld vs %ld)\n", 1407 "Adjusting %s more than 11%% (%ld vs %ld)\n",
1403 tk->tkr.clock->name, (long)tk->tkr.mult, 1408 tk->tkr.clock->name, (long)tk->tkr.mult,
@@ -1646,7 +1651,7 @@ struct timespec current_kernel_time(void)
1646} 1651}
1647EXPORT_SYMBOL(current_kernel_time); 1652EXPORT_SYMBOL(current_kernel_time);
1648 1653
1649struct timespec get_monotonic_coarse(void) 1654struct timespec64 get_monotonic_coarse64(void)
1650{ 1655{
1651 struct timekeeper *tk = &tk_core.timekeeper; 1656 struct timekeeper *tk = &tk_core.timekeeper;
1652 struct timespec64 now, mono; 1657 struct timespec64 now, mono;
@@ -1662,7 +1667,7 @@ struct timespec get_monotonic_coarse(void)
1662 set_normalized_timespec64(&now, now.tv_sec + mono.tv_sec, 1667 set_normalized_timespec64(&now, now.tv_sec + mono.tv_sec,
1663 now.tv_nsec + mono.tv_nsec); 1668 now.tv_nsec + mono.tv_nsec);
1664 1669
1665 return timespec64_to_timespec(now); 1670 return now;
1666} 1671}
1667 1672
1668/* 1673/*