Commit b7ec15bd004f4524bf091f851348da2ccb519e4f
Committed by
Linus Torvalds
1 parent
83ff7df5f1
Exists in
master
and in
20 other branches
uml: virtualized time fix
With the current timekeeping, !CONFIG_UML_REAL_TIME_CLOCK has inconsistent behavior. Previously, gettimeofday could be (and was) isolated from the clock ticking. Now, it's not, so when CONFIG_UML_REAL_TIME_CLOCK is disabled, gettimeofday must progress in lockstep with the clock, making it fully virtual. Signed-off-by: Jeff Dike <jdike@linux.intel.com> Cc: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 12 additions and 2 deletions Side-by-side Diff
arch/um/kernel/time.c
... | ... | @@ -34,8 +34,8 @@ |
34 | 34 | return (unsigned long long)jiffies_64 * (1000000000 / HZ); |
35 | 35 | } |
36 | 36 | |
37 | -static unsigned long long prev_nsecs[NR_CPUS]; | |
38 | 37 | #ifdef CONFIG_UML_REAL_TIME_CLOCK |
38 | +static unsigned long long prev_nsecs[NR_CPUS]; | |
39 | 39 | static long long delta[NR_CPUS]; /* Deviation per interval */ |
40 | 40 | #endif |
41 | 41 | |
42 | 42 | |
... | ... | @@ -94,7 +94,12 @@ |
94 | 94 | |
95 | 95 | do_timer(1); |
96 | 96 | |
97 | +#ifdef CONFIG_UML_REAL_TIME_CLOCK | |
97 | 98 | nsecs = get_time(); |
99 | +#else | |
100 | + nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec + | |
101 | + BILLION / HZ; | |
102 | +#endif | |
98 | 103 | xtime.tv_sec = nsecs / NSEC_PER_SEC; |
99 | 104 | xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC; |
100 | 105 | |
101 | 106 | |
102 | 107 | |
... | ... | @@ -127,13 +132,18 @@ |
127 | 132 | nsecs = os_nsecs(); |
128 | 133 | set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION, |
129 | 134 | -nsecs % BILLION); |
135 | + set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION); | |
130 | 136 | late_time_init = register_timer; |
131 | 137 | } |
132 | 138 | |
133 | 139 | void do_gettimeofday(struct timeval *tv) |
134 | 140 | { |
141 | +#ifdef CONFIG_UML_REAL_TIME_CLOCK | |
135 | 142 | unsigned long long nsecs = get_time(); |
136 | - | |
143 | +#else | |
144 | + unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION + | |
145 | + xtime.tv_nsec; | |
146 | +#endif | |
137 | 147 | tv->tv_sec = nsecs / NSEC_PER_SEC; |
138 | 148 | /* Careful about calculations here - this was originally done as |
139 | 149 | * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC |