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>
This commit is contained in:
parent
83ff7df5f1
commit
b7ec15bd00
1 changed files with 12 additions and 2 deletions
|
@ -34,8 +34,8 @@ unsigned long long sched_clock(void)
|
|||
return (unsigned long long)jiffies_64 * (1000000000 / HZ);
|
||||
}
|
||||
|
||||
static unsigned long long prev_nsecs[NR_CPUS];
|
||||
#ifdef CONFIG_UML_REAL_TIME_CLOCK
|
||||
static unsigned long long prev_nsecs[NR_CPUS];
|
||||
static long long delta[NR_CPUS]; /* Deviation per interval */
|
||||
#endif
|
||||
|
||||
|
@ -94,7 +94,12 @@ irqreturn_t um_timer(int irq, void *dev)
|
|||
|
||||
do_timer(1);
|
||||
|
||||
#ifdef CONFIG_UML_REAL_TIME_CLOCK
|
||||
nsecs = get_time();
|
||||
#else
|
||||
nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
|
||||
BILLION / HZ;
|
||||
#endif
|
||||
xtime.tv_sec = nsecs / NSEC_PER_SEC;
|
||||
xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
|
||||
|
||||
|
@ -127,13 +132,18 @@ void time_init(void)
|
|||
nsecs = os_nsecs();
|
||||
set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
|
||||
-nsecs % BILLION);
|
||||
set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
|
||||
late_time_init = register_timer;
|
||||
}
|
||||
|
||||
void do_gettimeofday(struct timeval *tv)
|
||||
{
|
||||
#ifdef CONFIG_UML_REAL_TIME_CLOCK
|
||||
unsigned long long nsecs = get_time();
|
||||
|
||||
#else
|
||||
unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
|
||||
xtime.tv_nsec;
|
||||
#endif
|
||||
tv->tv_sec = nsecs / NSEC_PER_SEC;
|
||||
/* Careful about calculations here - this was originally done as
|
||||
* (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
|
||||
|
|
Loading…
Reference in a new issue