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