Changes from Christian Limpach to improve timekeeping on NetBSD/xen by
actually adjusting the time correctly (calling hardclock as needed, not just blindly every time Xen schedules us) based on Xen's idea of the time in the shared page. Xen source repo change info: ChangeSet 2004/09/22 13:47:22+01:00 cl349@freefall.cl.cam.ac.uk Fix time. netbsd-2.0-xen-sparse/sys/arch/xen/xen/clock.c 2004/09/22 13:47:21+01:00 cl349@freefall.cl.cam.ac.uk +28 -3 Don't call hardclock on spurious timer interrupt and call hardclock for missed interrupts. netbsd-2.0-xen-sparse/sys/arch/xen/conf/XEN 2004/09/22 13:47:21+01:00 cl349@freefall.cl.cam.ac.uk +0 -1 Don't need custom HZ value any longer. : ----------------------------------------------------------------------
This commit is contained in:
parent
9d64f3ebc8
commit
849c42925b
@ -1,4 +1,4 @@
|
||||
# $NetBSD: GENERIC,v 1.15 2004/09/04 23:29:57 manu Exp $
|
||||
# $NetBSD: GENERIC,v 1.16 2004/09/23 02:24:22 tls Exp $
|
||||
# NetBSD: GENERIC,v 1.596 2004/04/07 13:13:59 augustss Exp
|
||||
#
|
||||
# GENERIC machine description file
|
||||
@ -23,14 +23,13 @@ include "arch/xen/conf/std.xen"
|
||||
|
||||
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
|
||||
|
||||
#ident "GENERIC-$Revision: 1.15 $"
|
||||
#ident "GENERIC-$Revision: 1.16 $"
|
||||
|
||||
maxusers 32 # estimated number of users
|
||||
|
||||
#
|
||||
options XEN
|
||||
options DOM0OPS
|
||||
options HZ=50
|
||||
|
||||
# CPU support. At least one is REQUIRED.
|
||||
options I686_CPU
|
||||
@ -55,7 +54,7 @@ options I686_CPU
|
||||
options INSECURE # disable kernel security levels - X needs this
|
||||
|
||||
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
|
||||
#options NTP # NTP phase/frequency locked loop
|
||||
options NTP # NTP phase/frequency locked loop
|
||||
#options NO_TSC_TIME # Don't use TSC microtime, even if available.
|
||||
# Improves time behavior under VMware.
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# $NetBSD: XEN,v 1.12 2004/09/04 23:29:57 manu Exp $
|
||||
# $NetBSD: XEN,v 1.13 2004/09/23 02:24:22 tls Exp $
|
||||
|
||||
include "arch/xen/conf/std.xen"
|
||||
|
||||
@ -13,7 +13,6 @@ maxusers 32 # estimated number of users
|
||||
#
|
||||
options XEN
|
||||
options DOM0OPS
|
||||
options HZ=50
|
||||
|
||||
#options I586_CPU
|
||||
options I686_CPU
|
||||
@ -29,7 +28,7 @@ options I686_CPU
|
||||
options INSECURE # disable kernel security levels - X needs this
|
||||
|
||||
options RTC_OFFSET=0 # hardware clock is this many mins. west of GMT
|
||||
#options NTP # NTP phase/frequency locked loop
|
||||
options NTP # NTP phase/frequency locked loop
|
||||
|
||||
options KTRACE # system call tracing via ktrace(1)
|
||||
#options SYSTRACE # system call vetting via systrace(1)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: locore.S,v 1.5 2004/04/26 22:05:04 cl Exp $ */
|
||||
/* $NetBSD: locore.S,v 1.6 2004/09/23 02:24:22 tls Exp $ */
|
||||
/* NetBSD: locore.S,v 1.26 2004/04/12 13:17:46 yamt Exp */
|
||||
|
||||
/*-
|
||||
@ -1588,6 +1588,7 @@ idle_zero:
|
||||
pushl $IPL_NONE
|
||||
call _C_LABEL(Xspllower)
|
||||
addl $4,%esp
|
||||
jmp idle_start
|
||||
4:
|
||||
call _C_LABEL(uvm_pageidlezero)
|
||||
CLI(%eax)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $ */
|
||||
/* $NetBSD: clock.c,v 1.7 2004/09/23 02:24:22 tls Exp $ */
|
||||
|
||||
/*
|
||||
*
|
||||
@ -34,7 +34,7 @@
|
||||
#include "opt_xen.h"
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.7 2004/09/23 02:24:22 tls Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -54,13 +54,17 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.6 2004/07/16 22:36:33 tls Exp $");
|
||||
static int xen_timer_handler(void *, struct trapframe *);
|
||||
|
||||
/* These are peridically updated in shared_info, and then copied here. */
|
||||
static unsigned long shadow_tsc_stamp;
|
||||
static u_int64_t shadow_system_time;
|
||||
static uint64_t shadow_tsc_stamp;
|
||||
static uint64_t shadow_system_time;
|
||||
static unsigned long shadow_time_version;
|
||||
static struct timeval shadow_tv;
|
||||
|
||||
static int timeset;
|
||||
|
||||
static uint64_t processed_system_time;
|
||||
|
||||
#define NS_PER_TICK (1000000000ULL/hz)
|
||||
|
||||
/*
|
||||
* Reads a consistent set of time-base values from Xen, into a shadow data
|
||||
* area. Must be called at splclock.
|
||||
@ -73,12 +77,23 @@ get_time_values_from_xen(void)
|
||||
__insn_barrier();
|
||||
shadow_tv.tv_sec = HYPERVISOR_shared_info->wc_sec;
|
||||
shadow_tv.tv_usec = HYPERVISOR_shared_info->wc_usec;
|
||||
shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp;
|
||||
shadow_tsc_stamp = HYPERVISOR_shared_info->tsc_timestamp <<
|
||||
HYPERVISOR_shared_info->rdtsc_bitshift;
|
||||
shadow_system_time = HYPERVISOR_shared_info->system_time;
|
||||
__insn_barrier();
|
||||
} while (shadow_time_version != HYPERVISOR_shared_info->time_version1);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_tsc_offset_ns(void)
|
||||
{
|
||||
uint32_t tsc_delta;
|
||||
struct cpu_info *ci = curcpu();
|
||||
|
||||
tsc_delta = cpu_counter32() - shadow_tsc_stamp;
|
||||
return tsc_delta * 1000000000 / cpu_frequency(ci);
|
||||
}
|
||||
|
||||
void
|
||||
inittodr(time_t base)
|
||||
{
|
||||
@ -189,6 +204,9 @@ void
|
||||
xen_initclocks()
|
||||
{
|
||||
|
||||
get_time_values_from_xen();
|
||||
processed_system_time = shadow_system_time;
|
||||
|
||||
event_set_handler(_EVENT_TIMER, (int (*)(void *))xen_timer_handler,
|
||||
NULL, IPL_CLOCK);
|
||||
hypervisor_enable_event(_EVENT_TIMER);
|
||||
@ -197,6 +215,8 @@ xen_initclocks()
|
||||
static int
|
||||
xen_timer_handler(void *arg, struct trapframe *regs)
|
||||
{
|
||||
int64_t delta;
|
||||
|
||||
#if defined(I586_CPU) || defined(I686_CPU)
|
||||
static int microset_iter; /* call cc_microset once/sec */
|
||||
struct cpu_info *ci = curcpu();
|
||||
@ -222,7 +242,13 @@ xen_timer_handler(void *arg, struct trapframe *regs)
|
||||
|
||||
get_time_values_from_xen();
|
||||
|
||||
hardclock((struct clockframe *)regs);
|
||||
delta = (int64_t)(shadow_system_time + get_tsc_offset_ns() -
|
||||
processed_system_time);
|
||||
while (delta >= NS_PER_TICK) {
|
||||
hardclock((struct clockframe *)regs);
|
||||
delta -= NS_PER_TICK;
|
||||
processed_system_time += NS_PER_TICK;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user