2008-06-03 19:05:49

by Jeff Dike

[permalink] [raw]
Subject: [PATCH 1/6] UML - Deal with host time going backwards

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 <[email protected]>
Signed-off-by: Jeff Dike <[email protected]>
---
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 });


2008-06-03 19:32:41

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Tue, 3 Jun 2008 15:02:35 -0400
Jeff Dike <[email protected]> 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?

2008-06-03 19:44:27

by Daniel Hazelton

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Tuesday 03 June 2008 03:32:11 pm Andrew Morton wrote:
> On Tue, 3 Jun 2008 15:02:35 -0400
>
> Jeff Dike <[email protected]> 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.

2008-06-03 19:52:54

by Nix

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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 <[email protected]> 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

2008-06-03 19:59:31

by Roland

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

>> 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?

mhh - what about admin`s/user`s stupidity ?

e.g.

0 * * * * root /usr/sbin/ntpdate some.time.server >/dev/null 2>&1

in root`s crontab.

if the hosts`s clock is running faster than clock on some.time.server, this would set host`s clock back in time every hour or so....

common malpractice regarding time-syncronization - have seen that more than once.
(and have to admit that i used that some years ago before i wasn`t aware that ntpd does handle that more intelligent)


_______________________________________________________________________
EINE F?R ALLE: die kostenlose WEB.DE-Plattform f?r Freunde und Deine
Homepage mit eigenem Namen. Jetzt starten! http://unddu.de/?kid=kid@mf2

2008-06-03 20:08:18

by Andrew Morton

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Tue, 03 Jun 2008 20:52:18 +0100
Nix <[email protected]> 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 <[email protected]> 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?

2008-06-03 20:42:34

by Daniel Hazelton

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Tuesday 03 June 2008 04:07:09 pm Andrew Morton wrote:
> On Tue, 03 Jun 2008 20:52:18 +0100
>
> Nix <[email protected]> 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 <[email protected]> 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.

2008-06-03 21:02:04

by Jeff Dike

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-04 01:51:44

by Eric W. Biederman

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

Jeff Dike <[email protected]> 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

2008-06-04 03:16:31

by Jeff Dike

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-04 05:12:48

by Daniel Hazelton

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

On Tuesday 03 June 2008 09:50:49 pm Eric W. Biederman wrote:
> Jeff Dike <[email protected]> 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.

2008-06-04 14:32:47

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-04 19:38:32

by Jeff Dike

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-04 20:06:06

by Jeremy Fitzhardinge

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-05 15:31:20

by Jeff Dike

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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:

2008-06-05 18:15:34

by Nix

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-05 18:20:08

by Nix

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-05 19:48:29

by Jeff Dike

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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

2008-06-05 21:42:55

by Nix

[permalink] [raw]
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards

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