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 MP-fy clock. per-cpu hardclock(). Us...
details: https://anonhg.NetBSD.org/src/rev/19a72696cb44
branches: cherry-xenmp
changeset: 765633:19a72696cb44
user: cherry <cherry%NetBSD.org@localhost>
date: Tue Aug 23 16:19:12 2011 +0000
description:
MP-fy clock. per-cpu hardclock(). Use the periodic timer, instead of the one-shot reload.
idle_loop() does not block the domain anymore. Instead, it yields to the hypervisor(). We can thus remove the one-shot "wakeup" timer.
diffstat:
sys/arch/xen/xen/clock.c | 93 +++++++++++++++++++++++------------------------
1 files changed, 45 insertions(+), 48 deletions(-)
diffs (245 lines):
diff -r 67bb5e1ffac3 -r 19a72696cb44 sys/arch/xen/xen/clock.c
--- a/sys/arch/xen/xen/clock.c Mon Aug 22 17:39:19 2011 +0000
+++ b/sys/arch/xen/xen/clock.c Tue Aug 23 16:19:12 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: clock.c,v 1.54.6.2 2011/07/25 17:29:43 cherry Exp $ */
+/* $NetBSD: clock.c,v 1.54.6.3 2011/08/23 16:19:12 cherry Exp $ */
/*
*
@@ -29,7 +29,7 @@
#include "opt_xen.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.54.6.2 2011/07/25 17:29:43 cherry Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.54.6.3 2011/08/23 16:19:12 cherry Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
@@ -38,12 +38,14 @@
#include <sys/timetc.h>
#include <sys/timevar.h>
#include <sys/kernel.h>
+#include <sys/mutex.h>
#include <sys/device.h>
#include <sys/sysctl.h>
#include <xen/xen.h>
#include <xen/hypervisor.h>
#include <xen/evtchn.h>
+#include <xen/xen3-public/vcpu.h>
#include <machine/cpu_counter.h>
#include <dev/clock_subr.h>
@@ -80,6 +82,8 @@
/* 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.
*/
@@ -90,7 +94,7 @@
* back to maintain the illusion that hardclock(9) was called when it
* was supposed to be, not when Xen got around to scheduling us.
*/
-static volatile uint64_t xen_clock_bias[MAXCPUS];
+static volatile uint64_t xen_clock_bias;
#ifdef DOM0OPS
/* If we're dom0, send our time to Xen every minute or so. */
@@ -245,18 +249,17 @@
xen_wall_time(struct timespec *wt)
{
uint64_t nsec;
- int s;
struct cpu_info *ci = &cpu_info_primary;
volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
- s = splhigh();
+ mutex_enter(&tmutex);
get_time_values_from_xen(ci);
*wt = shadow->ts;
nsec = wt->tv_nsec;
/* Under Xen3, this is the wall time less system time */
nsec += get_system_time();
- splx(s);
+ mutex_exit(&tmutex);
wt->tv_sec += nsec / 1000000000L;
wt->tv_nsec = nsec % 1000000000L;
}
@@ -282,8 +285,6 @@
#else
xen_platform_op_t op;
#endif
- int s;
-
if (xendomain_is_privileged()) {
/* needs to set the RTC chip too */
struct clock_ymdhms dt;
@@ -298,9 +299,9 @@
/* XXX is rtc_offset handled correctly everywhere? */
op.u.settime.secs = tvp->tv_sec;
op.u.settime.nsecs = tvp->tv_usec * 1000;
- s = splhigh();
+ mutex_enter(&tmutex);
op.u.settime.system_time = get_system_time();
- splx(s);
+ mutex_exit(&tmutex);
#if __XEN_INTERFACE_VERSION__ < 0x00030204
return HYPERVISOR_dom0_op(&op);
#else
@@ -355,18 +356,17 @@
return;
} else {
uint64_t when;
- int s;
/* for large delays, shadow->system_time is OK */
- s = splhigh();
+ mutex_enter(&tmutex);
get_time_values_from_xen(ci);
when = shadow->system_time + n * 1000;
while (shadow->system_time < when) {
- splx(s);
- s = splhigh();
+ mutex_exit(&tmutex);
+ mutex_enter(&tmutex);
get_time_values_from_xen(ci);
}
- splx(s);
+ mutex_exit(&tmutex);
}
}
@@ -416,11 +416,10 @@
xen_get_timecount(struct timecounter *tc)
{
uint64_t ns;
- int s;
- s = splhigh();
- ns = get_system_time() - xen_clock_bias[0];
- splx(s);
+ mutex_enter(&tmutex);
+ ns = get_system_time() - xen_clock_bias;
+ mutex_exit(&tmutex);
return (u_int)ns;
}
@@ -437,13 +436,15 @@
void
xen_initclocks(void)
{
- int evtch;
+ int err, evtch;
static bool tcdone = false;
+ struct vcpu_set_periodic_timer hardclock_period = { NS_PER_TICK };
+
struct cpu_info *ci = curcpu();
volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid];
- xen_clock_bias[ci->ci_cpuid] = 0;
+ xen_clock_bias = 0;
evcnt_attach_dynamic(&hardclock_called[ci->ci_cpuid],
EVCNT_TYPE_INTR,
@@ -462,10 +463,18 @@
get_time_values_from_xen(ci);
vcpu_system_time[ci->ci_cpuid] = shadow->system_time;
if (!tcdone) { /* Do this only once */
+ mutex_init(&tmutex, MUTEX_DEFAULT, IPL_HIGH);
tc_init(&xen_timecounter);
}
/* The splhigh requirements start here. */
+ /* Set hardclock() frequency */
+ err = HYPERVISOR_vcpu_op(VCPUOP_set_periodic_timer,
+ ci->ci_cpuid,
+ &hardclock_period);
+
+ KASSERT(err == 0);
+
event_set_handler(evtch, (int (*)(void *))xen_timer_handler,
ci, IPL_CLOCK, "clock");
hypervisor_enable_event(evtch);
@@ -493,43 +502,30 @@
xen_timer_handler(void *arg, struct intrframe *regs)
{
int64_t delta;
- int s, ticks_done;
struct cpu_info *ci = curcpu();
+ KASSERT(arg == ci);
+ mutex_enter(&tmutex);
- s = splhigh();
-#if 0
- get_time_values_from_xen(ci);
-#endif
delta = (int64_t)(get_vcpu_time(ci) - vcpu_system_time[ci->ci_cpuid]);
- splx(s);
+ mutex_exit(&tmutex);
- ticks_done = 0;
/* Several ticks may have passed without our being run; catch up. */
while (delta >= (int64_t)NS_PER_TICK) {
- ++ticks_done;
- s = splhigh();
+ mutex_enter(&tmutex);
vcpu_system_time[ci->ci_cpuid] += NS_PER_TICK;
- xen_clock_bias[ci->ci_cpuid] = (delta -= NS_PER_TICK);
- splx(s);
+ xen_clock_bias = (delta -= NS_PER_TICK);
+ mutex_exit(&tmutex);
hardclock((struct clockframe *)regs);
hardclock_called[ci->ci_cpuid].ev_count++;
}
- if (xen_clock_bias[ci->ci_cpuid]) {
- s = splhigh();
- xen_clock_bias[ci->ci_cpuid] = 0;
- splx(s);
+ if (xen_clock_bias) {
+ mutex_enter(&tmutex);
+ xen_clock_bias = 0;
+ mutex_exit(&tmutex);
}
- /*
- * Re-arm the timer here, if needed; Xen's auto-ticking while runnable
- * is useful only for HZ==100, and even then may be out of phase with
- * the vcpu_system_time[ci->ci_cpuid] steps.
- */
- if (ticks_done != 0)
- HYPERVISOR_set_timer_op(vcpu_system_time[ci->ci_cpuid] + NS_PER_TICK);
-
return 0;
}
@@ -542,7 +538,6 @@
idle_block(void)
{
int r;
- struct cpu_info *ci = curcpu();
/*
* We set the timer to when we expect the next timer
@@ -550,9 +545,11 @@
* easily find out when we will have more work (callouts) to
* process from hardclock.
*/
- r = HYPERVISOR_set_timer_op(vcpu_system_time[ci->ci_cpuid] + NS_PER_TICK);
- if (r == 0)
- HYPERVISOR_block();
+ r = 0; //HYPERVISOR_set_timer_op(vcpu_system_time[ci->ci_cpuid] + NS_PER_TICK);
+ if (r == 0) {
+ HYPERVISOR_yield();
+ __sti();
+ }
else
__sti();
}
Home |
Main Index |
Thread Index |
Old Index