[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [UNIKRAFT/LIBMIMALLOC PATCH] Initial port of mimalloc to Unikraft
Hi, main-tree.patch is missing an `#include <uk/mimalloc.h>` in `lib/ukboot/boot.c`. We might want to do a v2 just for that, but waiting for the actual review to happen first. Hugo On Fri, 2020-06-26 at 10:27 +0200, Hugo Lefeuvre wrote: > --- > Config.uk | 16 ++ > Makefile.uk | 95 ++++++++++++ > README.md | 13 ++ > glue.c | 240 > ++++++++++++++++++++++++++++++ > include/uk/mimalloc.h | 49 ++++++ > include/uk/mimalloc_impl.h | 56 +++++++ > main-tree.patch | 30 ++++ > patches/adapt-to-unikraft-interface.patch | 160 ++++++++++++++++++++ > 8 files changed, 659 insertions(+) > create mode 100644 Config.uk > create mode 100644 Makefile.uk > create mode 100644 README.md > create mode 100644 glue.c > create mode 100644 include/uk/mimalloc.h > create mode 100644 include/uk/mimalloc_impl.h > create mode 100644 main-tree.patch > create mode 100644 patches/adapt-to-unikraft-interface.patch > > diff --git a/Config.uk b/Config.uk > new file mode 100644 > index 0000000..7ee8aee > --- /dev/null > +++ b/Config.uk > @@ -0,0 +1,16 @@ > +menuconfig LIBMIMALLOC > + bool "mimalloc - a compact general purpose allocator with > excellent performance" > + default n > + select LIBUKSCHED > + select LIBNEWLIBC > + select LIBPOSIX_SYSINFO > + select LIBPTHREAD_EMBEDDED > + select LIBUKALLOCREGION > +if LIBMIMALLOC > + config MIMALLOC_DEBUG > + int "Mimalloc debug level" > + default 0 > + config MIMALLOC_ASSERT > + bool "Mimalloc assertions" > + default n > +endif > diff --git a/Makefile.uk b/Makefile.uk > new file mode 100644 > index 0000000..0289cb2 > --- /dev/null > +++ b/Makefile.uk > @@ -0,0 +1,95 @@ > +# libmimalloc Makefile.uc > +# > +# Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > +# > +# > +# Copyright (c) 2017, NEC Europe Ltd., NEC Corporation. All rights > reserved. > +# > +# Redistribution and use in source and binary forms, with or > without > +# modification, are permitted provided that the following > conditions > +# are met: > +# > +# 1. Redistributions of source code must retain the above copyright > +# notice, this list of conditions and the following disclaimer. > +# 2. Redistributions in binary form must reproduce the above > copyright > +# notice, this list of conditions and the following disclaimer > in the > +# documentation and/or other materials provided with the > distribution. > +# 3. Neither the name of the copyright holder nor the names of its > +# contributors may be used to endorse or promote products > derived from > +# this software without specific prior written permission. > +# > +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > +# POSSIBILITY OF SUCH DAMAGE. > +# > + > +#################################################################### > ############ > +# Library registration > +#################################################################### > ############ > +$(eval $(call addlib_s,libmimalloc,$(CONFIG_LIBMIMALLOC))) > + > +#################################################################### > ############ > +# Sources > +#################################################################### > ############ > +LIBMIMALLOC_VERSION=1.6.1 > +LIBMIMALLOC_URL=https://github.com/microsoft/mimalloc/archive/v$(LIB > MIMALLOC_VERSION).zip > +LIBMIMALLOC_DIR=mimalloc-$(LIBMIMALLOC_VERSION) > + > +LIBMIMALLOC_PATCHDIR=$(LIBMIMALLOC_BASE)/patches > +$(eval $(call > fetch,libmimalloc,$(LIBMIMALLOC_URL),v$(LIBMIMALLOC_VERSION).zip)) > +$(eval $(call > patch,libmimalloc,$(LIBMIMALLOC_PATCHDIR),$(LIBMIMALLOC_DIR))) > + > +#################################################################### > ############ > +# Helpers > +#################################################################### > ############ > +LIBMIMALLOC=$(LIBMIMALLOC_ORIGIN)/$(LIBMIMALLOC_DIR) > + > +#################################################################### > ############ > +# Library includes > +#################################################################### > ############ > + > +CINCLUDES-$(CONFIG_LIBMIMALLOC) += -I$(LIBMIMALLOC_BASE) \ > + -I$(LIBMIMALLOC_BASE)/include \ > + -I$(LIBMIMALLOC)/include > + > +#################################################################### > ############ > +# Global flags > +#################################################################### > ############ > +LIBMIMALLOC_GLOBAL_FLAGS-$(CONFIG_MIMALLOC_ASSERT) += -DNDEBUG > +LIBMIMALLOC_CFLAGS-y += -Wall -Wextra -Wno-unknown-pragmas > -fvisibility=hidden \ > + -Wno-invalid-memory-model \ > + -D'MI_DEBUG=${CONFIG_MIMALLOC_DEBUG}'\ > + ${LIBMIMALLOC_GLOBAL_FLAGS-n} > + > +#################################################################### > ############ > +# Glue code > +#################################################################### > ############ > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC_BASE)/glue.c > + > +#################################################################### > ############ > +# Sources > +#################################################################### > ############ > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/stats.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/random.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/os.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/arena.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/region.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/segment.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/page.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/alloc.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/alloc-aligned.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/alloc-posix.c > +#LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/bitmap.inc.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/heap.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/options.c > +LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/init.c > +#LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/alloc-override.c > +#LIBMIMALLOC_SRCS-y += $(LIBMIMALLOC)/src/page-queue.c > diff --git a/README.md b/README.md > new file mode 100644 > index 0000000..a43779c > --- /dev/null > +++ b/README.md > @@ -0,0 +1,13 @@ > +Mimalloc for Unikraft > +===================== > + > +This is the port of the Mimalloc [0] general-purpose memory > allocator for > +Unikraft as an external library. > + > +How to use this allocator in your unikernel application: > + > +- apply main-tree.patch to the main tree > +- select "Mimalloc" in `ukboot > Default memory allocator` > +- pass at least 256MiB of memory to the unikernel > + > +[0] https://microsoft.github.io/mimalloc/ > diff --git a/glue.c b/glue.c > new file mode 100644 > index 0000000..d6f7d51 > --- /dev/null > +++ b/glue.c > @@ -0,0 +1,240 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > + * > + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights > reserved. > + * > + * Redistribution and use in source and binary forms, with or > without > + * modification, are permitted provided that the following > conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above > copyright > + * notice, this list of conditions and the following disclaimer > in the > + * documentation and/or other materials provided with the > distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products > derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#include <uk/mimalloc_impl.h> > +#include <uk/mimalloc.h> > +#include <mimalloc.h> > +#include <mimalloc-internal.h> // _mi_options_init() > +#include <uk/alloc_impl.h> > +#include <uk/print.h> > +#include <uk/allocregion.h> > +#include <uk/thread.h> // uk_thread_current() > +#include <uk/page.h> // round_pgup() > +#include <uk/sched.h> // uk_mimalloc_init_internal() > + > +/* Notes of Unikraft's Mimalloc port: > + * > + * 1. Minimum heap size required: 256MiB, which is the size of an > arena. > + * > + * 2. Maximum number of Mimalloc instances: > + * Mimalloc's current code base relies strongly on static > variables. Instead > + * of heavily patching it (and maintaining the patches) we simply > restrict > + * the maximum number of Mimalloc instances to one. > + * > + * 3. Early boot time allocator: > + * Mimalloc can only be initialized after pthread. However the > early boot > + * process including pthread's initialization itself requires a > functioning > + * memory allocator. We solve this problem by relying on > ukallocregion during > + * the early boot time. The transition to Mimalloc is triggered > as soon as > + * _tls_ready() returns true. We expect that this won't cause > significant > + * memory leak since memory allocated during EBT is typically not > freed. > + * > + * 4. Transition EBT allocator -> Mimalloc: > + * We transition as soon as the TLS has been allocated and the > %fs register > + * set. This is checked at every EBT allocation by inspecting > + * uk_thread_current()->prv which typically points to the thread > local > + * storage. Since memory allocations might happen during > Mimalloc's > + * initialization itself (e.g. calls to malloc() by pthread) the > early boot > + * time allocator continues to satisfy requests until Mimalloc is > ready > + * (after mi_process_load() returned). > + */ > + > +/* Minimum heap size (size of an arena) > + * TODO: can Mimalloc be reconfigured/patched to lower/remove this > limitation? > + */ > +#define MIN_HEAP_SIZE 268435456L > + > +/* Rely on ukallocregion to satisfy boot-time allocations */ > +static struct uk_alloc *__region_alloc; > + > +/* make sure that the transition from boot-time allocation to > Mimalloc is done > + * only once: calls to malloc() during Mimalloc initialization > should be > + * satisfied using the boot-time allocator. > + */ > +static int __initialized = 0; > + > +static inline int _tls_ready(void) > +{ > + /* Is the thread local storage ready? */ > + struct uk_thread *current = uk_thread_current(); > + return current && current->prv != NULL; > +} > + > +/* boot-time malloc interface */ > + > +static void uk_mimalloc_init_internal(struct uk_alloc *a); > + > +/* NOTE: not static, this is used in the mimalloc code base to > request memory > + * "from the OS" > + */ > +void *uk_mimalloc_region_malloc(struct uk_alloc *a, size_t size) > +{ > + /* detect call from main thread to leave boot time mode */ > + if (_tls_ready() && !__initialized) { > + uk_pr_debug("%s: leaving early boot-time allocation > mode\n", > + uk_thread_current()->name); > + __initialized = 1; > + uk_mimalloc_init_internal(a); > + > + /* satisfy request using new malloc interface */ > + return uk_malloc(a, size); > + } > + > + uk_pr_debug("allocating %zu from region allocator\n", size); > + > + return uk_malloc(__region_alloc, size); > +} > + > +static int uk_mimalloc_region_posix_memalign(struct uk_alloc *a > __unused, void **memptr, > + size_t align, size_t size) > +{ > + uk_pr_debug("allocating %zu aligned at %zu from region > allocator\n", size, > + align); > + > + return uk_posix_memalign(__region_alloc, memptr, align, > size); > +} > + > +static void uk_mimalloc_region_free(struct uk_alloc *a __unused, > void *ptr) > +{ > + uk_pr_info("attempt to free memory during early boot > time\n"); > + > + return uk_free(__region_alloc, ptr); > +} > + > +/* malloc interface */ > + > +static void *uk_mimalloc_malloc(struct uk_alloc *a __unused, size_t > size) > +{ > + return mi_malloc(size); > +} > + > +static void uk_mimalloc_free(struct uk_alloc *a __unused, void *ptr) > +{ > + mi_free(ptr); > +} > + > +static void *uk_mimalloc_realloc(struct uk_alloc *a __unused, void > *ptr, size_t size) > +{ > + return mi_realloc(ptr, size); > +} > + > +static void *uk_mimalloc_calloc(struct uk_alloc *a __unused, size_t > nelem, > + size_t elem_size) > +{ > + return mi_calloc(nelem, elem_size); > +} > + > +static int uk_mimalloc_posix_memalign(struct uk_alloc *a __unused, > void** p, > + size_t alignment, size_t size) > +{ > + return mi_posix_memalign(p, alignment, size); > +} > + > +static void *uk_mimalloc_memalign(struct uk_alloc *a __unused, > size_t alignment, > + size_t size) > +{ > + return mi_memalign(alignment, size); > +} > + > +static void uk_mimalloc_init_internal(struct uk_alloc *a) > +{ > + mi_process_load(); > + > + /* rebind interface to actual malloc interface */ > + (a)->malloc = uk_mimalloc_malloc; > + (a)->calloc = uk_mimalloc_calloc; > + (a)->realloc = uk_mimalloc_realloc; > + (a)->posix_memalign = uk_mimalloc_posix_memalign; > + (a)->memalign = uk_mimalloc_memalign; > + (a)->free = uk_mimalloc_free; > + > + /* delay this after interface rebinding to avoid using early > boot > + * time memory. > + */ > + _mi_options_init(); > + > + uk_pr_info("Successfully initialized Mimalloc\n"); > +} > + > +struct uk_alloc *uk_mimalloc_init(void *base, size_t len) > +{ > + struct uk_alloc *a; > + size_t metalen; > + > + /* TODO: This Mimalloc port does not support multiple memory > regions > + * yet. Because of the multiboot layout, the first region > might be a > + * single page, so we simply ignore it. > + */ > + if (len <= __PAGE_SIZE) > + return NULL; > + > + if (__region_alloc) { > + uk_pr_err("mimalloc already initialized (max number > of instances: 1)\n"); > + return NULL; > + } > + > + metalen = round_pgup(sizeof(*a)); > + > + /* enough space for allocator available? */ > + if (metalen > len) { > + uk_pr_err("Not enough space for allocator: > %"__PRIsz" B required but only %" > + __PRIuptr" B usable\n", metalen, len); > + return NULL; > + } > + > + /* enough space to allocate arena? */ > + if (len < MIN_HEAP_SIZE) { > + /* Note: we don't exit, but calls to malloc will > return NULL. */ > + uk_pr_err("Not enough space to allocate arena: %lu > bytes required" > + "but only %" __PRIsz" bytes usable\n", > 268435456L, len); > + } > + > + /* store allocator metadata on the heap, just before the > memory pool */ > + a = (struct uk_alloc *)base; > + uk_pr_info("Initialize mimalloc allocator (early boot time > mode) @ 0x%" > + __PRIuptr ", len %"__PRIsz"\n", (uintptr_t)a, > len); > + > + /* register mimalloc *before* initializing the region > allocator: in all cases > + * we want Mimalloc to be the default allocator. > + * FIXME: add uk_allocregion_init_noregister() that > initializes a region > + * allocator without registering it. > + */ > + uk_alloc_init_malloc(a, uk_mimalloc_region_malloc, > uk_calloc_compat, > + uk_realloc_compat, > uk_mimalloc_region_free, > + uk_mimalloc_region_posix_memalign, > + uk_memalign_compat, NULL); > + > + __region_alloc = uk_allocregion_init((void*)((uintptr_t) > base + metalen), > + len - metalen); > + > + return a; > +} > diff --git a/include/uk/mimalloc.h b/include/uk/mimalloc.h > new file mode 100644 > index 0000000..8e465aa > --- /dev/null > +++ b/include/uk/mimalloc.h > @@ -0,0 +1,49 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > + * > + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights > reserved. > + * > + * Redistribution and use in source and binary forms, with or > without > + * modification, are permitted provided that the following > conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above > copyright > + * notice, this list of conditions and the following disclaimer > in the > + * documentation and/or other materials provided with the > distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products > derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#ifndef __UKMIMALLOC_H__ > +#define __UKMIMALLOC_H__ > + > +#include <uk/alloc.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* allocator initialization */ > +struct uk_alloc *uk_mimalloc_init(void *base, size_t len); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __UKMIMALLOC_H__ */ > diff --git a/include/uk/mimalloc_impl.h b/include/uk/mimalloc_impl.h > new file mode 100644 > index 0000000..9fc3fe9 > --- /dev/null > +++ b/include/uk/mimalloc_impl.h > @@ -0,0 +1,56 @@ > +/* SPDX-License-Identifier: BSD-3-Clause */ > +/* > + * Authors: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > + * > + * Copyright (c) 2020, NEC Europe Ltd., NEC Corporation. All rights > reserved. > + * > + * Redistribution and use in source and binary forms, with or > without > + * modification, are permitted provided that the following > conditions > + * are met: > + * > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above > copyright > + * notice, this list of conditions and the following disclaimer > in the > + * documentation and/or other materials provided with the > distribution. > + * 3. Neither the name of the copyright holder nor the names of its > + * contributors may be used to endorse or promote products > derived from > + * this software without specific prior written permission. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND > CONTRIBUTORS "AS IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED > TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A > PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR > CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, > OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT > OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR > BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, > WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR > OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF > ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +/* > + * NOTE: These functions are not part of the public ukmimalloc API. > + * This interface is used in the mimalloc code base to request > memory > + * "from the OS". > + */ > + > +#ifndef __UK_MIMALLOC_IMPL_H__ > +#define __UK_MIMALLOC_IMPL_H__ > + > +#include <uk/alloc.h> > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/* region allocator */ > + > +void *uk_mimalloc_region_malloc(struct uk_alloc *a, size_t size); > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __UK_MIMALLOC_IMPL_H__ */ > diff --git a/main-tree.patch b/main-tree.patch > new file mode 100644 > index 0000000..5c0d7f9 > --- /dev/null > +++ b/main-tree.patch > @@ -0,0 +1,30 @@ > +From: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > +Subject: Add Mimalloc entry to the menuconfig and initialize it > +diff --git a/lib/ukboot/Config.uk b/lib/ukboot/Config.uk > +index a888bc1c..8c9a1dc2 100644 > +--- a/lib/ukboot/Config.uk > ++++ b/lib/ukboot/Config.uk > +@@ -32,6 +32,10 @@ if LIBUKBOOT > + Satisfy allocation as fast as possible. No > support for free(). > + Refer to help in ukallocregion for more > information. > + > ++ config LIBUKBOOT_INITMIMALLOC > ++ bool "Mimalloc" > ++ select LIBMIMALLOC > ++ > + config LIBUKBOOT_NOALLOC > + bool "No memory allocator" > + > +diff --git a/lib/ukboot/boot.c b/lib/ukboot/boot.c > +index 4e749aa5..06561b82 100644 > +--- a/lib/ukboot/boot.c > ++++ b/lib/ukboot/boot.c > +@@ -233,6 +233,8 @@ void ukplat_entry(int argc, char *argv[]) > + a = uk_allocbbuddy_init(md.base, md.len); > + #elif CONFIG_LIBUKBOOT_INITREGION > + a = uk_allocregion_init(md.base, md.len); > ++#elif CONFIG_LIBUKBOOT_INITMIMALLOC > ++ a = uk_mimalloc_init(md.base, md.len); > + #endif > + } else { > + uk_alloc_addmem(a, md.base, md.len); > diff --git a/patches/adapt-to-unikraft-interface.patch > b/patches/adapt-to-unikraft-interface.patch > new file mode 100644 > index 0000000..8a41454 > --- /dev/null > +++ b/patches/adapt-to-unikraft-interface.patch > @@ -0,0 +1,160 @@ > +From: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx> > +Subject: Adapt Mimalloc interface to Unikraft > + - expose mi_process_load() since it is called in the glue code > + - remove useless ATOMIC_VAR_INIT calls since they cause problems > with newlib > + - request memory from the OS via mi_unikraft_heap_grow(), which > relies > + internally on uk_mimalloc_region_malloc(), our underlying region > manager > + - at the time where Mimalloc was ported, the support for memory > protections > + by Unikraft was unclear, so it is here disabled. A future update > of this > + port should address this. > +diff -urNp mimalloc-orig/include/mimalloc.h mimalloc- > patched/include/mimalloc.h > +--- mimalloc-orig/include/mimalloc.h 2020-02-17 > 19:10:22.000000000 +0100 > ++++ mimalloc-patched/include/mimalloc.h 2020-06-24 > 10:16:31.439830260 +0200 > +@@ -144,6 +144,7 @@ mi_decl_export void mi_stats_print(void* > + mi_decl_export void mi_stats_print_out(mi_output_fun* out, void* > arg) mi_attr_noexcept; > + > + mi_decl_export void mi_process_init(void) mi_attr_noexcept; > ++mi_decl_export void mi_process_load(void) mi_attr_noexcept; > + mi_decl_export void mi_thread_init(void) mi_attr_noexcept; > + mi_decl_export void mi_thread_done(void) mi_attr_noexcept; > + mi_decl_export void mi_thread_stats_print_out(mi_output_fun* out, > void* arg) mi_attr_noexcept; > +diff -urNp mimalloc-orig/src/init.c mimalloc-patched/src/init.c > +--- mimalloc-orig/src/init.c 2020-02-17 19:10:22.000000000 > +0100 > ++++ mimalloc-patched/src/init.c 2020-06-24 10:16:31.443830218 > +0200 > +@@ -25,8 +25,8 @@ const mi_page_t _mi_page_empty = { > + 0, // used > + 0, // xblock_size > + NULL, // local_free > +- ATOMIC_VAR_INIT(0), // xthread_free > +- ATOMIC_VAR_INIT(0), // xheap > ++ 0, // xthread_free > ++ 0, // xheap > + NULL, NULL > + }; > + > +@@ -91,7 +91,7 @@ const mi_heap_t _mi_heap_empty = { > + NULL, > + MI_SMALL_PAGES_EMPTY, > + MI_PAGE_QUEUES_EMPTY, > +- ATOMIC_VAR_INIT(NULL), > ++ NULL, > + 0, // tid > + 0, // cookie > + { 0, 0 }, // keys > +@@ -125,7 +125,7 @@ mi_heap_t _mi_heap_main = { > + &tld_main, > + MI_SMALL_PAGES_EMPTY, > + MI_PAGE_QUEUES_EMPTY, > +- ATOMIC_VAR_INIT(NULL), > ++ NULL, > + 0, // thread id > + 0, // initial cookie > + { 0, 0 }, // the key of the main heap can be fixed > (unlike page keys that need to be secure!) > +@@ -430,7 +430,7 @@ static void mi_allocator_done() { > + #endif > + > + // Called once by the process loader > +-static void mi_process_load(void) { > ++void mi_process_load(void) { > + mi_heap_main_init(); > + #if defined(MI_TLS_RECURSE_GUARD) > + volatile mi_heap_t* dummy = _mi_heap_default; // access TLS to > allocate it before setting tls_initialized to true; > +@@ -438,7 +438,9 @@ static void mi_process_load(void) { > + #endif > + os_preloading = false; > + atexit(&mi_process_done); > +- _mi_options_init(); > ++ // delay _mi_options_init() after initialization as it allocates > a lot of > ++ // memory and we want to avoid doing that with the early boot > time allocator > ++ //_mi_options_init(); > + mi_process_init(); > + //mi_stats_reset();- > + if (mi_redirected) _mi_verbose_message("malloc is > redirected.\n"); > +@@ -519,6 +521,8 @@ static void mi_process_done(void) { > + } > + static bool mi_initialized = _mi_process_init(); > + > ++#elif defined(CONFIG_LIBMIMALLOC) > ++ // called by uk_init_mimalloc() > + #elif defined(__GNUC__) || defined(__clang__) > + // GCC,Clang: use the constructor attribute > + static void __attribute__((constructor)) _mi_process_init(void) { > +diff -urNp mimalloc-orig/src/os.c mimalloc-patched/src/os.c > +--- mimalloc-orig/src/os.c 2020-02-17 19:10:22.000000000 > +0100 > ++++ mimalloc-patched/src/os.c 2020-06-24 14:44:56.745158608 > +0200 > +@@ -14,11 +14,14 @@ terms of the MIT license. A copy of the > + > + #include <string.h> // strerror > + > ++#include <uk/mimalloc_impl.h> // uk_mimalloc_region_malloc > + > + #if defined(_WIN32) > + #include <windows.h> > + #elif defined(__wasi__) > + // stdlib.h is all we need, and has already been included in > mimalloc.h > ++#elif defined(CONFIG_LIBMIMALLOC) > ++#include <unistd.h> // sysconf > + #else > + #include <sys/mman.h> // mmap > + #include <unistd.h> // sysconf > +@@ -184,8 +187,8 @@ static bool mi_os_mem_free(void* addr, s > + bool err = false; > + #if defined(_WIN32) > + err = (VirtualFree(addr, 0, MEM_RELEASE) == 0); > +-#elif defined(__wasi__) > +- err = 0; // WebAssembly's heap cannot be shrunk > ++#elif defined(__wasi__) || defined(CONFIG_LIBMIMALLOC) > ++ err = 0; // WebAssembly's/Unikraft's heap cannot be shrunk > + #else > + err = (munmap(addr, size) == -1); > + #endif > +@@ -272,6 +275,10 @@ static void* mi_wasm_heap_grow(size_t si > + } > + return (void*)aligned_base; > + } > ++#elif defined(CONFIG_LIBMIMALLOC) > ++static void* mi_unikraft_heap_grow(size_t size, size_t > try_alignment) { > ++ return uk_mimalloc_region_malloc(NULL, size); > ++} > + #else > + #define MI_OS_USE_MMAP > + static void* mi_unix_mmapx(void* addr, size_t size, size_t > try_alignment, int protect_flags, int flags, int fd) { > +@@ -450,6 +457,9 @@ static void* mi_os_mem_alloc(size_t size > + #elif defined(__wasi__) > + *is_large = false; > + p = mi_wasm_heap_grow(size, try_alignment); > ++ #elif defined(CONFIG_LIBMIMALLOC) > ++ *is_large = false; > ++ p = mi_unikraft_heap_grow(size, try_alignment); > + #else > + int protect_flags = (commit ? (PROT_WRITE | PROT_READ) : > PROT_NONE); > + p = mi_unix_mmap(NULL, size, try_alignment, protect_flags, > false, allow_large, is_large); > +@@ -638,8 +648,8 @@ static bool mi_os_commitx(void* addr, si > + BOOL ok = VirtualFree(start, csize, MEM_DECOMMIT); > + err = (ok ? 0 : GetLastError()); > + } > +- #elif defined(__wasi__) > +- // WebAssembly guests can't control memory protection > ++ #elif defined(__wasi__) || defined(CONFIG_LIBMIMALLOC) > ++ // Unikraft/WebAssembly guests can't control memory protection > + #elif defined(MAP_FIXED) > + if (!commit) { > + // use mmap with MAP_FIXED to discard the existing memory (and > reduce commit charge) > +@@ -714,7 +724,7 @@ static bool mi_os_resetx(void* addr, siz > + advice = MADV_DONTNEED; > + err = madvise(start, csize, advice); > + } > +-#elif defined(__wasi__) > ++#elif defined(__wasi__) || defined(CONFIG_LIBMIMALLOC) > + int err = 0; > + #else > + int err = madvise(start, csize, MADV_DONTNEED); > +@@ -768,7 +778,7 @@ static bool mi_os_protectx(void* addr, > + DWORD oldprotect = 0; > + BOOL ok = VirtualProtect(start, csize, protect ? PAGE_NOACCESS : > PAGE_READWRITE, &oldprotect); > + err = (ok ? 0 : GetLastError()); > +-#elif defined(__wasi__) > ++#elif defined(__wasi__) || defined(CONFIG_LIBMIMALLOC) > + err = 0; > + #else > + err = mprotect(start, csize, protect ? PROT_NONE : (PROT_READ | > PROT_WRITE));
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |