Commit 90889a635a9b5488624bccce3ff6b2eec68c007b

Authored by Thomas Gleixner

Merge branch 'fortglx/3.9/time' of git://git.linaro.org/people/jstultz/linux into timers/core

Trivial conflict in arch/x86/Kconfig

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>

Showing 15 changed files Side-by-side Diff

... ... @@ -6598,7 +6598,7 @@
6598 6598 F: drivers/dma/dw_dmac.c
6599 6599  
6600 6600 TIMEKEEPING, NTP
6601   -M: John Stultz <johnstul@us.ibm.com>
  6601 +M: John Stultz <john.stultz@linaro.org>
6602 6602 M: Thomas Gleixner <tglx@linutronix.de>
6603 6603 T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git timers/core
6604 6604 S: Supported
arch/powerpc/kernel/time.c
... ... @@ -668,7 +668,7 @@
668 668 struct rtc_time tm;
669 669  
670 670 if (!ppc_md.set_rtc_time)
671   - return 0;
  671 + return -ENODEV;
672 672  
673 673 to_tm(now.tv_sec + 1 + timezone_offset, &tm);
674 674 tm.tm_year -= 1900;
... ... @@ -106,6 +106,7 @@
106 106 select GENERIC_CLOCKEVENTS_BROADCAST if X86_64 || (X86_32 && X86_LOCAL_APIC)
107 107 select GENERIC_TIME_VSYSCALL if X86_64
108 108 select KTIME_SCALAR if X86_32
  109 + select ALWAYS_USE_PERSISTENT_CLOCK
109 110 select GENERIC_STRNCPY_FROM_USER
110 111 select GENERIC_STRNLEN_USER
111 112 select HAVE_CONTEXT_TRACKING if X86_64
arch/x86/kernel/tsc.c
... ... @@ -623,7 +623,8 @@
623 623 ns_now = __cycles_2_ns(tsc_now);
624 624  
625 625 if (cpu_khz) {
626   - *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz;
  626 + *scale = ((NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR) +
  627 + cpu_khz / 2) / cpu_khz;
627 628 *offset = ns_now - mult_frac(tsc_now, *scale,
628 629 (1UL << CYC2NS_SCALE_FACTOR));
629 630 }
... ... @@ -20,14 +20,24 @@
20 20 config RTC_HCTOSYS
21 21 bool "Set system time from RTC on startup and resume"
22 22 default y
  23 + depends on !ALWAYS_USE_PERSISTENT_CLOCK
23 24 help
24 25 If you say yes here, the system time (wall clock) will be set using
25 26 the value read from a specified RTC device. This is useful to avoid
26 27 unnecessary fsck runs at boot time, and to network better.
27 28  
  29 +config RTC_SYSTOHC
  30 + bool "Set the RTC time based on NTP synchronization"
  31 + default y
  32 + depends on !ALWAYS_USE_PERSISTENT_CLOCK
  33 + help
  34 + If you say yes here, the system time (wall clock) will be stored
  35 + in the RTC specified by RTC_HCTOSYS_DEVICE approximately every 11
  36 + minutes if userspace reports synchronized NTP status.
  37 +
28 38 config RTC_HCTOSYS_DEVICE
29 39 string "RTC used to set the system time"
30   - depends on RTC_HCTOSYS = y
  40 + depends on RTC_HCTOSYS = y || RTC_SYSTOHC = y
31 41 default "rtc0"
32 42 help
33 43 The RTC device that will be used to (re)initialize the system
drivers/rtc/Makefile
... ... @@ -6,6 +6,7 @@
6 6  
7 7 obj-$(CONFIG_RTC_LIB) += rtc-lib.o
8 8 obj-$(CONFIG_RTC_HCTOSYS) += hctosys.o
  9 +obj-$(CONFIG_RTC_SYSTOHC) += systohc.o
