From: Jeff D. <jd...@ad...> - 2008-06-03 19:03:21
|
Protection against the host's time going backwards - keep track of the time at the last tick and if it's greater than the current time, keep time stopped until the host catches up. Cc: Nix <ni...@es...> Signed-off-by: Jeff Dike <jd...@li...> --- arch/um/os-Linux/time.c | 7 +++++++ 1 file changed, 7 insertions(+) Index: linux-2.6-git/arch/um/os-Linux/time.c =================================================================== --- linux-2.6-git.orig/arch/um/os-Linux/time.c 2008-05-14 10:44:02.000000000 -0400 +++ linux-2.6-git/arch/um/os-Linux/time.c 2008-06-02 15:43:53.000000000 -0400 @@ -106,6 +106,10 @@ static void deliver_alarm(void) unsigned long long this_tick = os_nsecs(); int one_tick = UM_NSEC_PER_SEC / UM_HZ; + /* Protection against the host's time going backwards */ + if ((last_tick != 0) && (this_tick < last_tick)) + this_tick = last_tick; + if (last_tick == 0) last_tick = this_tick - one_tick; @@ -148,6 +152,9 @@ static int after_sleep_interval(struct t start_usecs = usec; start_usecs -= skew / UM_NSEC_PER_USEC; + if (start_usecs < 0) + start_usecs = 0; + tv = ((struct timeval) { .tv_sec = start_usecs / UM_USEC_PER_SEC, .tv_usec = start_usecs % UM_USEC_PER_SEC }); interval = ((struct itimerval) { { 0, usec }, tv }); |
From: Andrew M. <ak...@li...> - 2008-06-03 19:32:29
|
On Tue, 3 Jun 2008 15:02:35 -0400 Jeff Dike <jd...@ad...> wrote: > Protection against the host's time going backwards - keep track of the > time at the last tick and if it's greater than the current time, keep > time stopped until the host catches up. Strange. What would cause the host's time (or at least UML's perception of it) to go backwards? |
From: Daniel H. <dha...@en...> - 2008-06-03 19:44:30
|
On Tuesday 03 June 2008 03:32:11 pm Andrew Morton wrote: > On Tue, 3 Jun 2008 15:02:35 -0400 > > Jeff Dike <jd...@ad...> wrote: > > Protection against the host's time going backwards - keep track of the > > time at the last tick and if it's greater than the current time, keep > > time stopped until the host catches up. > > Strange. What would cause the host's time (or at least UML's perception > of it) to go backwards? A wild guess would be that the UML process is running "fast" at some point and its expectation of the host's time is skewed forward because of that. Another possibility is that the hosts clock got reset between the times UML has checked it and the correction was a negative one. DRH -- Dialup is like pissing through a pipette. Slow and excruciatingly painful. |
From: Nix <ni...@es...> - 2008-06-05 18:15:21
|
On 5 Jun 2008, Jeff Dike verbalised: > Aha, I was looking at timer_* and not getting reasonable-looking > results. The one questionable aspect of this is that I need to pull > in a new library (librt) and I wonder how many people don't have it > installed... It comes with glibc, and even ls uses it (for clock_gettime(), to determine what format to use for date display). I'd say using it is about as safe as can be. > Anyway, the patch below seems to make the guest behave reasonably in > the face of the host time doing funky things... > > Give it a spin and let me know how it does. If there aren't any > problems, I'll get it into mainline. Rebuilding for a test now. -- `If you are having a "ua luea luea le ua le" kind of day, I can only assume that you are doing no work due [to] incapacitating nausea caused by numerous lazy demons.' --- Frossie |
From: Jeff D. <jd...@ad...> - 2008-06-05 19:48:18
|
On Thu, Jun 05, 2008 at 07:14:30PM +0100, Nix wrote: > It comes with glibc, and even ls uses it (for clock_gettime(), to > determine what format to use for date display). > > I'd say using it is about as safe as can be. Without adding -lrt to the link line here (F7), I get arch/um/os-Linux/built-in.o: In function `nsecs': /home/jdike/linux/2.6/linux-2.6.22/arch/um/os-Linux/time.c:84: undefined reference to `clock_gettime' collect2: ld returned 1 exit status A little odd for a system call... > Does this really only apply on top of 2.6.22? Which of the bewildering > blizzard of time-fixup patches we've been exchanging do I need? :) I have it on top of 2.6.26-rc2-mm1, plus all the other patches I've sent to Andrew. The patch which started this discussion is the one you really need though, since this backs it out. Jeff -- Work email - jdike at linux dot intel dot com |
From: Nix <ni...@es...> - 2008-06-05 21:42:42
|
On 5 Jun 2008, Jeff Dike uttered the following: > On Thu, Jun 05, 2008 at 07:14:30PM +0100, Nix wrote: >> It comes with glibc, and even ls uses it (for clock_gettime(), to >> determine what format to use for date display). >> >> I'd say using it is about as safe as can be. > > Without adding -lrt to the link line here (F7), I get Yes, you'll definitely *need* -lrt for clock_*(). > arch/um/os-Linux/built-in.o: In function `nsecs': > /home/jdike/linux/2.6/linux-2.6.22/arch/um/os-Linux/time.c:84: undefined reference to `clock_gettime' > collect2: ld returned 1 exit status > > A little odd for a system call... I think it's in there because it's part of the POSIX realtime extensions, so you should have to, as it were, assent to using something that's not as portable as just using libc. It makes more sense than libm, anyway. (It's completely moot for UML of course :) ) -- `If you are having a "ua luea luea le ua le" kind of day, I can only assume that you are doing no work due [to] incapacitating nausea caused by numerous lazy demons.' --- Frossie |
From: Nix <ni...@es...> - 2008-06-03 19:52:56
|
On 3 Jun 2008, Daniel Hazelton said: > On Tuesday 03 June 2008 03:32:11 pm Andrew Morton wrote: >> On Tue, 3 Jun 2008 15:02:35 -0400 >> >> Jeff Dike <jd...@ad...> wrote: >> > Protection against the host's time going backwards - keep track of the >> > time at the last tick and if it's greater than the current time, keep >> > time stopped until the host catches up. >> >> Strange. What would cause the host's time (or at least UML's perception >> of it) to go backwards? > > A wild guess would be that the UML process is running "fast" at some point and > its expectation of the host's time is skewed forward because of that. Quite so. Simply running ntp on the host (in slew-only mode, no less!) can cause this. > Another possibility is that the hosts clock got reset between the times UML > has checked it and the correction was a negative one. That too. -- `If you are having a "ua luea luea le ua le" kind of day, I can only assume that you are doing no work due [to] incapacitating nausea caused by numerous lazy demons.' --- Frossie |
From: Andrew M. <ak...@li...> - 2008-06-03 20:08:06
|
On Tue, 03 Jun 2008 20:52:18 +0100 Nix <ni...@es...> wrote: > On 3 Jun 2008, Daniel Hazelton said: > > > On Tuesday 03 June 2008 03:32:11 pm Andrew Morton wrote: > >> On Tue, 3 Jun 2008 15:02:35 -0400 > >> > >> Jeff Dike <jd...@ad...> wrote: > >> > Protection against the host's time going backwards - keep track of the > >> > time at the last tick and if it's greater than the current time, keep > >> > time stopped until the host catches up. > >> > >> Strange. What would cause the host's time (or at least UML's perception > >> of it) to go backwards? > > > > A wild guess would be that the UML process is running "fast" at some point and > > its expectation of the host's time is skewed forward because of that. > > Quite so. Simply running ntp on the host (in slew-only mode, no less!) > can cause this. > > > Another possibility is that the hosts clock got reset between the times UML > > has checked it and the correction was a negative one. > > That too. > So if I change the host's time by an hour, the time will not advance at all on the guest for the next hour? Sounds suboptimal :) I suppose the guest should be running an ntp client synced to something sane anyway? |
From: Daniel H. <dha...@en...> - 2008-06-03 20:38:04
|
On Tuesday 03 June 2008 04:07:09 pm Andrew Morton wrote: > On Tue, 03 Jun 2008 20:52:18 +0100 > > Nix <ni...@es...> wrote: > > On 3 Jun 2008, Daniel Hazelton said: > > > On Tuesday 03 June 2008 03:32:11 pm Andrew Morton wrote: > > >> On Tue, 3 Jun 2008 15:02:35 -0400 > > >> > > >> Jeff Dike <jd...@ad...> wrote: > > >> > Protection against the host's time going backwards - keep track of > > >> > the time at the last tick and if it's greater than the current time, > > >> > keep time stopped until the host catches up. > > >> > > >> Strange. What would cause the host's time (or at least UML's > > >> perception of it) to go backwards? > > > > > > A wild guess would be that the UML process is running "fast" at some > > > point and its expectation of the host's time is skewed forward because > > > of that. > > > > Quite so. Simply running ntp on the host (in slew-only mode, no less!) > > can cause this. > > > > > Another possibility is that the hosts clock got reset between the times > > > UML has checked it and the correction was a negative one. > > > > That too. > > So if I change the host's time by an hour, the time will not advance at all > on the guest for the next hour? Sounds suboptimal :) I agree. But like I said originally - it's a wild guess. I don't even know how accurate it is. > I suppose the guest should be running an ntp client synced to something > sane anyway? That might be helpful :) DRH -- Dialup is like pissing through a pipette. Slow and excruciatingly painful. |
From: Jeff D. <jd...@ad...> - 2008-06-03 21:02:09
|
On Tue, Jun 03, 2008 at 01:07:09PM -0700, Andrew Morton wrote: > So if I change the host's time by an hour, the time will not advance at all > on the guest for the next hour? Sounds suboptimal :) It is, but if the host is whacked, the guest just has to do the best that it can... Jeff -- Work email - jdike at linux dot intel dot com |
From: <ebi...@xm...> - 2008-06-04 01:51:45
|
Jeff Dike <jd...@ad...> writes: > On Tue, Jun 03, 2008 at 01:07:09PM -0700, Andrew Morton wrote: >> So if I change the host's time by an hour, the time will not advance at all >> on the guest for the next hour? Sounds suboptimal :) > > It is, but if the host is whacked, the guest just has to do the best that > it can... Could using a CLOCK_MONOTONIC time source fix this? Those timers do not change when we change the time on the host. Eric |
From: Jeff D. <jd...@ad...> - 2008-06-04 03:16:21
|
On Tue, Jun 03, 2008 at 06:50:49PM -0700, Eric W. Biederman wrote: > Could using a CLOCK_MONOTONIC time source fix this? Those timers do not > change when we change the time on the host. Hmmm, maybe. The man page looks promising... Jeff -- Work email - jdike at linux dot intel dot com |
From: Daniel H. <dha...@en...> - 2008-06-04 05:12:44
|
On Tuesday 03 June 2008 09:50:49 pm Eric W. Biederman wrote: > Jeff Dike <jd...@ad...> writes: > > On Tue, Jun 03, 2008 at 01:07:09PM -0700, Andrew Morton wrote: > >> So if I change the host's time by an hour, the time will not advance at > >> all on the guest for the next hour? Sounds suboptimal :) > > > > It is, but if the host is whacked, the guest just has to do the best that > > it can... > > Could using a CLOCK_MONOTONIC time source fix this? Those timers do not > change when we change the time on the host. > > Eric I'm not all that familiar with the specifics of the code - my original statements about possible causes were barely more than wild guesses - but this does sound like it would work. DRH -- Dialup is like pissing through a pipette. Slow and excruciatingly painful. |
From: Jeremy F. <je...@go...> - 2008-06-04 14:32:41
|
Jeff Dike wrote: > On Tue, Jun 03, 2008 at 01:07:09PM -0700, Andrew Morton wrote: > >> So if I change the host's time by an hour, the time will not advance at all >> on the guest for the next hour? Sounds suboptimal :) >> > > It is, but if the host is whacked, the guest just has to do the best that > it can... > Shouldn't UML use a monotonic host clock for guest timekeeping? J |
From: Jeff D. <jd...@ad...> - 2008-06-04 19:38:13
|
On Wed, Jun 04, 2008 at 03:31:58PM +0100, Jeremy Fitzhardinge wrote: > Shouldn't UML use a monotonic host clock for guest timekeeping? Indeed, Eric pointed out the posix timers, which I had forgotten about. On the face of it, a monotonic timer should do the trick, but it's not obvious how to get it to behave like a monotonic gettimeofday... Jeff -- Work email - jdike at linux dot intel dot com |
From: Jeremy F. <je...@go...> - 2008-06-04 20:05:53
|
Jeff Dike wrote: > On Wed, Jun 04, 2008 at 03:31:58PM +0100, Jeremy Fitzhardinge wrote: > >> Shouldn't UML use a monotonic host clock for guest timekeeping? >> > > Indeed, Eric pointed out the posix timers, which I had forgotten > about. On the face of it, a monotonic timer should do the trick, but > it's not obvious how to get it to behave like a monotonic > gettimeofday... You can either read the monotonic clock directly, or use it as a time source for a monotonic timer. clock_gettime(CLOCK_MONOTONIC, &ts) will return the time in ns, and you can just feed that directly into the guest as a clocksource. J |
From: Jeff D. <jd...@ad...> - 2008-06-05 15:31:08
|
On Wed, Jun 04, 2008 at 09:05:11PM +0100, Jeremy Fitzhardinge wrote: > You can either read the monotonic clock directly, or use it as a time > source for a monotonic timer. clock_gettime(CLOCK_MONOTONIC, &ts) will > return the time in ns, and you can just feed that directly into the guest > as a clocksource. Aha, I was looking at timer_* and not getting reasonable-looking results. The one questionable aspect of this is that I need to pull in a new library (librt) and I wonder how many people don't have it installed... Anyway, the patch below seems to make the guest behave reasonably in the face of the host time doing funky things... Give it a spin and let me know how it does. If there aren't any problems, I'll get it into mainline. Jeff -- Work email - jdike at linux dot intel dot com Index: linux-2.6.22/arch/um/os-Linux/time.c =================================================================== --- linux-2.6.22.orig/arch/um/os-Linux/time.c 2008-06-02 15:38:34.000000000 -0400 +++ linux-2.6.22/arch/um/os-Linux/time.c 2008-06-04 19:49:16.000000000 -0400 @@ -56,6 +56,11 @@ static inline long long timeval_to_ns(co tv->tv_usec * UM_NSEC_PER_USEC; } +static inline long long timespec_to_ns(const struct timespec *ts) +{ + return ((long long) ts->tv_sec * UM_NSEC_PER_SEC) + ts->tv_nsec; +} + long long disable_timer(void) { struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } }); @@ -72,12 +77,22 @@ long long disable_timer(void) return remain; } -long long os_nsecs(void) +static inline long long nsecs(int clock) { - struct timeval tv; + struct timespec ts; + + clock_gettime(clock, &ts); + return timespec_to_ns(&ts); +} + +long long os_wall_nsecs(void) +{ + return nsecs(CLOCK_REALTIME); +} - gettimeofday(&tv, NULL); - return timeval_to_ns(&tv); +long long os_mono_nsecs(void) +{ + return nsecs(CLOCK_MONOTONIC); } extern void alarm_handler(int sig, struct sigcontext *sc); @@ -104,13 +119,9 @@ unsigned long long skew; static void deliver_alarm(void) { - unsigned long long this_tick = os_nsecs(); + unsigned long long this_tick = os_mono_nsecs(); int one_tick = UM_NSEC_PER_SEC / UM_HZ; - /* Protection against the host's time going backwards */ - if ((last_tick != 0) && (this_tick < last_tick)) - this_tick = last_tick; - if (last_tick == 0) last_tick = this_tick - one_tick; Index: linux-2.6.22/arch/um/Makefile =================================================================== --- linux-2.6.22.orig/arch/um/Makefile 2008-05-29 11:21:25.000000000 -0400 +++ linux-2.6.22/arch/um/Makefile 2008-06-04 19:42:09.000000000 -0400 @@ -126,7 +126,7 @@ define cmd_vmlinux__ $(CC) $(CFLAGS_vmlinux) -o $@ \ -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \ -Wl,--start-group $(vmlinux-main) -Wl,--end-group \ - -lutil \ + -lutil -lrt \ $(filter-out $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) vmlinux.o \ FORCE ,$^) ; rm -f linux endef Index: linux-2.6.22/arch/um/include/os.h =================================================================== --- linux-2.6.22.orig/arch/um/include/os.h 2008-06-02 15:38:34.000000000 -0400 +++ linux-2.6.22/arch/um/include/os.h 2008-06-04 19:51:55.000000000 -0400 @@ -244,7 +244,8 @@ extern int set_interval(void); extern int timer_one_shot(int ticks); extern long long disable_timer(void); extern void uml_idle_timer(void); -extern long long os_nsecs(void); +extern long long os_wall_nsecs(void); +extern long long os_mono_nsecs(void); /* skas/mem.c */ extern long run_syscall_stub(struct mm_id * mm_idp, Index: linux-2.6.22/arch/um/kernel/time.c =================================================================== --- linux-2.6.22.orig/arch/um/kernel/time.c 2008-06-02 15:38:33.000000000 -0400 +++ linux-2.6.22/arch/um/kernel/time.c 2008-06-04 19:51:59.000000000 -0400 @@ -74,7 +74,7 @@ static irqreturn_t um_timer(int irq, voi static cycle_t itimer_read(void) { - return os_nsecs() / 1000; + return os_mono_nsecs() / 1000; } static struct clocksource itimer_clocksource = { @@ -117,7 +117,7 @@ void __init time_init(void) timer_init(); - nsecs = os_nsecs(); + nsecs = os_wall_nsecs(); set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC, -nsecs % NSEC_PER_SEC); set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC, Index: linux-2.6.22/arch/um/os-Linux/skas/process.c =================================================================== --- linux-2.6.22.orig/arch/um/os-Linux/skas/process.c 2008-06-04 19:51:05.000000000 -0400 +++ linux-2.6.22/arch/um/os-Linux/skas/process.c 2008-06-04 19:51:59.000000000 -0400 @@ -359,7 +359,7 @@ void userspace(struct uml_pt_regs *regs) printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno); nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC + timer.it_value.tv_usec * UM_NSEC_PER_USEC; - nsecs += os_nsecs(); + nsecs += os_mono_nsecs(); while (1) { /* @@ -420,7 +420,7 @@ void userspace(struct uml_pt_regs *regs) relay_signal(SIGTRAP, regs); break; case SIGVTALRM: - now = os_nsecs(); + now = os_mono_nsecs(); if (now < nsecs) break; block_signals(); @@ -430,7 +430,7 @@ void userspace(struct uml_pt_regs *regs) UM_NSEC_PER_SEC + timer.it_value.tv_usec * UM_NSEC_PER_USEC; - nsecs += os_nsecs(); + nsecs += os_mono_nsecs(); break; case SIGIO: case SIGILL: |
From: Nix <ni...@es...> - 2008-06-05 18:19:54
|
On 5 Jun 2008, Jeff Dike uttered the following: > Index: linux-2.6.22/arch/um/os-Linux/time.c Does this really only apply on top of 2.6.22? Which of the bewildering blizzard of time-fixup patches we've been exchanging do I need? :) -- `If you are having a "ua luea luea le ua le" kind of day, I can only assume that you are doing no work due [to] incapacitating nausea caused by numerous lazy demons.' --- Frossie |