Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/cherry-xenmp]: src/sys/arch/xen/xen More improvements:



details:   https://anonhg.NetBSD.org/src/rev/1590f592ae19
branches:  cherry-xenmp
changeset: 765649:1590f592ae19
user:      bouyer <bouyer%NetBSD.org@localhost>
date:      Sat Oct 22 22:42:20 2011 +0000

description:
More improvements:
- Precise what tmutex protects
- springle some KASSERT(mutex_owned(&tmutex))
- the system time uses the CPU timecounter to get some precision;
  don't mix local CPU timecounter with VCPU0's time, it won't work well.
  Always use curcpu()'s time.

diffstat:

 sys/arch/xen/xen/clock.c |  71 +++++++++++++++++++++--------------------------
 1 files changed, 32 insertions(+), 39 deletions(-)

diffs (164 lines):

diff -r 72fc64741ff9 -r 1590f592ae19 sys/arch/xen/xen/clock.c
--- a/sys/arch/xen/xen/clock.c  Sat Oct 22 21:16:59 2011 +0000
+++ b/sys/arch/xen/xen/clock.c  Sat Oct 22 22:42:20 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: clock.c,v 1.54.6.6 2011/10/22 21:16:59 bouyer Exp $    */
+/*     $NetBSD: clock.c,v 1.54.6.7 2011/10/22 22:42:20 bouyer Exp $    */
 
 /*
  *
@@ -29,7 +29,7 @@
 #include "opt_xen.h"
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.54.6.6 2011/10/22 21:16:59 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.54.6.7 2011/10/22 22:42:20 bouyer Exp $");
 
 #include <sys/param.h>
 #include <sys/cpu.h>
@@ -79,11 +79,12 @@
        struct timespec ts;
 };
 
+/* Protects volatile variables ci_shadow & xen_clock_bias */
+static kmutex_t tmutex;
+
 /* Per CPU shadow time values */
 static volatile struct shadow ci_shadow[MAXCPUS];
 
-static kmutex_t tmutex; /* Protects volatile variables, below */
-
 /* The time when the last hardclock(9) call should have taken place,
  * per cpu.
  */
@@ -116,6 +117,7 @@
        volatile struct vcpu_time_info *t = &ci->ci_vcpu->time;
        uint32_t tversion;
 
+       KASSERT(mutex_owned(&tmutex));
        do {
                shadow->time_version = t->version;
                xen_rmb();
@@ -142,9 +144,11 @@
 time_values_up_to_date(struct cpu_info *ci)
 {
        int rv;
-       KASSERT(ci != NULL);
+       volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
-       volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
+       KASSERT(ci != NULL);
+       KASSERT(mutex_owned(&tmutex));
+
 
        xen_rmb();
        rv = shadow->time_version == ci->ci_vcpu->time.version;
@@ -187,6 +191,7 @@
        uint64_t tsc_delta, offset;
        volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
+       KASSERT(mutex_owned(&tmutex));
        tsc_delta = cpu_counter() - shadow->tsc_stamp;
        offset = scale_delta(tsc_delta, shadow->freq_mul,
            shadow->freq_shift);
@@ -212,53 +217,36 @@
        uint64_t offset, stime;
        volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
        
-       for (;;) {
+       KASSERT(mutex_owned(&tmutex));
+       do {
+               get_time_values_from_xen(ci);
                offset = get_tsc_offset_ns(ci);
                stime = shadow->system_time + offset;
                
                /* if the timestamp went stale before we used it, refresh */
-               if (time_values_up_to_date(ci)) {
-                       /*
-                        * Work around an intermittent Xen2 bug where, for
-                        * a period of 1<<32 ns, currently running domains
-                        * don't get their timer events as usual (and also
-                        * aren't preempted in favor of other runnable
-                        * domains).  Setting the timer into the past in
-                        * this way causes it to fire immediately.
-                        */
-                       break;
-               }
-               get_time_values_from_xen(ci);
-       }
+       } while (!time_values_up_to_date(ci));
 
        return stime;
 }
 
-/*
- * SMP note: system time always derives from Boot Processor.
- * Must be called at splhigh. See comment above on get_vcpu_time()
- */
-static uint64_t
-get_system_time(void)
-{
-       return get_vcpu_time(&cpu_info_primary);
-
-}
-
 static void
 xen_wall_time(struct timespec *wt)
 {
        uint64_t nsec;
-       struct cpu_info *ci = &cpu_info_primary;
+       struct cpu_info *ci = curcpu();
        volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
 
        mutex_enter(&tmutex);
-       get_time_values_from_xen(ci);
-       *wt = shadow->ts;
-       nsec = wt->tv_nsec;
+       do {
+               /*
+                * Under Xen3, shadow->ts is the wall time less system time
+                * get_vcpu_time() will update shadow
+                */
+               nsec = get_vcpu_time(curcpu());
+               *wt = shadow->ts;
+               nsec += wt->tv_nsec;
 
-       /* Under Xen3, this is the wall time less system time */
-       nsec += get_system_time();
+       } while (!time_values_up_to_date(ci));
        mutex_exit(&tmutex);
        wt->tv_sec += nsec / 1000000000L;
        wt->tv_nsec = nsec % 1000000000L;
@@ -300,7 +288,7 @@
                op.u.settime.secs        = tvp->tv_sec;
                op.u.settime.nsecs       = tvp->tv_usec * 1000;
                mutex_enter(&tmutex);
-               op.u.settime.system_time = get_system_time();
+               op.u.settime.system_time = get_vcpu_time(curcpu());
                mutex_exit(&tmutex);
 #if __XEN_INTERFACE_VERSION__ < 0x00030204
                return HYPERVISOR_dom0_op(&op);
@@ -363,6 +351,7 @@
                when = shadow->system_time + n * 1000;
                while (shadow->system_time < when) {
                        mutex_exit(&tmutex);
+                       HYPERVISOR_yield();
                        mutex_enter(&tmutex);
                        get_time_values_from_xen(ci);
                }
@@ -459,10 +448,14 @@
        evtch = bind_virq_to_evtch(VIRQ_TIMER);
        aprint_verbose("Xen clock: using event channel %d\n", evtch);
 
+       if (!tcdone) { /* Do this only once */
+               mutex_init(&tmutex, MUTEX_DEFAULT, IPL_CLOCK);
+       }
+       mutex_enter(&tmutex);
        get_time_values_from_xen(ci);
        vcpu_system_time[ci->ci_cpuid] = shadow->system_time;
+       mutex_exit(&tmutex);
        if (!tcdone) { /* Do this only once */
-               mutex_init(&tmutex, MUTEX_DEFAULT, IPL_CLOCK);
                tc_init(&xen_timecounter);
        }
        /* The splhigh requirements start here. */



Home | Main Index | Thread Index | Old Index