9 10 obj-$(CONFIG_RTC_CLASS) += rtc-core.o
10 11 rtc-core-y := class.o interface.o
11 12  
... ... @@ -50,6 +50,10 @@
50 50 struct rtc_device *rtc = to_rtc_device(dev);
51 51 struct rtc_time tm;
52 52 struct timespec delta, delta_delta;
  53 +
  54 + if (has_persistent_clock())
  55 + return 0;
  56 +
53 57 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
54 58 return 0;
55 59  
... ... @@ -87,6 +91,9 @@
87 91 struct rtc_time tm;
88 92 struct timespec new_system, new_rtc;
89 93 struct timespec sleep_time;
  94 +
  95 + if (has_persistent_clock())
  96 + return 0;
90 97  
91 98 rtc_hctosys_ret = -ENODEV;
92 99 if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
drivers/rtc/systohc.c
  1 +/*
  2 + * This program is free software; you can redistribute it and/or modify it
  3 + * under the terms of the GNU General Public License version 2 as published by
  4 + * the Free Software Foundation.
  5 + *
  6 + */
  7 +#include <linux/rtc.h>
  8 +#include <linux/time.h>
  9 +
  10 +/**
  11 + * rtc_set_ntp_time - Save NTP synchronized time to the RTC
  12 + * @now: Current time of day
  13 + *
  14 + * Replacement for the NTP platform function update_persistent_clock
  15 + * that stores time for later retrieval by rtc_hctosys.
  16 + *
  17 + * Returns 0 on successful RTC update, -ENODEV if a RTC update is not
  18 + * possible at all, and various other -errno for specific temporary failure
  19 + * cases.
  20 + *
  21 + * If temporary failure is indicated the caller should try again 'soon'
  22 + */
  23 +int rtc_set_ntp_time(struct timespec now)
  24 +{
  25 + struct rtc_device *rtc;
  26 + struct rtc_time tm;
  27 + int err = -ENODEV;
  28 +
  29 + if (now.tv_nsec < (NSEC_PER_SEC >> 1))
  30 + rtc_time_to_tm(now.tv_sec, &tm);
  31 + else
  32 + rtc_time_to_tm(now.tv_sec + 1, &tm);
  33 +
  34 + rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
  35 + if (rtc) {
  36 + /* rtc_hctosys exclusively uses UTC, so we call set_time here,
  37 + * not set_mmss. */
  38 + if (rtc->ops && (rtc->ops->set_time || rtc->ops->set_mmss))
  39 + err = rtc_set_time(rtc, &tm);
  40 + rtc_class_close(rtc);
  41 + }
  42 +
  43 + return err;
  44 +}
... ... @@ -167,12 +167,16 @@
167 167 static size_t ramoops_write_kmsg_hdr(struct persistent_ram_zone *prz)
168 168 {
169 169 char *hdr;
170   - struct timeval timestamp;
  170 + struct timespec timestamp;
171 171 size_t len;
172 172  
173   - do_gettimeofday(&timestamp);
  173 + /* Report zeroed timestamp if called before timekeeping has resumed. */
  174 + if (__getnstimeofday(&timestamp)) {
  175 + timestamp.tv_sec = 0;
  176 + timestamp.tv_nsec = 0;
  177 + }
174 178 hdr = kasprintf(GFP_ATOMIC, RAMOOPS_KERNMSG_HDR "%lu.%lu\n",
175   - (long)timestamp.tv_sec, (long)timestamp.tv_usec);
  179 + (long)timestamp.tv_sec, (long)(timestamp.tv_nsec / 1000));
176 180 WARN_ON_ONCE(!hdr);
177 181 len = hdr ? strlen(hdr) : 0;
178 182 persistent_ram_write(prz, hdr, len);
... ... @@ -138,6 +138,7 @@
138 138 extern int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm);
139 139 extern int rtc_set_time(struct rtc_device *rtc, struct rtc_time *tm);
140 140 extern int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs);
  141 +extern int rtc_set_ntp_time(struct timespec now);
