On Thu, Aug 25, 2022 at 03:57:48PM +1000, Jonathan Gray wrote: > On Wed, Aug 24, 2022 at 11:05:30PM -0500, Scott Cheloha wrote: > > On Wed, Aug 24, 2022 at 05:51:14PM +1000, Jonathan Gray wrote: > > > On Tue, Aug 23, 2022 at 12:20:39PM -0500, Scott Cheloha wrote: > > > > > Hyper-V generation 1 VMs are bios boot with emulation of the usual > > > > > devices. 32-bit and 64-bit guests. > > > > > > > > > > Hyper-V generation 2 VMs are 64-bit uefi with paravirtualised devices. > > > > > 64-bit guests only. > > > > > > > > > > There is no 8254 in generation 2. > > > > > No HPET in either generation. > > > > > > > > > > hv_delay uses the "Partition Reference Counter MSR" described in > > > > > https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/tlfs/timers > > > > > It seems it is available in both generations and could be used from > > > > > i386? > > > > > > > > > > From reading that page hv_delay() should be preferred over > > > > > lapic_delay() > > > > > > > > Alright, I have nudged hv_delay's quality up over lapic_delay's > > > > quality. > > > > > > Before these changes, tsc is probed before pvbus. Do the tsc sanity > > > checks result in it not being considered an option on hyper-v? I think > > > the tsc_delay and hv_delay numbers should be swapped in a later commit. > > > It is unclear if that would change the final delay_func setting. > > > > Why would we prefer hv_delay() to tsc_delay() if we had a > > constant/invariant TSC available in our Hyper-V guest? > > > > When patrick@ emailed me last year about issues with delay(9) on > > Hyper-V, he started by saying that the root of the problem was that > > the OpenBSD guest was not opting to use tsc_delay() because the host > > wasn't reporting a constant/invariant TSC. So the guest was trying to > > use i8254_delay(), which was impossible because Hyper-V Gen2 guests > > don't have an i8254. Hence, hv_delay() was added to the tree. > > > > So, my understanding is that the addition of hv_delay() does not mean > > tsc_delay() is worse than hv_delay(). hv_delay() was added because > > tsc_delay() isn't always an option and (to our surprise) neither is > > i8254_delay(). > > I'm not clear on when rdtsc and rdmsr would cause a vm exit. > Presumably the reference tsc page is provided to avoid that, > but we don't use it. rdtsc and rdmsr don't always cause an exit. > > The wording of Microsoft's "Hypervisor Top Level Functional > Specification" reads as the interface is only available when > the underlying machine has a constant frequency tsc. It also > makes the point that the interface being in time not cycles avoids > problems when the tsc frequency changes on live migration. > > "12.3 Partition Reference Time Enlightenment > > The partition reference time enlightenment presents a reference > time source to a partition which does not require an intercept into > the hypervisor. This enlightenment is available only when the > underlying platform provides support of an invariant processor Time > Stamp Counter (TSC), or iTSC. In such platforms, the processor TSC > frequency remains constant irrespective of changes in the processor's > clock frequency due to the use of power management states such as > ACPI processor performance states, processor idle sleep states (ACPI > C-states), etc. > > The partition reference time enlightenment uses a virtual TSC value, > an offset and a multiplier to enable a guest partition to compute > the normalized reference time since partition creation, in 100nS > units. The mechanism also allows a guest partition to atomically > compute the reference time when the guest partition is migrated to > a platform with a different TSC rate, and provides a fallback > mechanism to support migration to platforms without the constant > rate TSC feature. > > This facility is not intended to be used a source of wall clock > time, since the reference time computed using this facility will > appear to stop during the time that a guest partition is saved until > the subsequent restore."
If hv_delay() never causes a vm exit, but tsc_delay() *might* cause a vm exit, and both have microsecond or better resolution, then hv_delay() is the preferable delay(9) implementation where it is available because vm exits have ambiguous overhead. If that seems sensible to you, I'll commit this switch. Index: arch/amd64/amd64/tsc.c =================================================================== RCS file: /cvs/src/sys/arch/amd64/amd64/tsc.c,v retrieving revision 1.26 diff -u -p -r1.26 tsc.c --- arch/amd64/amd64/tsc.c 25 Aug 2022 17:38:16 -0000 1.26 +++ arch/amd64/amd64/tsc.c 29 Aug 2022 16:58:25 -0000 @@ -109,7 +109,7 @@ tsc_identify(struct cpu_info *ci) tsc_frequency = tsc_freq_cpuid(ci); if (tsc_frequency > 0) - delay_init(tsc_delay, 5000); + delay_init(tsc_delay, 4000); } static inline int Index: dev/pv/pvbus.c =================================================================== RCS file: /cvs/src/sys/dev/pv/pvbus.c,v retrieving revision 1.25 diff -u -p -r1.25 pvbus.c --- dev/pv/pvbus.c 25 Aug 2022 17:38:16 -0000 1.25 +++ dev/pv/pvbus.c 29 Aug 2022 16:58:26 -0000 @@ -320,7 +320,7 @@ pvbus_hyperv(struct pvbus_hv *hv) #if NHYPERV > 0 if (hv->hv_features & CPUID_HV_MSR_TIME_REFCNT) - delay_init(hv_delay, 4000); + delay_init(hv_delay, 5000); #endif }