[Bug 216759] [kern] Memory speed with small blocks (1K) up to 35 times slower than host system (under QEMU emulation, but not only)

bugzilla-noreply at freebsd.org bugzilla-noreply at freebsd.org
Fri Mar 3 18:42:36 UTC 2017


https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=216759

--- Comment #14 from andrew at azar-a.net ---
Bob, this issue is a major one. I had to delve into almost academical works
around all available timers and their connection with virtualization.

Seems the only "correct" work is done by VMWare which does corrections to
broken TSC. I say "correct" because it still requires a special reliable_tsc
flag on virtual CPU that the OS believes it. Reason? Because virtualization
software does not provide direct access there might be time outs (say host is
doing something) which leads to skewing of time or even negative timer.

Here's the VMWare "fix":

static void
tsc_freq_vmware(void)
{
        u_int regs[4];

        if (hv_high >= 0x40000010) {
                do_cpuid(0x40000010, regs);
                tsc_freq = regs[0] * 1000;
        } else {
                vmware_hvcall(VMW_HVCMD_GETHZ, regs);
                if (regs[1] != UINT_MAX)
                        tsc_freq = regs[0] | ((uint64_t)regs[1] << 32);
        }
        tsc_is_invariant = 1;
}

static void
probe_tsc_freq(void)
{

...

        if (vm_guest == VM_GUEST_VMWARE) {
                tsc_freq_vmware();
                return;
        }
...

So this issue arrived on KVM, also with ease of migration it came to attention
that non-standardized timers lead to migration and suspend resume FAILURE.

KVM created kvmclock - which is a monstrosity and is still twice slower than
native TSC. And works only on Linux.

FreeBSD has no support for KVMClock. It has native support for VMWare in code,
however it does not recognize constant_tsc flag for some reason. This leads to
issue where OS under virtualization uses HPET or ACPI-PM which are slower on
some systems and are serial (why have them faster when you have TSC?).

Here's the code which kills the quality of TSC under KVM in FreeBSD:

static int
test_tsc(void)
{
        uint64_t *data, *tsc;
        u_int i, size, adj;

        if ((!smp_tsc && !tsc_is_invariant) || vm_guest)
                return (-100);

...

As you can see, KVM has no chance of going around. What takes sets the vm_guest
variable? Well it's the 'hypervisor' flag on CPU


Disabling which brings on a new can of worms (not working virtio drivers). And
I think it hits the SMP test which never happens (KVM gives 1 core)

-- 
You are receiving this mail because:
You are the assignee for the bug.


More information about the freebsd-virtualization mailing list