diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2009-08-14 09:47:31 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2009-08-15 04:55:46 -0400 |
commit | d4f587c67fc39e0030ddd718675e252e208da4d7 (patch) | |
tree | 2222681c57966cc6b8404afdff3ab1a09ac7ea69 /arch | |
parent | 75c5158f70c065b9704b924503d96e8297838f79 (diff) |
timekeeping: Increase granularity of read_persistent_clock()
The persistent clock of some architectures (e.g. s390) have a
better granularity than seconds. To reduce the delta between the
host clock and the guest clock in a virtualized system change the
read_persistent_clock function to return a struct timespec.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Cc: Ingo Molnar <mingo@elte.hu>
Acked-by: John Stultz <johnstul@us.ibm.com>
Cc: Daniel Walker <dwalker@fifo99.com>
LKML-Reference: <20090814134811.013873340@de.ibm.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/m68knommu/kernel/time.c | 5 | ||||
-rw-r--r-- | arch/mips/dec/time.c | 5 | ||||
-rw-r--r-- | arch/mips/lasat/ds1603.c | 5 | ||||
-rw-r--r-- | arch/mips/lasat/sysctl.c | 8 | ||||
-rw-r--r-- | arch/mips/lemote/lm2e/setup.c | 5 | ||||
-rw-r--r-- | arch/mips/mti-malta/malta-time.c | 5 | ||||
-rw-r--r-- | arch/mips/pmc-sierra/yosemite/setup.c | 5 | ||||
-rw-r--r-- | arch/mips/sibyte/swarm/setup.c | 15 | ||||
-rw-r--r-- | arch/mips/sni/time.c | 5 | ||||
-rw-r--r-- | arch/powerpc/kernel/time.c | 7 | ||||
-rw-r--r-- | arch/s390/kernel/time.c | 22 | ||||
-rw-r--r-- | arch/sh/kernel/time.c | 6 | ||||
-rw-r--r-- | arch/x86/kernel/rtc.c | 5 | ||||
-rw-r--r-- | arch/xtensa/kernel/time.c | 5 |
14 files changed, 53 insertions, 50 deletions
diff --git a/arch/m68knommu/kernel/time.c b/arch/m68knommu/kernel/time.c index d182b2f72211..68432248515c 100644 --- a/arch/m68knommu/kernel/time.c +++ b/arch/m68knommu/kernel/time.c | |||
@@ -72,9 +72,10 @@ static unsigned long read_rtc_mmss(void) | |||
72 | return mktime(year, mon, day, hour, min, sec);; | 72 | return mktime(year, mon, day, hour, min, sec);; |
73 | } | 73 | } |
74 | 74 | ||
75 | unsigned long read_persistent_clock(void) | 75 | void read_persistent_clock(struct timespec *ts) |
76 | { | 76 | { |
77 | return read_rtc_mmss(); | 77 | ts->tv_sec = read_rtc_mmss(); |
78 | ts->tv_nsec = 0; | ||
78 | } | 79 | } |
79 | 80 | ||
80 | int update_persistent_clock(struct timespec now) | 81 | int update_persistent_clock(struct timespec now) |
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c index 463136e6685a..02f505f23c32 100644 --- a/arch/mips/dec/time.c +++ b/arch/mips/dec/time.c | |||
@@ -18,7 +18,7 @@ | |||
18 | #include <asm/dec/ioasic.h> | 18 | #include <asm/dec/ioasic.h> |
19 | #include <asm/dec/machtype.h> | 19 | #include <asm/dec/machtype.h> |
20 | 20 | ||
21 | unsigned long read_persistent_clock(void) | 21 | void read_persistent_clock(struct timespec *ts) |
22 | { | 22 | { |
23 | unsigned int year, mon, day, hour, min, sec, real_year; | 23 | unsigned int year, mon, day, hour, min, sec, real_year; |
24 | unsigned long flags; | 24 | unsigned long flags; |
@@ -53,7 +53,8 @@ unsigned long read_persistent_clock(void) | |||
53 | 53 | ||
54 | year += real_year - 72 + 2000; | 54 | year += real_year - 72 + 2000; |
55 | 55 | ||
56 | return mktime(year, mon, day, hour, min, sec); | 56 | ts->tv_sec = mktime(year, mon, day, hour, min, sec); |
57 | ts->tv_nsec = 0; | ||
57 | } | 58 | } |
58 | 59 | ||
59 | /* | 60 | /* |
diff --git a/arch/mips/lasat/ds1603.c b/arch/mips/lasat/ds1603.c index 52cb1436a12a..c6fd96ff118d 100644 --- a/arch/mips/lasat/ds1603.c +++ b/arch/mips/lasat/ds1603.c | |||
@@ -135,7 +135,7 @@ static void rtc_end_op(void) | |||
135 | lasat_ndelay(1000); | 135 | lasat_ndelay(1000); |
136 | } | 136 | } |
137 | 137 | ||
138 | unsigned long read_persistent_clock(void) | 138 | void read_persistent_clock(struct timespec *ts) |
139 | { | 139 | { |
140 | unsigned long word; | 140 | unsigned long word; |
141 | unsigned long flags; | 141 | unsigned long flags; |
@@ -147,7 +147,8 @@ unsigned long read_persistent_clock(void) | |||
147 | rtc_end_op(); | 147 | rtc_end_op(); |
148 | spin_unlock_irqrestore(&rtc_lock, flags); | 148 | spin_unlock_irqrestore(&rtc_lock, flags); |
149 | 149 | ||
150 | return word; | 150 | ts->tv_sec = word; |
151 | ts->tv_nsec = 0; | ||
151 | } | 152 | } |
152 | 153 | ||
153 | int rtc_mips_set_mmss(unsigned long time) | 154 | int rtc_mips_set_mmss(unsigned long time) |
diff --git a/arch/mips/lasat/sysctl.c b/arch/mips/lasat/sysctl.c index 8f88886feb12..3f04d4c406b7 100644 --- a/arch/mips/lasat/sysctl.c +++ b/arch/mips/lasat/sysctl.c | |||
@@ -92,10 +92,12 @@ static int rtctmp; | |||
92 | int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, | 92 | int proc_dolasatrtc(ctl_table *table, int write, struct file *filp, |
93 | void *buffer, size_t *lenp, loff_t *ppos) | 93 | void *buffer, size_t *lenp, loff_t *ppos) |
94 | { | 94 | { |
95 | struct timespec ts; | ||
95 | int r; | 96 | int r; |
96 | 97 | ||
97 | if (!write) { | 98 | if (!write) { |
98 | rtctmp = read_persistent_clock(); | 99 | read_persistent_clock(&ts); |
100 | rtctmp = ts.tv_sec; | ||
99 | /* check for time < 0 and set to 0 */ | 101 | /* check for time < 0 and set to 0 */ |
100 | if (rtctmp < 0) | 102 | if (rtctmp < 0) |
101 | rtctmp = 0; | 103 | rtctmp = 0; |
@@ -134,9 +136,11 @@ int sysctl_lasat_rtc(ctl_table *table, | |||
134 | void *oldval, size_t *oldlenp, | 136 | void *oldval, size_t *oldlenp, |
135 | void *newval, size_t newlen) | 137 | void *newval, size_t newlen) |
136 | { | 138 | { |
139 | struct timespec ts; | ||
137 | int r; | 140 | int r; |
138 | 141 | ||
139 | rtctmp = read_persistent_clock(); | 142 | read_persistent_clock(&ts); |
143 | rtctmp = ts.tv_sec; | ||
140 | if (rtctmp < 0) | 144 | if (rtctmp < 0) |
141 | rtctmp = 0; | 145 | rtctmp = 0; |
142 | r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); | 146 | r = sysctl_intvec(table, oldval, oldlenp, newval, newlen); |
diff --git a/arch/mips/lemote/lm2e/setup.c b/arch/mips/lemote/lm2e/setup.c index ebd6ceaef2fd..24b355df6127 100644 --- a/arch/mips/lemote/lm2e/setup.c +++ b/arch/mips/lemote/lm2e/setup.c | |||
@@ -54,9 +54,10 @@ void __init plat_time_init(void) | |||
54 | mips_hpt_frequency = cpu_clock_freq / 2; | 54 | mips_hpt_frequency = cpu_clock_freq / 2; |
55 | } | 55 | } |
56 | 56 | ||
57 | unsigned long read_persistent_clock(void) | 57 | void read_persistent_clock(struct timespec *ts) |
58 | { | 58 | { |
59 | return mc146818_get_cmos_time(); | 59 | ts->tv_sec = mc146818_get_cmos_time(); |
60 | ts->tv_nsec = 0; | ||
60 | } | 61 | } |
61 | 62 | ||
62 | void (*__wbflush)(void); | 63 | void (*__wbflush)(void); |
diff --git a/arch/mips/mti-malta/malta-time.c b/arch/mips/mti-malta/malta-time.c index 0b97d47691fc..3c6f190aa61c 100644 --- a/arch/mips/mti-malta/malta-time.c +++ b/arch/mips/mti-malta/malta-time.c | |||
@@ -100,9 +100,10 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
100 | return count; | 100 | return count; |
101 | } | 101 | } |
102 | 102 | ||
103 | unsigned long read_persistent_clock(void) | 103 | void read_persistent_clock(struct timespec *ts) |
104 | { | 104 | { |
105 | return mc146818_get_cmos_time(); | 105 | ts->tv_sec = mc146818_get_cmos_time(); |
106 | ts->tv_nsec = 0; | ||
106 | } | 107 | } |
107 | 108 | ||
108 | static void __init plat_perf_setup(void) | 109 | static void __init plat_perf_setup(void) |
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 2d3c0dca275d..3498ac9c35af 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c | |||
@@ -70,7 +70,7 @@ void __init bus_error_init(void) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | 72 | ||
73 | unsigned long read_persistent_clock(void) | 73 | void read_persistent_clock(struct timespec *ts) |
74 | { | 74 | { |
75 | unsigned int year, month, day, hour, min, sec; | 75 | unsigned int year, month, day, hour, min, sec; |
76 | unsigned long flags; | 76 | unsigned long flags; |
@@ -92,7 +92,8 @@ unsigned long read_persistent_clock(void) | |||
92 | m48t37_base->control = 0x00; | 92 | m48t37_base->control = 0x00; |
93 | spin_unlock_irqrestore(&rtc_lock, flags); | 93 | spin_unlock_irqrestore(&rtc_lock, flags); |
94 | 94 | ||
95 | return mktime(year, month, day, hour, min, sec); | 95 | ts->tv_sec = mktime(year, month, day, hour, min, sec); |
96 | ts->tv_nsec = 0; | ||
96 | } | 97 | } |
97 | 98 | ||
98 | int rtc_mips_set_time(unsigned long tim) | 99 | int rtc_mips_set_time(unsigned long tim) |
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c index 672e45d495a9..623ffc933c4c 100644 --- a/arch/mips/sibyte/swarm/setup.c +++ b/arch/mips/sibyte/swarm/setup.c | |||
@@ -87,19 +87,26 @@ enum swarm_rtc_type { | |||
87 | 87 | ||
88 | enum swarm_rtc_type swarm_rtc_type; | 88 | enum swarm_rtc_type swarm_rtc_type; |
89 | 89 | ||
90 | unsigned long read_persistent_clock(void) | 90 | void read_persistent_clock(struct timespec *ts) |
91 | { | 91 | { |
92 | unsigned long sec; | ||
93 | |||
92 | switch (swarm_rtc_type) { | 94 | switch (swarm_rtc_type) { |
93 | case RTC_XICOR: | 95 | case RTC_XICOR: |
94 | return xicor_get_time(); | 96 | sec = xicor_get_time(); |
97 | break; | ||
95 | 98 | ||
96 | case RTC_M4LT81: | 99 | case RTC_M4LT81: |
97 | return m41t81_get_time(); | 100 | sec = m41t81_get_time(); |
101 | break; | ||
98 | 102 | ||
99 | case RTC_NONE: | 103 | case RTC_NONE: |
100 | default: | 104 | default: |
101 | return mktime(2000, 1, 1, 0, 0, 0); | 105 | sec = mktime(2000, 1, 1, 0, 0, 0); |
106 | break; | ||
102 | } | 107 | } |
108 | ts->tv_sec = sec; | ||
109 | tv->tv_nsec = 0; | ||
103 | } | 110 | } |
104 | 111 | ||
105 | int rtc_mips_set_time(unsigned long sec) | 112 | int rtc_mips_set_time(unsigned long sec) |
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c index 0d9ec1a5c24a..62df6a598e0a 100644 --- a/arch/mips/sni/time.c +++ b/arch/mips/sni/time.c | |||
@@ -182,7 +182,8 @@ void __init plat_time_init(void) | |||
182 | setup_pit_timer(); | 182 | setup_pit_timer(); |
183 | } | 183 | } |
184 | 184 | ||
185 | unsigned long read_persistent_clock(void) | 185 | void read_persistent_clock(struct timespec *ts) |
186 | { | 186 | { |
187 | return -1; | 187 | ts->tv_sec = -1; |
188 | ts->tv_nsec = 0; | ||
188 | } | 189 | } |
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index eae4511ceeac..ad63f30fe3da 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c | |||
@@ -769,7 +769,7 @@ int update_persistent_clock(struct timespec now) | |||
769 | return ppc_md.set_rtc_time(&tm); | 769 | return ppc_md.set_rtc_time(&tm); |
770 | } | 770 | } |
771 | 771 | ||
772 | unsigned long read_persistent_clock(void) | 772 | void read_persistent_clock(struct timespec *ts) |
773 | { | 773 | { |
774 | struct rtc_time tm; | 774 | struct rtc_time tm; |
775 | static int first = 1; | 775 | static int first = 1; |
@@ -787,8 +787,9 @@ unsigned long read_persistent_clock(void) | |||
787 | if (!ppc_md.get_rtc_time) | 787 | if (!ppc_md.get_rtc_time) |
788 | return 0; | 788 | return 0; |
789 | ppc_md.get_rtc_time(&tm); | 789 | ppc_md.get_rtc_time(&tm); |
790 | return mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, | 790 | ts->tv_sec = mktime(tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, |
791 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 791 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
792 | ts->tv_nsec = 0; | ||
792 | } | 793 | } |
793 | 794 | ||
794 | /* clocksource code */ | 795 | /* clocksource code */ |
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c index e76c2e7a8b9a..a94ec48587b4 100644 --- a/arch/s390/kernel/time.c +++ b/arch/s390/kernel/time.c | |||
@@ -182,12 +182,9 @@ static void timing_alert_interrupt(__u16 code) | |||
182 | static void etr_reset(void); | 182 | static void etr_reset(void); |
183 | static void stp_reset(void); | 183 | static void stp_reset(void); |
184 | 184 | ||
185 | unsigned long read_persistent_clock(void) | 185 | void read_persistent_clock(struct timespec *ts) |
186 | { | 186 | { |
187 | struct timespec ts; | 187 | tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, ts); |
188 | |||
189 | tod_to_timeval(get_clock() - TOD_UNIX_EPOCH, &ts); | ||
190 | return ts.tv_sec; | ||
191 | } | 188 | } |
192 | 189 | ||
193 | static cycle_t read_tod_clock(struct clocksource *cs) | 190 | static cycle_t read_tod_clock(struct clocksource *cs) |
@@ -248,7 +245,6 @@ void __init time_init(void) | |||
248 | { | 245 | { |
249 | struct timespec ts; | 246 | struct timespec ts; |
250 | unsigned long flags; | 247 | unsigned long flags; |
251 | cycle_t now; | ||
252 | 248 | ||
253 | /* Reset time synchronization interfaces. */ | 249 | /* Reset time synchronization interfaces. */ |
254 | etr_reset(); | 250 | etr_reset(); |
@@ -266,20 +262,10 @@ void __init time_init(void) | |||
266 | panic("Could not register TOD clock source"); | 262 | panic("Could not register TOD clock source"); |
267 | 263 | ||
268 | /* | 264 | /* |
269 | * The TOD clock is an accurate clock. The xtime should be | 265 | * Reset wall_to_monotonic to the initial timestamp created |
270 | * initialized in a way that the difference between TOD and | 266 | * in head.S to get a precise value in /proc/uptime. |
271 | * xtime is reasonably small. Too bad that timekeeping_init | ||
272 | * sets xtime.tv_nsec to zero. In addition the clock source | ||
273 | * change from the jiffies clock source to the TOD clock | ||
274 | * source add another error of up to 1/HZ second. The same | ||
275 | * function sets wall_to_monotonic to a value that is too | ||
276 | * small for /proc/uptime to be accurate. | ||
277 | * Reset xtime and wall_to_monotonic to sane values. | ||
278 | */ | 267 | */ |
279 | write_seqlock_irqsave(&xtime_lock, flags); | 268 | write_seqlock_irqsave(&xtime_lock, flags); |
280 | now = get_clock(); | ||
281 | tod_to_timeval(now - TOD_UNIX_EPOCH, &xtime); | ||
282 | clocksource_tod.cycle_last = now; | ||
283 | tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts); | 269 | tod_to_timeval(sched_clock_base_cc - TOD_UNIX_EPOCH, &ts); |
284 | set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec); | 270 | set_normalized_timespec(&wall_to_monotonic, -ts.tv_sec, -ts.tv_nsec); |
285 | write_sequnlock_irqrestore(&xtime_lock, flags); | 271 | write_sequnlock_irqrestore(&xtime_lock, flags); |
diff --git a/arch/sh/kernel/time.c b/arch/sh/kernel/time.c index 9b352a1e3fb4..3f4706aa975e 100644 --- a/arch/sh/kernel/time.c +++ b/arch/sh/kernel/time.c | |||
@@ -39,11 +39,9 @@ void (*rtc_sh_get_time)(struct timespec *) = null_rtc_get_time; | |||
39 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; | 39 | int (*rtc_sh_set_time)(const time_t) = null_rtc_set_time; |
40 | 40 | ||
41 | #ifdef CONFIG_GENERIC_CMOS_UPDATE | 41 | #ifdef CONFIG_GENERIC_CMOS_UPDATE |
42 | unsigned long read_persistent_clock(void) | 42 | void read_persistent_clock(struct timespec *ts) |
43 | { | 43 | { |
44 | struct timespec tv; | 44 | rtc_sh_get_time(&ts); |
45 | rtc_sh_get_time(&tv); | ||
46 | return tv.tv_sec; | ||
47 | } | 45 | } |
48 | 46 | ||
49 | int update_persistent_clock(struct timespec now) | 47 | int update_persistent_clock(struct timespec now) |
diff --git a/arch/x86/kernel/rtc.c b/arch/x86/kernel/rtc.c index 5d465b207e72..bf67dcb4a44c 100644 --- a/arch/x86/kernel/rtc.c +++ b/arch/x86/kernel/rtc.c | |||
@@ -178,7 +178,7 @@ static int set_rtc_mmss(unsigned long nowtime) | |||
178 | } | 178 | } |
179 | 179 | ||
180 | /* not static: needed by APM */ | 180 | /* not static: needed by APM */ |
181 | unsigned long read_persistent_clock(void) | 181 | void read_persistent_clock(struct timespec *ts) |
182 | { | 182 | { |
183 | unsigned long retval, flags; | 183 | unsigned long retval, flags; |
184 | 184 | ||
@@ -186,7 +186,8 @@ unsigned long read_persistent_clock(void) | |||
186 | retval = get_wallclock(); | 186 | retval = get_wallclock(); |
187 | spin_unlock_irqrestore(&rtc_lock, flags); | 187 | spin_unlock_irqrestore(&rtc_lock, flags); |
188 | 188 | ||
189 | return retval; | 189 | ts->tv_sec = retval; |
190 | ts->tv_nsec = 0; | ||
190 | } | 191 | } |
191 | 192 | ||
192 | int update_persistent_clock(struct timespec now) | 193 | int update_persistent_clock(struct timespec now) |
diff --git a/arch/xtensa/kernel/time.c b/arch/xtensa/kernel/time.c index 8848120d291b..19085ff0484a 100644 --- a/arch/xtensa/kernel/time.c +++ b/arch/xtensa/kernel/time.c | |||
@@ -59,9 +59,8 @@ static struct irqaction timer_irqaction = { | |||
59 | 59 | ||
60 | void __init time_init(void) | 60 | void __init time_init(void) |
61 | { | 61 | { |
62 | xtime.tv_nsec = 0; | 62 | /* FIXME: xtime&wall_to_monotonic are set in timekeeping_init. */ |
63 | xtime.tv_sec = read_persistent_clock(); | 63 | read_persistent_clock(&xtime); |
64 | |||
65 | set_normalized_timespec(&wall_to_monotonic, | 64 | set_normalized_timespec(&wall_to_monotonic, |
66 | -xtime.tv_sec, -xtime.tv_nsec); | 65 | -xtime.tv_sec, -xtime.tv_nsec); |
67 | 66 | ||