aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-12-19 06:03:17 -0500
committerThomas Gleixner <tglx@linutronix.de>2015-12-19 06:03:17 -0500
commite2666d69068aba300d6c0dfe96489552f653be2a (patch)
tree07fa371d800deec45225589ebe6154dcc6c956b2
parentd33f250af4e67d449f2c748b861ba99d50955469 (diff)
parentec02b076ceab63f99e5b3d80fd223d777266c236 (diff)
Merge branch 'fortglx/4.5/time' of https://git.linaro.org/people/john.stultz/linux into timers/core
Get the core time(keeping) updates from John Stultz - NTP robustness tweaks - Another signed overflow nailed down - More y2038 changes - Stop alarmtimer after resume - MAINTAINERS update - Selftest fixes
-rw-r--r--MAINTAINERS3
-rw-r--r--include/linux/time.h26
-rw-r--r--kernel/time/alarmtimer.c17
-rw-r--r--kernel/time/clocksource.c4
-rw-r--r--kernel/time/ntp.c44
-rw-r--r--kernel/time/ntp_internal.h2
-rw-r--r--kernel/time/timekeeping.c49
-rw-r--r--kernel/time/timekeeping_internal.h2
-rw-r--r--tools/testing/selftests/timers/clocksource-switch.c2
9 files changed, 121 insertions, 28 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 050d0e77a2cf..b2f6b0463678 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9348,7 +9348,7 @@ M: Andreas Noever <andreas.noever@gmail.com>
9348S: Maintained 9348S: Maintained
9349F: drivers/thunderbolt/ 9349F: drivers/thunderbolt/
9350 9350
9351TIMEKEEPING, CLOCKSOURCE CORE, NTP 9351TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER
9352M: John Stultz <john.stultz@linaro.org> 9352M: John Stultz <john.stultz@linaro.org>
9353M: Thomas Gleixner <tglx@linutronix.de> 9353M: Thomas Gleixner <tglx@linutronix.de>
9354L: linux-kernel@vger.kernel.org 9354L: linux-kernel@vger.kernel.org
@@ -9361,6 +9361,7 @@ F: include/uapi/linux/time.h
9361F: include/uapi/linux/timex.h 9361F: include/uapi/linux/timex.h
9362F: kernel/time/clocksource.c 9362F: kernel/time/clocksource.c
9363F: kernel/time/time*.c 9363F: kernel/time/time*.c
9364F: kernel/time/alarmtimer.c
9364F: kernel/time/ntp.c 9365F: kernel/time/ntp.c
9365F: tools/testing/selftests/timers/ 9366F: tools/testing/selftests/timers/
9366 9367
diff --git a/include/linux/time.h b/include/linux/time.h
index beebe3a02d43..297f09f23896 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -125,6 +125,32 @@ static inline bool timeval_valid(const struct timeval *tv)
125 125
126extern struct timespec timespec_trunc(struct timespec t, unsigned gran); 126extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
127 127
128/*
129 * Validates if a timespec/timeval used to inject a time offset is valid.
130 * Offsets can be postive or negative. The value of the timeval/timespec
131 * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
132 * always be non-negative.
133 */
134static inline bool timeval_inject_offset_valid(const struct timeval *tv)
135{
136 /* We don't check the tv_sec as it can be positive or negative */
137
138 /* Can't have more microseconds then a second */
139 if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
140 return false;
141 return true;
142}
143
144static inline bool timespec_inject_offset_valid(const struct timespec *ts)
145{
146 /* We don't check the tv_sec as it can be positive or negative */
147
148 /* Can't have more nanoseconds then a second */
149 if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
150 return false;
151 return true;
152}
153
128#define CURRENT_TIME (current_kernel_time()) 154#define CURRENT_TIME (current_kernel_time())
129#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 }) 155#define CURRENT_TIME_SEC ((struct timespec) { get_seconds(), 0 })
130 156
diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c
index 7fbba635a549..e840ed867a5d 100644
--- a/kernel/time/alarmtimer.c
+++ b/kernel/time/alarmtimer.c
@@ -271,11 +271,27 @@ static int alarmtimer_suspend(struct device *dev)
271 __pm_wakeup_event(ws, MSEC_PER_SEC); 271 __pm_wakeup_event(ws, MSEC_PER_SEC);
272 return ret; 272 return ret;
273} 273}
274
275static int alarmtimer_resume(struct device *dev)
276{
277 struct rtc_device *rtc;
278
279 rtc = alarmtimer_get_rtcdev();
280 if (rtc)
281 rtc_timer_cancel(rtc, &rtctimer);
282 return 0;
283}
284
274#else 285#else
275static int alarmtimer_suspend(struct device *dev) 286static int alarmtimer_suspend(struct device *dev)
276{ 287{
277 return 0; 288 return 0;
278} 289}
290
291static int alarmtimer_resume(struct device *dev)
292{
293 return 0;
294}
279#endif 295#endif
280 296
281static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) 297static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type)
@@ -800,6 +816,7 @@ out:
800/* Suspend hook structures */ 816/* Suspend hook structures */
801static const struct dev_pm_ops alarmtimer_pm_ops = { 817static const struct dev_pm_ops alarmtimer_pm_ops = {
802 .suspend = alarmtimer_suspend, 818 .suspend = alarmtimer_suspend,
819 .resume = alarmtimer_resume,
803}; 820};
804 821
805static struct platform_driver alarmtimer_driver = { 822static struct platform_driver alarmtimer_driver = {
diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
index 1347882d131e..664de539299b 100644
--- a/kernel/time/clocksource.c
+++ b/kernel/time/clocksource.c
@@ -218,8 +218,8 @@ static void clocksource_watchdog(unsigned long data)
218 218
219 /* Check the deviation from the watchdog clocksource. */ 219 /* Check the deviation from the watchdog clocksource. */
220 if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) { 220 if (abs(cs_nsec - wd_nsec) > WATCHDOG_THRESHOLD) {
221 pr_warn("timekeeping watchdog: Marking clocksource '%s' as unstable because the skew is too large:\n", 221 pr_warn("timekeeping watchdog on CPU%d: Marking clocksource '%s' as unstable because the skew is too large:\n",
222 cs->name); 222 smp_processor_id(), cs->name);
223 pr_warn(" '%s' wd_now: %llx wd_last: %llx mask: %llx\n", 223 pr_warn(" '%s' wd_now: %llx wd_last: %llx mask: %llx\n",
224 watchdog->name, wdnow, wdlast, watchdog->mask); 224 watchdog->name, wdnow, wdlast, watchdog->mask);
225 pr_warn(" '%s' cs_now: %llx cs_last: %llx mask: %llx\n", 225 pr_warn(" '%s' cs_now: %llx cs_last: %llx mask: %llx\n",
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index 149cc8086aea..36f2ca09aa5e 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -16,8 +16,11 @@
16#include <linux/mm.h> 16#include <linux/mm.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/rtc.h> 18#include <linux/rtc.h>
19#include <linux/math64.h>
19 20
20#include "ntp_internal.h" 21#include "ntp_internal.h"
22#include "timekeeping_internal.h"
23
21 24
22/* 25/*
23 * NTP timekeeping variables: 26 * NTP timekeeping variables:
@@ -70,7 +73,7 @@ static long time_esterror = NTP_PHASE_LIMIT;
70static s64 time_freq; 73static s64 time_freq;
71 74
72/* time at last adjustment (secs): */ 75/* time at last adjustment (secs): */
73static long time_reftime; 76static time64_t time_reftime;
74 77
75static long time_adjust; 78static long time_adjust;
76 79
@@ -297,25 +300,27 @@ static void ntp_update_offset(long offset)
297 if (!(time_status & STA_PLL)) 300 if (!(time_status & STA_PLL))
298 return; 301 return;
299 302
300 if (!(time_status & STA_NANO)) 303 if (!(time_status & STA_NANO)) {
304 /* Make sure the multiplication below won't overflow */
305 offset = clamp(offset, -USEC_PER_SEC, USEC_PER_SEC);
301 offset *= NSEC_PER_USEC; 306 offset *= NSEC_PER_USEC;
307 }
302 308
303 /* 309 /*
304 * Scale the phase adjustment and 310 * Scale the phase adjustment and
305 * clamp to the operating range. 311 * clamp to the operating range.
306 */ 312 */
307 offset = min(offset, MAXPHASE); 313 offset = clamp(offset, -MAXPHASE, MAXPHASE);
308 offset = max(offset, -MAXPHASE);
309 314
310 /* 315 /*
311 * Select how the frequency is to be controlled 316 * Select how the frequency is to be controlled
312 * and in which mode (PLL or FLL). 317 * and in which mode (PLL or FLL).
313 */ 318 */
314 secs = get_seconds() - time_reftime; 319 secs = (long)(__ktime_get_real_seconds() - time_reftime);
315 if (unlikely(time_status & STA_FREQHOLD)) 320 if (unlikely(time_status & STA_FREQHOLD))
316 secs = 0; 321 secs = 0;
317 322
318 time_reftime = get_seconds(); 323 time_reftime = __ktime_get_real_seconds();
319 324
320 offset64 = offset; 325 offset64 = offset;
321 freq_adj = ntp_update_offset_fll(offset64, secs); 326 freq_adj = ntp_update_offset_fll(offset64, secs);
@@ -390,10 +395,11 @@ ktime_t ntp_get_next_leap(void)
390 * 395 *
391 * Also handles leap second processing, and returns leap offset 396 * Also handles leap second processing, and returns leap offset
392 */ 397 */
393int second_overflow(unsigned long secs) 398int second_overflow(time64_t secs)
394{ 399{
395 s64 delta; 400 s64 delta;
396 int leap = 0; 401 int leap = 0;
402 s32 rem;
397 403
398 /* 404 /*
399 * Leap second processing. If in leap-insert state at the end of the 405 * Leap second processing. If in leap-insert state at the end of the
@@ -404,19 +410,19 @@ int second_overflow(unsigned long secs)
404 case TIME_OK: 410 case TIME_OK:
405 if (time_status & STA_INS) { 411 if (time_status & STA_INS) {
406 time_state = TIME_INS; 412 time_state = TIME_INS;
407 ntp_next_leap_sec = secs + SECS_PER_DAY - 413 div_s64_rem(secs, SECS_PER_DAY, &rem);
408 (secs % SECS_PER_DAY); 414 ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
409 } else if (time_status & STA_DEL) { 415 } else if (time_status & STA_DEL) {
410 time_state = TIME_DEL; 416 time_state = TIME_DEL;
411 ntp_next_leap_sec = secs + SECS_PER_DAY - 417 div_s64_rem(secs + 1, SECS_PER_DAY, &rem);
412 ((secs+1) % SECS_PER_DAY); 418 ntp_next_leap_sec = secs + SECS_PER_DAY - rem;
413 } 419 }
414 break; 420 break;
415 case TIME_INS: 421 case TIME_INS:
416 if (!(time_status & STA_INS)) { 422 if (!(time_status & STA_INS)) {
417 ntp_next_leap_sec = TIME64_MAX; 423 ntp_next_leap_sec = TIME64_MAX;
418 time_state = TIME_OK; 424 time_state = TIME_OK;
419 } else if (secs % SECS_PER_DAY == 0) { 425 } else if (secs == ntp_next_leap_sec) {
420 leap = -1; 426 leap = -1;
421 time_state = TIME_OOP; 427 time_state = TIME_OOP;
422 printk(KERN_NOTICE 428 printk(KERN_NOTICE
@@ -427,7 +433,7 @@ int second_overflow(unsigned long secs)
427 if (!(time_status & STA_DEL)) { 433 if (!(time_status & STA_DEL)) {
428 ntp_next_leap_sec = TIME64_MAX; 434 ntp_next_leap_sec = TIME64_MAX;
429 time_state = TIME_OK; 435 time_state = TIME_OK;
430 } else if ((secs + 1) % SECS_PER_DAY == 0) { 436 } else if (secs == ntp_next_leap_sec) {
431 leap = 1; 437 leap = 1;
432 ntp_next_leap_sec = TIME64_MAX; 438 ntp_next_leap_sec = TIME64_MAX;
433 time_state = TIME_WAIT; 439 time_state = TIME_WAIT;
@@ -590,7 +596,7 @@ static inline void process_adj_status(struct timex *txc, struct timespec64 *ts)
590 * reference time to current time. 596 * reference time to current time.
591 */ 597 */
592 if (!(time_status & STA_PLL) && (txc->status & STA_PLL)) 598 if (!(time_status & STA_PLL) && (txc->status & STA_PLL))
593 time_reftime = get_seconds(); 599 time_reftime = __ktime_get_real_seconds();
594 600
595 /* only set allowed bits */ 601 /* only set allowed bits */
596 time_status &= STA_RONLY; 602 time_status &= STA_RONLY;
@@ -674,8 +680,14 @@ int ntp_validate_timex(struct timex *txc)
674 return -EINVAL; 680 return -EINVAL;
675 } 681 }
676 682
677 if ((txc->modes & ADJ_SETOFFSET) && (!capable(CAP_SYS_TIME))) 683 if (txc->modes & ADJ_SETOFFSET) {
678 return -EPERM; 684 /* In order to inject time, you gotta be super-user! */
685 if (!capable(CAP_SYS_TIME))
686 return -EPERM;
687
688 if (!timeval_inject_offset_valid(&txc->time))
689 return -EINVAL;
690 }
679 691
680 /* 692 /*
681 * Check for potential multiplication overflows that can 693 * Check for potential multiplication overflows that can
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index af924470eac0..d8a7c11fa71a 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -6,7 +6,7 @@ extern void ntp_clear(void);
6/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */ 6/* Returns how long ticks are at present, in ns / 2^NTP_SCALE_SHIFT. */
7extern u64 ntp_tick_length(void); 7extern u64 ntp_tick_length(void);
8extern ktime_t ntp_get_next_leap(void); 8extern ktime_t ntp_get_next_leap(void);
9extern int second_overflow(unsigned long secs); 9extern int second_overflow(time64_t secs);
10extern int ntp_validate_timex(struct timex *); 10extern int ntp_validate_timex(struct timex *);
11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); 11extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
12extern void __hardpps(const struct timespec64 *, const struct timespec64 *); 12extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index d563c1960302..34b4cedfa80d 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -305,8 +305,7 @@ static inline s64 timekeeping_get_ns(struct tk_read_base *tkr)
305 305
306 delta = timekeeping_get_delta(tkr); 306 delta = timekeeping_get_delta(tkr);
307 307
308 nsec = delta * tkr->mult + tkr->xtime_nsec; 308 nsec = (delta * tkr->mult + tkr->xtime_nsec) >> tkr->shift;
309 nsec >>= tkr->shift;
310 309
311 /* If arch requires, add in get_arch_timeoffset() */ 310 /* If arch requires, add in get_arch_timeoffset() */
312 return nsec + arch_gettimeoffset(); 311 return nsec + arch_gettimeoffset();
@@ -846,6 +845,19 @@ time64_t ktime_get_real_seconds(void)
846} 845}
847EXPORT_SYMBOL_GPL(ktime_get_real_seconds); 846EXPORT_SYMBOL_GPL(ktime_get_real_seconds);
848 847
848/**
849 * __ktime_get_real_seconds - The same as ktime_get_real_seconds
850 * but without the sequence counter protect. This internal function
851 * is called just when timekeeping lock is already held.
852 */
853time64_t __ktime_get_real_seconds(void)
854{
855 struct timekeeper *tk = &tk_core.timekeeper;
856
857 return tk->xtime_sec;
858}
859
860
849#ifdef CONFIG_NTP_PPS 861#ifdef CONFIG_NTP_PPS
850 862
851/** 863/**
@@ -959,7 +971,7 @@ int timekeeping_inject_offset(struct timespec *ts)
959 struct timespec64 ts64, tmp; 971 struct timespec64 ts64, tmp;
960 int ret = 0; 972 int ret = 0;
961 973
962 if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) 974 if (!timespec_inject_offset_valid(ts))
963 return -EINVAL; 975 return -EINVAL;
964 976
965 ts64 = timespec_to_timespec64(*ts); 977 ts64 = timespec_to_timespec64(*ts);
@@ -1592,9 +1604,12 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
1592{ 1604{
1593 s64 interval = tk->cycle_interval; 1605 s64 interval = tk->cycle_interval;
1594 s64 xinterval = tk->xtime_interval; 1606 s64 xinterval = tk->xtime_interval;
1607 u32 base = tk->tkr_mono.clock->mult;
1608 u32 max = tk->tkr_mono.clock->maxadj;
1609 u32 cur_adj = tk->tkr_mono.mult;
1595 s64 tick_error; 1610 s64 tick_error;
1596 bool negative; 1611 bool negative;
1597 u32 adj; 1612 u32 adj_scale;
1598 1613
1599 /* Remove any current error adj from freq calculation */ 1614 /* Remove any current error adj from freq calculation */
1600 if (tk->ntp_err_mult) 1615 if (tk->ntp_err_mult)
@@ -1613,13 +1628,33 @@ static __always_inline void timekeeping_freqadjust(struct timekeeper *tk,
1613 /* preserve the direction of correction */ 1628 /* preserve the direction of correction */
1614 negative = (tick_error < 0); 1629 negative = (tick_error < 0);
1615 1630
1616 /* Sort out the magnitude of the correction */ 1631 /* If any adjustment would pass the max, just return */
1632 if (negative && (cur_adj - 1) <= (base - max))
1633 return;
1634 if (!negative && (cur_adj + 1) >= (base + max))
1635 return;
1636 /*
1637 * Sort out the magnitude of the correction, but
1638 * avoid making so large a correction that we go
1639 * over the max adjustment.
1640 */
1641 adj_scale = 0;
1617 tick_error = abs(tick_error); 1642 tick_error = abs(tick_error);
1618 for (adj = 0; tick_error > interval; adj++) 1643 while (tick_error > interval) {
1644 u32 adj = 1 << (adj_scale + 1);
1645
1646 /* Check if adjustment gets us within 1 unit from the max */
1647 if (negative && (cur_adj - adj) <= (base - max))
1648 break;
1649 if (!negative && (cur_adj + adj) >= (base + max))
1650 break;
1651
1652 adj_scale++;
1619 tick_error >>= 1; 1653 tick_error >>= 1;
1654 }
1620 1655
1621 /* scale the corrections */ 1656 /* scale the corrections */
1622 timekeeping_apply_adjustment(tk, offset, negative, adj); 1657 timekeeping_apply_adjustment(tk, offset, negative, adj_scale);
1623} 1658}
1624 1659
1625/* 1660/*
diff --git a/kernel/time/timekeeping_internal.h b/kernel/time/timekeeping_internal.h
index 4ea005a7f9da..e20466ffc208 100644
--- a/kernel/time/timekeeping_internal.h
+++ b/kernel/time/timekeeping_internal.h
@@ -26,4 +26,6 @@ static inline cycle_t clocksource_delta(cycle_t now, cycle_t last, cycle_t mask)
26} 26}
27#endif 27#endif
28 28
29extern time64_t __ktime_get_real_seconds(void);
30
29#endif /* _TIMEKEEPING_INTERNAL_H */ 31#endif /* _TIMEKEEPING_INTERNAL_H */
diff --git a/tools/testing/selftests/timers/clocksource-switch.c b/tools/testing/selftests/timers/clocksource-switch.c
index 627ec7425f78..fd88e3025bed 100644
--- a/tools/testing/selftests/timers/clocksource-switch.c
+++ b/tools/testing/selftests/timers/clocksource-switch.c
@@ -97,7 +97,7 @@ int get_cur_clocksource(char *buf, size_t size)
97int change_clocksource(char *clocksource) 97int change_clocksource(char *clocksource)
98{ 98{
99 int fd; 99 int fd;
100 size_t size; 100 ssize_t size;
101 101
102 fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY); 102 fd = open("/sys/devices/system/clocksource/clocksource0/current_clocksource", O_WRONLY);
103 103