Date: Thu, 5 Jan 2006 06:42:26 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 89196 for review Message-ID: <200601050642.k056gQEL073562@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=89196 Change 89196 by kmacy@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); + + + } /*
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200601050642.k056gQEL073562>