Index: sys/arch/xen/xen/clock.c =================================================================== RCS file: /cvsroot/src/sys/arch/xen/xen/clock.c,v retrieving revision 1.64 diff -p -u -r1.64 clock.c --- sys/arch/xen/xen/clock.c 12 Jun 2016 09:08:09 -0000 1.64 +++ sys/arch/xen/xen/clock.c 29 Oct 2017 13:58:10 -0000 @@ -33,6 +33,7 @@ __KERNEL_RCSID(0, "$NetBSD: clock.c,v 1. #include <sys/param.h> #include <sys/systm.h> +#include <sys/lwp.h> #include <sys/time.h> #include <sys/timetc.h> #include <sys/timevar.h> @@ -118,22 +119,29 @@ get_time_values_from_xen(struct cpu_info KASSERT(mutex_owned(&tmutex)); do { - shadow->time_version = t->version; + if (1 & (shadow->time_version = t->version)) { + /* update in progress */ + SPINLOCK_BACKOFF_HOOK(); + continue; + } xen_rmb(); shadow->tsc_stamp = t->tsc_timestamp; shadow->system_time = t->system_time; shadow->freq_mul = t->tsc_to_system_mul; shadow->freq_shift = t->tsc_shift; xen_rmb(); - } while ((t->version & 1) || (shadow->time_version != t->version)); + } while (shadow->time_version != t->version); do { - tversion = HYPERVISOR_shared_info->wc_version; + if (1 & (tversion = HYPERVISOR_shared_info->wc_version)) { + /* update in progress */ + SPINLOCK_BACKOFF_HOOK(); + continue; + } xen_rmb(); shadow->ts.tv_sec = HYPERVISOR_shared_info->wc_sec; shadow->ts.tv_nsec = HYPERVISOR_shared_info->wc_nsec; xen_rmb(); - } while ((HYPERVISOR_shared_info->wc_version & 1) || - (tversion != HYPERVISOR_shared_info->wc_version)); + } while (tversion != HYPERVISOR_shared_info->wc_version); } /* @@ -228,6 +236,7 @@ xen_wall_time(struct timespec *wt) { uint64_t nsec; + int bound = curlwp_bind(); struct cpu_info *ci = curcpu(); volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid]; @@ -243,6 +252,8 @@ xen_wall_time(struct timespec *wt) } while (!time_values_up_to_date(ci)); mutex_exit(&tmutex); + curlwp_bindx(bound); + wt->tv_sec += nsec / 1000000000L; wt->tv_nsec = nsec % 1000000000L; } @@ -313,6 +324,7 @@ startrtclock(void) void xen_delay(unsigned int n) { + int bound = curlwp_bind(); struct cpu_info *ci = curcpu(); volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid]; @@ -335,8 +347,6 @@ xen_delay(unsigned int n) cc2 = cpu_counter(); while (cc2 < when) cc2 = cpu_counter(); - - return; } else { uint64_t when; @@ -352,6 +362,7 @@ xen_delay(unsigned int n) } mutex_exit(&tmutex); } + curlwp_bindx(bound); } #ifdef DOM0OPS @@ -400,12 +411,15 @@ xen_get_timecount(struct timecounter *tc { uint64_t ns; + int bound = curlwp_bind(); struct cpu_info *ci = curcpu(); mutex_enter(&tmutex); ns = get_vcpu_time(ci) - xen_clock_bias[ci->ci_cpuid]; mutex_exit(&tmutex); + curlwp_bindx(bound); + return (u_int)ns; } @@ -422,6 +436,8 @@ xen_initclocks(void) int err __diagused; static bool tcdone = false; + /* XXX KASSERT whatever mechanism binds us to a CPU */ + struct cpu_info *ci = curcpu(); volatile struct shadow *shadow = &ci_shadow[ci->ci_cpuid]; @@ -578,6 +594,7 @@ setstatclockrate(int arg) void idle_block(void) { + KASSERT(curlwp->l_pflag & LP_BOUND); /* idle loop thread */ KASSERT(curcpu()->ci_ipending == 0); HYPERVISOR_block(); }