141 142 int __rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm);
142 143 extern int rtc_read_alarm(struct rtc_device *rtc,
143 144 struct rtc_wkalrm *alrm);
include/linux/time.h
... ... @@ -115,6 +115,17 @@
115 115 return true;
116 116 }
117 117  
  118 +extern bool persistent_clock_exist;
  119 +
  120 +#ifdef ALWAYS_USE_PERSISTENT_CLOCK
  121 +#define has_persistent_clock() true
  122 +#else
  123 +static inline bool has_persistent_clock(void)
  124 +{
  125 + return persistent_clock_exist;
  126 +}
  127 +#endif
  128 +
118 129 extern void read_persistent_clock(struct timespec *ts);
119 130 extern void read_boot_clock(struct timespec *ts);
120 131 extern int update_persistent_clock(struct timespec now);
... ... @@ -158,6 +169,7 @@
158 169 struct itimerval *ovalue);
159 170 extern unsigned int alarm_setitimer(unsigned int seconds);
160 171 extern int do_getitimer(int which, struct itimerval *value);
  172 +extern int __getnstimeofday(struct timespec *tv);
161 173 extern void getnstimeofday(struct timespec *tv);
162 174 extern void getrawmonotonic(struct timespec *ts);
163 175 extern void getnstime_raw_and_real(struct timespec *ts_raw,
kernel/posix-timers.c
... ... @@ -997,7 +997,7 @@
997 997  
998 998 err = kc->clock_adj(which_clock, &ktx);
999 999  
1000   - if (!err && copy_to_user(utx, &ktx, sizeof(ktx)))
  1000 + if (err >= 0 && copy_to_user(utx, &ktx, sizeof(ktx)))
1001 1001 return -EFAULT;
1002 1002  
1003 1003 return err;
... ... @@ -12,6 +12,11 @@
12 12 config ARCH_CLOCKSOURCE_DATA
13 13 bool
14 14  
  15 +# Platforms has a persistent clock
  16 +config ALWAYS_USE_PERSISTENT_CLOCK
  17 + bool
  18 + default n
  19 +
15 20 # Timekeeping vsyscall support
16 21 config GENERIC_TIME_VSYSCALL
17 22 bool
... ... @@ -15,6 +15,7 @@
15 15 #include <linux/time.h>
16 16 #include <linux/mm.h>
17 17 #include <linux/module.h>
  18 +#include <linux/rtc.h>
18 19  
19 20 #include "tick-internal.h"
20 21  
... ... @@ -483,8 +484,7 @@
483 484 return leap;
484 485 }
485 486  
486   -#ifdef CONFIG_GENERIC_CMOS_UPDATE
487   -
  487 +#if defined(CONFIG_GENERIC_CMOS_UPDATE) || defined(CONFIG_RTC_SYSTOHC)
488 488 static void sync_cmos_clock(struct work_struct *work);
489 489  
490 490 static DECLARE_DELAYED_WORK(sync_cmos_work, sync_cmos_clock);
491 491  
492 492  
... ... @@ -510,14 +510,22 @@
510 510 }
511 511  
512 512 getnstimeofday(&now);
513   - if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2)
  513 + if (abs(now.tv_nsec - (NSEC_PER_SEC / 2)) <= tick_nsec / 2) {
  514 + fail = -ENODEV;
  515 +#ifdef CONFIG_GENERIC_CMOS_UPDATE
514 516 fail = update_persistent_clock(now);
  517 +#endif
  518 +#ifdef CONFIG_RTC_SYSTOHC
  519 + if (fail == -ENODEV)
  520 + fail = rtc_set_ntp_time(now);
  521 +#endif
  522 + }
515 523  
516 524 next.tv_nsec = (NSEC_PER_SEC / 2) - now.tv_nsec - (TICK_NSEC / 2);
517 525 if (next.tv_nsec <= 0)
518 526 next.tv_nsec += NSEC_PER_SEC;
519 527  
520   - if (!fail)
  528 + if (!fail || fail == -ENODEV)
