From 2d24d386afb2debdcfd0eb0aa496b2642ce2e7b7 Mon Sep 17 00:00:00 2001 From: Hans Rosenfeld Date: Mon, 11 Jun 2018 20:47:47 +0000 Subject: OS-6988 bhyve wastes 1GB of RAM for each VM using more than 3GB Reviewed by: John Levon Reviewed by: Patrick Mooney Approved by: Patrick Mooney --- usr/src/lib/libvmmapi/common/vmmapi.c | 40 +++++++++++++++++++++++++++++++++++ usr/src/lib/libvmmapi/common/vmmapi.h | 5 +++++ usr/src/uts/i86pc/io/vmm/vmm.c | 4 ++++ 3 files changed, 49 insertions(+) diff --git a/usr/src/lib/libvmmapi/common/vmmapi.c b/usr/src/lib/libvmmapi/common/vmmapi.c index de86e2b9bd..7ded3a82b5 100644 --- a/usr/src/lib/libvmmapi/common/vmmapi.c +++ b/usr/src/lib/libvmmapi/common/vmmapi.c @@ -384,13 +384,26 @@ vm_get_memseg(struct vmctx *ctx, int segid, size_t *lenp, char *namebuf, } static int +#ifdef __FreeBSD__ setup_memory_segment(struct vmctx *ctx, vm_paddr_t gpa, size_t len, char *base) +#else +setup_memory_segment(struct vmctx *ctx, int segid, vm_paddr_t gpa, size_t len, + char *base) +#endif { char *ptr; int error, flags; /* Map 'len' bytes starting at 'gpa' in the guest address space */ +#ifdef __FreeBSD__ error = vm_mmap_memseg(ctx, gpa, VM_SYSMEM, gpa, len, PROT_ALL); +#else + /* + * As we use two segments for lowmem/highmem the offset within the + * segment is 0 on illumos. + */ + error = vm_mmap_memseg(ctx, gpa, segid, 0, len, PROT_ALL); +#endif if (error) return (error); @@ -430,9 +443,11 @@ vm_setup_memory(struct vmctx *ctx, size_t memsize, enum vm_mmap_style vms) objsize = ctx->lowmem; } +#ifdef __FreeBSD__ error = vm_alloc_memseg(ctx, VM_SYSMEM, objsize, NULL); if (error) return (error); +#endif /* * Stake out a contiguous region covering the guest physical memory @@ -445,6 +460,8 @@ vm_setup_memory(struct vmctx *ctx, size_t memsize, enum vm_mmap_style vms) return (-1); baseaddr = ptr + VM_MMAP_GUARD_SIZE; + +#ifdef __FreeBSD__ if (ctx->highmem > 0) { gpa = 4*GB; len = ctx->highmem; @@ -460,6 +477,29 @@ vm_setup_memory(struct vmctx *ctx, size_t memsize, enum vm_mmap_style vms) if (error) return (error); } +#else + if (ctx->highmem > 0) { + error = vm_alloc_memseg(ctx, VM_HIGHMEM, ctx->highmem, NULL); + if (error) + return (error); + gpa = 4*GB; + len = ctx->highmem; + error = setup_memory_segment(ctx, VM_HIGHMEM, gpa, len, baseaddr); + if (error) + return (error); + } + + if (ctx->lowmem > 0) { + error = vm_alloc_memseg(ctx, VM_LOWMEM, ctx->lowmem, NULL); + if (error) + return (error); + gpa = 0; + len = ctx->lowmem; + error = setup_memory_segment(ctx, VM_LOWMEM, gpa, len, baseaddr); + if (error) + return (error); + } +#endif ctx->baseaddr = baseaddr; diff --git a/usr/src/lib/libvmmapi/common/vmmapi.h b/usr/src/lib/libvmmapi/common/vmmapi.h index cfceafc6f4..43481fefbe 100644 --- a/usr/src/lib/libvmmapi/common/vmmapi.h +++ b/usr/src/lib/libvmmapi/common/vmmapi.h @@ -78,7 +78,12 @@ enum vm_mmap_style { * - the remaining identifiers can be used to create devmem segments. */ enum { +#ifdef __FreeBSD__ VM_SYSMEM, +#else + VM_LOWMEM, + VM_HIGHMEM, +#endif VM_BOOTROM, VM_FRAMEBUFFER, }; diff --git a/usr/src/uts/i86pc/io/vmm/vmm.c b/usr/src/uts/i86pc/io/vmm/vmm.c index c4988c6d72..2bb50de66f 100644 --- a/usr/src/uts/i86pc/io/vmm/vmm.c +++ b/usr/src/uts/i86pc/io/vmm/vmm.c @@ -146,7 +146,11 @@ struct mem_seg { bool sysmem; struct vm_object *object; }; +#ifdef __FreeBSD__ #define VM_MAX_MEMSEGS 3 +#else +#define VM_MAX_MEMSEGS 4 +#endif struct mem_map { vm_paddr_t gpa; -- cgit v1.2.3