public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeff Dike <jdike@addtoit.com>
To: Nix <nix@esperi.org.uk>, dhazelton@enter.net
Cc: Andrew Morton <akpm@linux-foundation.org>,
	linux-kernel@vger.kernel.org,
	user-mode-linux-devel@lists.sourceforge.net,
	Jeremy Fitzhardinge <jeremy@goop.org>
Subject: Re: [PATCH 1/6] UML - Deal with host time going backwards
Date: Thu, 5 Jun 2008 11:30:08 -0400	[thread overview]
Message-ID: <20080605153008.GC7311@c2.user-mode-linux.org> (raw)
In-Reply-To: <4846F577.10603@goop.org>

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:

  reply	other threads:[~2008-06-05 15:31 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-06-03 19:02 [PATCH 1/6] UML - Deal with host time going backwards Jeff Dike
2008-06-03 19:32 ` Andrew Morton
2008-06-03 19:43   ` Daniel Hazelton
2008-06-03 19:52     ` Nix
2008-06-03 20:07       ` Andrew Morton
2008-06-03 20:37         ` Daniel Hazelton
2008-06-03 21:00         ` Jeff Dike
2008-06-04  1:50           ` Eric W. Biederman
2008-06-04  3:15             ` Jeff Dike
2008-06-04  5:12             ` Daniel Hazelton
2008-06-04 14:31           ` Jeremy Fitzhardinge
2008-06-04 19:37             ` Jeff Dike
2008-06-04 20:05               ` Jeremy Fitzhardinge
2008-06-05 15:30                 ` Jeff Dike [this message]
2008-06-05 18:14                   ` Nix
2008-06-05 19:47                     ` Jeff Dike
2008-06-05 21:41                       ` Nix
2008-06-05 18:19                   ` Nix
  -- strict thread matches above, loose matches on Subject: below --
2008-06-03 19:59 devzero

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080605153008.GC7311@c2.user-mode-linux.org \
    --to=jdike@addtoit.com \
    --cc=akpm@linux-foundation.org \
    --cc=dhazelton@enter.net \
    --cc=jeremy@goop.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nix@esperi.org.uk \
    --cc=user-mode-linux-devel@lists.sourceforge.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox