PERFORCE change 89196 for review

Kip Macy kmacy at FreeBSD.org
Wed Jan 4 22:42:27 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=89196

Change 89196 by kmacy at kmacy:freebsd7_xen3 on 2006/01/05 06:41:54

	set wallclock time so that domain time corresponds to dom0 time
	change get_timecount so that time doesn't increase in a bursty fashion

Affected files ...

.. //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#3 edit

Differences ...

==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/clock.c#3 (text+ko) ====

@@ -129,7 +129,10 @@
 static unsigned long fast_gettimeoffset_quotient;
 
 /* These are peridically updated in shared_info, and then copied here. */
-static struct timeval shadow_tv;
+static struct timespec shadow_tv;
+
+uint32_t shadow_tv_version;
+
 
 #define do_div(n,base) ({ \
         unsigned long __upper, __low, __high, __mod, __base; \
@@ -239,6 +242,21 @@
 	return scale_delta(delta, shadow->tsc_to_nsec_mul, shadow->tsc_shift);
 }
 
+static void update_wallclock(void)
+{
+	shared_info_t *s = HYPERVISOR_shared_info;
+
+	do {
+		shadow_tv_version = s->wc_version;
+		rmb();
+		shadow_tv.tv_sec  = s->wc_sec;
+		shadow_tv.tv_nsec = s->wc_nsec;
+		rmb();
+	}
+	while ((s->wc_version & 1) | (shadow_tv_version ^ s->wc_version));
+
+}
+
 /*
  * Reads a consistent set of time-base values from Xen, into a shadow data
  * area. Must be called with the xtime_lock held for writing.
@@ -288,47 +306,49 @@
 	0			/* quality */
 };
 
-
 static void 
 clkintr(struct trapframe *frame)
 {
-    int64_t delta_cpu, delta;
-    int cpu = smp_processor_id();
-    struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
-    long ticks = 0;
-    TRACE_ENTER;
+	int64_t delta_cpu, delta;
+	int cpu = smp_processor_id();
+	struct shadow_time_info *shadow = &per_cpu(shadow_time, cpu);
+	long lticks = 0;
+	
+	do {
+		__get_time_values_from_xen();
+		
+		delta = delta_cpu = 
+			shadow->system_timestamp + get_nsec_offset(shadow);
+		
+		delta     -= processed_system_time;
+		delta_cpu -= per_cpu(processed_system_time, cpu);
 
-    do {
-    	__get_time_values_from_xen();
-
-    	delta = delta_cpu = 
-	  shadow->system_timestamp + get_nsec_offset(shadow);
-
-	delta     -= processed_system_time;
-	delta_cpu -= per_cpu(processed_system_time, cpu);
-
-    } while (!time_values_up_to_date(cpu));
-
-    if (unlikely(delta < (int64_t)-1000000) || unlikely(delta_cpu < 0)) {
-        printf("Timer ISR: Time went backwards: %lld\n", delta);
-        return;
-    }
-
-    /* Process elapsed ticks since last call. */
-    if (delta > NS_PER_TICK) {
-	    ticks += (delta / NS_PER_TICK);
-	    delta = (delta % NS_PER_TICK);
-	    processed_system_time += ticks*NS_PER_TICK;
-	    per_cpu(processed_system_time, cpu) += ticks*NS_PER_TICK;
-    }
+	} while (!time_values_up_to_date(cpu));
+	
+	if (unlikely(delta < (int64_t)-1000000) || unlikely(delta_cpu < 0)) {
+		printf("Timer ISR: Time went backwards: %lld\n", delta);
+		return;
+	}
+	
+	/* Process elapsed ticks since last call. */
+	if (delta >= NS_PER_TICK) {
+		lticks = (delta / NS_PER_TICK);
+		processed_system_time += lticks*NS_PER_TICK;
+		per_cpu(processed_system_time, cpu) += lticks*NS_PER_TICK;
+	}
 	hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame));
-    /*
-     * Take synchronised time from Xen once a minute if we're not
-     * synchronised ourselves, and we haven't chosen to keep an independent
-     * time base.
-     */
-    
-    /* XXX TODO */
+	/*
+	 * Take synchronised time from Xen once a minute if we're not
+	 * synchronised ourselves, and we haven't chosen to keep an independent
+	 * time base.
+	 */
+	
+	if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
+		update_wallclock();
+		tc_setclock(&shadow_tv);
+	}
+	
+	/* XXX TODO */
 }
 
 #include "opt_ddb.h"
@@ -336,7 +356,7 @@
 getit(void)
 {
 	__get_time_values_from_xen();
-	return per_cpu(shadow_time, 0).tsc_timestamp;
+	return per_cpu(shadow_time, smp_processor_id()).system_timestamp;
 }
 
 /*
@@ -507,6 +527,8 @@
 	int		s, y;
 	struct timespec ts;
 
+	update_wallclock();
+	
 	s = splclock();
 	if (base) {
 		ts.tv_sec = base;
@@ -517,9 +539,7 @@
 	y = time_second - shadow_tv.tv_sec;
 	if (y <= -2 || y >= 2) {
 		/* badly off, adjust it */
-		ts.tv_sec = shadow_tv.tv_sec;
-		ts.tv_nsec = shadow_tv.tv_usec * 1000;
-		tc_setclock(&ts);
+		tc_setclock(&shadow_tv);
 	}
 	splx(s);
 }
@@ -582,11 +602,18 @@
 
     	printf("cpu_stopprofclock: profiling clock is not supported\n");
 }
+#define NSEC_PER_USEC 1000
 
 static uint32_t
 xen_get_timecount(struct timecounter *tc)
-{
-	return processed_system_time;
+{	
+	struct shadow_time_info *shadow;
+	shadow = &per_cpu(shadow_time, smp_processor_id());
+
+	return (uint32_t)get_nsec_offset(shadow);
+
+
+	
 }
 
 /*


More information about the p4-projects mailing list