521 529 next.tv_sec = 659;
522 530 else
523 531 next.tv_sec = 0;
kernel/time/timekeeping.c
... ... @@ -29,6 +29,9 @@
29 29 /* flag for if timekeeping is suspended */
30 30 int __read_mostly timekeeping_suspended;
31 31  
  32 +/* Flag for if there is a persistent clock on this platform */
  33 +bool __read_mostly persistent_clock_exist = false;
  34 +
32 35 static inline void tk_normalize_xtime(struct timekeeper *tk)
33 36 {
34 37 while (tk->xtime_nsec >= ((u64)NSEC_PER_SEC << tk->shift)) {
35 38  
36 39  
37 40  
... ... @@ -264,19 +267,18 @@
264 267 }
265 268  
266 269 /**
267   - * getnstimeofday - Returns the time of day in a timespec
  270 + * __getnstimeofday - Returns the time of day in a timespec.
268 271 * @ts: pointer to the timespec to be set
269 272 *
270   - * Returns the time of day in a timespec.
  273 + * Updates the time of day in the timespec.
  274 + * Returns 0 on success, or -ve when suspended (timespec will be undefined).
271 275 */
272   -void getnstimeofday(struct timespec *ts)
  276 +int __getnstimeofday(struct timespec *ts)
273 277 {
274 278 struct timekeeper *tk = &timekeeper;
275 279 unsigned long seq;
276 280 s64 nsecs = 0;
277 281  
278   - WARN_ON(timekeeping_suspended);
279   -
280 282 do {
281 283 seq = read_seqbegin(&tk->lock);
282 284  
283 285  
... ... @@ -287,7 +289,27 @@
287 289  
288 290 ts->tv_nsec = 0;
289 291 timespec_add_ns(ts, nsecs);
  292 +
  293 + /*
  294 + * Do not bail out early, in case there were callers still using
  295 + * the value, even in the face of the WARN_ON.
  296 + */
  297 + if (unlikely(timekeeping_suspended))
  298 + return -EAGAIN;
  299 + return 0;
290 300 }
  301 +EXPORT_SYMBOL(__getnstimeofday);
  302 +
  303 +/**
  304 + * getnstimeofday - Returns the time of day in a timespec.
  305 + * @ts: pointer to the timespec to be set
  306 + *
  307 + * Returns the time of day in a timespec (WARN if suspended).
  308 + */
  309 +void getnstimeofday(struct timespec *ts)
  310 +{
  311 + WARN_ON(__getnstimeofday(ts));
  312 +}
291 313 EXPORT_SYMBOL(getnstimeofday);
292 314  
293 315 ktime_t ktime_get(void)
294 316  
... ... @@ -640,12 +662,14 @@
640 662 struct timespec now, boot, tmp;
641 663  
642 664 read_persistent_clock(&now);
  665 +
643 666 if (!timespec_valid_strict(&now)) {
644 667 pr_warn("WARNING: Persistent clock returned invalid value!\n"
645 668 " Check your CMOS/BIOS settings.\n");
646 669 now.tv_sec = 0;
647 670 now.tv_nsec = 0;
648   - }
  671 + } else if (now.tv_sec || now.tv_nsec)
  672 + persistent_clock_exist = true;
649 673  
650 674 read_boot_clock(&boot);
651 675 if (!timespec_valid_strict(&boot)) {
652 676  
... ... @@ -718,11 +742,12 @@
718 742 {
719 743 struct timekeeper *tk = &timekeeper;
720 744 unsigned long flags;
721   - struct timespec ts;
722 745  
723   - /* Make sure we don't set the clock twice */
724   - read_persistent_clock(&ts);
725   - if (!(ts.tv_sec == 0 && ts.tv_nsec == 0))
  746 + /*
  747 + * Make sure we don't set the clock twice, as timekeeping_resume()
  748 + * already did it
  749 + */
  750 + if (has_persistent_clock())
726 751 return;
727 752  
728 753 write_seqlock_irqsave(&tk->lock, flags);