[PATCH v10 05/20] xen: rework xen timer so it can be used early in boot process

From: Roger Pau Monne <roger.pau_at_citrix.com>
Date: Tue, 14 Jan 2014 15:59:27 +0100
This should not introduce any functional change, and makes the
functions suitable to be called before we have actually mapped the
vcpu_info struct on a per-cpu basis.
---
 sys/dev/xen/timer/timer.c |   29 ++++++++++++++++++++---------
 1 files changed, 20 insertions(+), 9 deletions(-)

diff --git a/sys/dev/xen/timer/timer.c b/sys/dev/xen/timer/timer.c
index 354085b..b2f6bcd 100644
--- a/sys/dev/xen/timer/timer.c
+++ b/sys/dev/xen/timer/timer.c
_at__at_ -230,22 +230,22 _at__at_ xen_fetch_vcpu_tinfo(struct vcpu_time_info *dst, struct vcpu_time_info *src)
 /**
  * \brief Get the current time, in nanoseconds, since the hypervisor booted.
  *
+ * \param vcpu		vcpu_info structure to fetch the time from.
+ *
  * \note This function returns the current CPU's idea of this value, unless
  *       it happens to be less than another CPU's previously determined value.
  */
 static uint64_t
-xen_fetch_vcpu_time(void)
+xen_fetch_vcpu_time(struct vcpu_info *vcpu)
 {
 	struct vcpu_time_info dst;
 	struct vcpu_time_info *src;
 	uint32_t pre_version;
 	uint64_t now;
 	volatile uint64_t last;
-	struct vcpu_info *vcpu = DPCPU_GET(vcpu_info);
 
 	src = &vcpu->time;
 
-	critical_enter();
 	do {
 		pre_version = xen_fetch_vcpu_tinfo(&dst, src);
 		barrier();
_at__at_ -266,16 +266,19 _at__at_ xen_fetch_vcpu_time(void)
 		}
 	} while (!atomic_cmpset_64(&xen_timer_last_time, last, now));
 
-	critical_exit();
-
 	return (now);
 }
 
 static uint32_t
 xentimer_get_timecount(struct timecounter *tc)
 {
+	uint32_t xen_time;
 
-	return ((uint32_t)xen_fetch_vcpu_time() & UINT_MAX);
+	critical_enter();
+	xen_time = (uint32_t)xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)) & UINT_MAX;
+	critical_exit();
+
+	return (xen_time);
 }
 
 /**
_at__at_ -305,7 +308,12 _at__at_ xen_fetch_wallclock(struct timespec *ts)
 static void
 xen_fetch_uptime(struct timespec *ts)
 {
-	uint64_t uptime = xen_fetch_vcpu_time();
+	uint64_t uptime;
+
+	critical_enter();
+	uptime = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info));
+	critical_exit();
+
 	ts->tv_sec = uptime / NSEC_IN_SEC;
 	ts->tv_nsec = uptime % NSEC_IN_SEC;
 }
_at__at_ -354,7 +362,7 _at__at_ xentimer_intr(void *arg)
 	struct xentimer_softc *sc = (struct xentimer_softc *)arg;
 	struct xentimer_pcpu_data *pcpu = DPCPU_PTR(xentimer_pcpu);
 
-	pcpu->last_processed = xen_fetch_vcpu_time();
+	pcpu->last_processed = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info));
 	if (pcpu->timer != 0 && sc->et.et_active)
 		sc->et.et_event_cb(&sc->et, sc->et.et_arg);
 
_at__at_ -415,7 +423,10 _at__at_ xentimer_et_start(struct eventtimer *et,
 	do {
 		if (++i == 60)
 			panic("can't schedule timer");
-		next_time = xen_fetch_vcpu_time() + first_in_ns;
+		critical_enter();
+		next_time = xen_fetch_vcpu_time(DPCPU_GET(vcpu_info)) +
+		            first_in_ns;
+		critical_exit();
 		error = xentimer_vcpu_start_timer(cpu, next_time);
 	} while (error == -ETIME);
 
-- 
1.7.7.5 (Apple Git-26)
Received on Tue Jan 14 2014 - 14:00:11 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:40:46 UTC