diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2015-12-19 06:03:17 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2015-12-19 06:03:17 -0500 |
commit | e2666d69068aba300d6c0dfe96489552f653be2a (patch) | |
tree | 07fa371d800deec45225589ebe6154dcc6c956b2 | |
parent | d33f250af4e67d449f2c748b861ba99d50955469 (diff) | |
parent | ec02b076ceab63f99e5b3d80fd223d777266c236 (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-- | MAINTAINERS | 3 | ||||
-rw-r--r-- | include/linux/time.h | 26 | ||||
-rw-r--r-- | kernel/time/alarmtimer.c | 17 | ||||
-rw-r--r-- | kernel/time/clocksource.c | 4 | ||||
-rw-r--r-- | kernel/time/ntp.c | 44 | ||||
-rw-r--r-- | kernel/time/ntp_internal.h | 2 | ||||
-rw-r--r-- | kernel/time/timekeeping.c | 49 | ||||
-rw-r--r-- | kernel/time/timekeeping_internal.h | 2 | ||||
-rw-r--r-- | tools/testing/selftests/timers/clocksource-switch.c | 2 |
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> | |||
9348 | S: Maintained | 9348 | S: Maintained |
9349 | F: drivers/thunderbolt/ | 9349 | F: drivers/thunderbolt/ |
9350 | 9350 | ||
9351 | TIMEKEEPING, CLOCKSOURCE CORE, NTP | 9351 | TIMEKEEPING, CLOCKSOURCE CORE, NTP, ALARMTIMER |
9352 | M: John Stultz <john.stultz@linaro.org> | 9352 | M: John Stultz <john.stultz@linaro.org> |
9353 | M: Thomas Gleixner <tglx@linutronix.de> | 9353 | M: Thomas Gleixner <tglx@linutronix.de> |
9354 | L: linux-kernel@vger.kernel.org | 9354 | L: linux-kernel@vger.kernel.org |
@@ -9361,6 +9361,7 @@ F: include/uapi/linux/time.h | |||
9361 | F: include/uapi/linux/timex.h | 9361 | F: include/uapi/linux/timex.h |
9362 | F: kernel/time/clocksource.c | 9362 | F: kernel/time/clocksource.c |
9363 | F: kernel/time/time*.c | 9363 | F: kernel/time/time*.c |
9364 | F: kernel/time/alarmtimer.c | ||
9364 | F: kernel/time/ntp.c | 9365 | F: kernel/time/ntp.c |
9365 | F: tools/testing/selftests/timers/ | 9366 | F: 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 | ||
126 | extern struct timespec timespec_trunc(struct timespec t, unsigned gran); | 126 | extern 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 | */ | ||
134 | static 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 | |||
144 | static 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 | |||
275 | static 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 |
275 | static int alarmtimer_suspend(struct device *dev) | 286 | static int alarmtimer_suspend(struct device *dev) |
276 | { | 287 | { |
277 | return 0; | 288 | return 0; |
278 | } | 289 | } |
290 | |||
291 | static int alarmtimer_resume(struct device *dev) | ||
292 | { | ||
293 | return 0; | ||
294 | } | ||
279 | #endif | 295 | #endif |
280 | 296 | ||
281 | static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) | 297 | static void alarmtimer_freezerset(ktime_t absexp, enum alarmtimer_type type) |
@@ -800,6 +816,7 @@ out: | |||
800 | /* Suspend hook structures */ | 816 | /* Suspend hook structures */ |
801 | static const struct dev_pm_ops alarmtimer_pm_ops = { | 817 | static const struct dev_pm_ops alarmtimer_pm_ops = { |
802 | .suspend = alarmtimer_suspend, | 818 | .suspend = alarmtimer_suspend, |
819 | .resume = alarmtimer_resume, | ||
803 | }; | 820 | }; |
804 | 821 | ||
805 | static struct platform_driver alarmtimer_driver = { | 822 | static 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; | |||
70 | static s64 time_freq; | 73 | static s64 time_freq; |
71 | 74 | ||
72 | /* time at last adjustment (secs): */ | 75 | /* time at last adjustment (secs): */ |
73 | static long time_reftime; | 76 | static time64_t time_reftime; |
74 | 77 | ||
75 | static long time_adjust; | 78 | static 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 | */ |
393 | int second_overflow(unsigned long secs) | 398 | int 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. */ |
7 | extern u64 ntp_tick_length(void); | 7 | extern u64 ntp_tick_length(void); |
8 | extern ktime_t ntp_get_next_leap(void); | 8 | extern ktime_t ntp_get_next_leap(void); |
9 | extern int second_overflow(unsigned long secs); | 9 | extern int second_overflow(time64_t secs); |
10 | extern int ntp_validate_timex(struct timex *); | 10 | extern int ntp_validate_timex(struct timex *); |
11 | extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); | 11 | extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *); |
12 | extern void __hardpps(const struct timespec64 *, const struct timespec64 *); | 12 | extern 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 | } |
847 | EXPORT_SYMBOL_GPL(ktime_get_real_seconds); | 846 | EXPORT_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 | */ | ||
853 | time64_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 | ||
29 | extern 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) | |||
97 | int change_clocksource(char *clocksource) | 97 | int 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 | ||