On Wed, Jul 25, 2012 at 11:14, Matthew Dempsky wrote: > In vmt_tick() we could notice anytime the reported sensor value jumps > significantly and then wind forward the clocks like we do when > recovering from ACPI sleep.
I like this, and I think it even works. Scary warnings about no locking in kern_tc.c aside. I had a look, and there's three functions. tc_setclock - doesn't seem to do much itself. What are the consquences of timehands->th_offset getting raced? timeout_adjust_ticks - does its own locking, safe. tc_windup - this function is "slightly magic". mostly operates on the next timehands, then swaps at the end. I think calling two windups at the same time would be bad, but calling this in parallel with other time code doesn't appear harmful. So how much locking do we need? Protect tc_windup with a mutex? Maybe tc_setclock should operate on the next timehands as well? Anyway, here's the diff. I don't mean to suggest we literally want this, but it does what I want. Of course, if somebody wanted to test a vm with a wrong clock, they're not going to have much luck. Should the vmt clock bludgeon be optional or not? Index: vmt.c =================================================================== RCS file: /cvs/src/sys/dev/vmt.c,v retrieving revision 1.11 diff -u -p -r1.11 vmt.c --- vmt.c 27 Jan 2011 21:29:25 -0000 1.11 +++ vmt.c 25 Jul 2012 19:44:20 -0000 @@ -38,6 +38,7 @@ #include <sys/syslog.h> #include <sys/proc.h> #include <sys/socket.h> +#include <sys/timetc.h> #include <net/if.h> #include <netinet/in.h> @@ -356,6 +357,7 @@ vmt_tick(void *xarg) struct vm_backdoor frame; struct timeval *guest = &sc->sc_sensor.tv; struct timeval host, diff; + struct timespec ts; microtime(guest); @@ -374,6 +376,11 @@ vmt_tick(void *xarg) sc->sc_sensor.value = (u_int64_t)diff.tv_sec * 1000000000LL + (u_int64_t)diff.tv_usec * 1000LL; sc->sc_sensor.status = SENSOR_S_OK; + + if (diff.tv_sec > 60 || diff.tv_sec < -60) { + TIMEVAL_TO_TIMESPEC(&host, &ts); + tc_setclock(&ts); + } } else { sc->sc_sensor.status = SENSOR_S_UNKNOWN; } @@ -381,7 +388,7 @@ vmt_tick(void *xarg) vmt_update_guest_info(sc); vmt_update_guest_uptime(sc); - timeout_add_sec(&sc->sc_tick, 15); + timeout_add_sec(&sc->sc_tick, 1); } void