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:
tls 2004-09-23 02:24:22 +00:00
parent 9d64f3ebc8
commit 849c42925b
4 changed files with 39 additions and 14 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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)

View File

@ -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;
}