- Non-debug
dev-bhyve
branch with this as last commit:commit dc994c4720f1b6cbd88011c5de076e580a8deeab Author: Mike Gerdts <[email protected]> Date: Thu Feb 15 21:40:29 2018 +0000 OS-6558 cleanup to match master push
- Platform Image:
$ mls /mgerdts/public/bhyve-20180221-nd platform-20180214T165906Z.iso platform-20180214T165906Z.tgz platform-20180214T165906Z.usb.bz2
- Guest running Ubuntu 17.10, 16 vcpu, 48 GB RAM
$ cd /builds/linux
$ make -j 32 clean; time make -j 32
...
real 11m32.055s
user 139m2.487s
sys 20m27.720s
Same as above, but every struct vcpu
is guaranteed to be aligned.
commit 442f94ec0bd6cdeaefbdda627f08036be4378849
Author: Mike Gerdts <[email protected]>
Date: Thu Feb 22 04:10:22 2018 +0000
avoid false sharing in vcpu array
diff --git a/usr/src/uts/i86pc/io/vmm/vmm.c b/usr/src/uts/i86pc/io/vmm/vmm.c
index 0e55799..7dd48be 100644
--- a/usr/src/uts/i86pc/io/vmm/vmm.c
+++ b/usr/src/uts/i86pc/io/vmm/vmm.c
@@ -124,6 +124,7 @@ struct vcpu {
void *stats; /* (a,i) statistics */
struct vm_exit exitinfo; /* (x) exit reason and collateral */
uint64_t nextrip; /* (x) next instruction to execute */
+ uint64_t pad; /* avoid false sharing */
};
#define vcpu_lock_initialized(v) mtx_initialized(&((v)->mtx))
@@ -180,7 +181,7 @@ struct vm {
struct mem_seg mem_segs[VM_MAX_MEMSEGS]; /* (o) guest memory regions */
struct vmspace *vmspace; /* (o) guest's address space */
char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
- struct vcpu vcpu[VM_MAXCPU]; /* (i) guest vcpus */
+ struct vcpu *vcpu; /* (i) guest vcpus */
#ifndef __FreeBSD__
krwlock_t ioport_rwlock;
list_t ioport_hooks;
@@ -306,6 +307,9 @@ vcpu_init(struct vm *vm, int vcpu_id, bool create)
vcpu = &vm->vcpu[vcpu_id];
+ KASSERT(((uintptr_t)vcpu & (CPU_CACHE_COHERENCE_SIZE - 1)) == 0,
+ ("vcpu_init: cpu %d not aligned on cache line", vcpu_id));
+
if (create) {
#ifdef __FreeBSD__
KASSERT(!vcpu_lock_initialized(vcpu), ("vcpu %d already "
@@ -504,6 +508,10 @@ vm_init(struct vm *vm, bool create)
vm->suspend = 0;
CPU_ZERO(&vm->suspended_cpus);
+ if (create) {
+ vm->vcpu = kmem_zalloc(VM_MAXCPU * sizeof (*vm->vcpu),
+ KM_SLEEP);
+ }
for (i = 0; i < VM_MAXCPU; i++)
vcpu_init(vm, i, create);
}
Verified with:
[root@emy-17 /root]# mdb -k
Loading modules: [ unix genunix specfs dtrace mac cpu.generic uppc apix scsi_vhci ufs vmm ip hook neti sockfs arp usba xhci stmf_sbd stmf zfs mm lofs idm sata crypto random cpc logindmux ptm kvm sppp nsmb smbsrv nfs ]
> ::sizeof struct vcpu
sizeof (struct vcpu) = 0x100
> ::sizeof struct vcpu |=D
256
$ cd /builds/linux
$ make -j 32 clean; time make -j 32
...
real 11m9.153s
user 138m59.443s
sys 20m15.444s