]> xenbits.xensource.com Git - unikraft/unikraft.git/commitdiff
lib/ukalloc: Introduce `uk_alloc_maxalloc()` and make `uk_alloc_availmem()` available
authorSimon Kuenzer <simon.kuenzer@neclab.eu>
Thu, 12 Nov 2020 15:52:53 +0000 (16:52 +0100)
committerUnikraft <monkey@unikraft.io>
Tue, 22 Jun 2021 13:14:08 +0000 (13:14 +0000)
The purpose of this commit is to make `uk_alloc_availmem()` always
available because it is currently the only way to figure out how much heap
memory is still available. We also introduce `uk_alloc_maxalloc()` that
returns the biggest possible allocation that an allocator can currently
satisfy. The configuration option `CONFIG_IFSTAT` is removed because it
raises the expectation of an interface that returns detailed allocator
statistics.

Signed-off-by: Simon Kuenzer <simon.kuenzer@neclab.eu>
Reviewed-by: Cezar Craciunoiu <cezar.craciunoiu@gmail.com>
Tested-by: Unikraft CI <monkey@unikraft.io>
GitHub-Pull-Request: #229

lib/ukalloc/Config.uk
lib/ukalloc/include/uk/alloc.h
lib/ukalloc/include/uk/alloc_impl.h
lib/ukallocbbuddy/bbuddy.c
lib/ukallocpool/pool.c
lib/ukallocregion/region.c

index c965d0808285f6cb18e4ecb9297b48f5582b154b..59a6aa78323739a8162e3067c364d9b6ff994255 100644 (file)
@@ -10,9 +10,4 @@ if LIBUKALLOC
                default n
                help
                        Provide helpers for allocators defining exclusively malloc and free
-       config LIBUKALLOC_IFSTATS
-               bool "Statistics interface"
-               default n
-               help
-                       Provide interfaces for querying allocator status
 endif
index 4c6bb872fe7bbfc45cbe036362e0349ff0acb280..927c46b28a7a91c052c23f0d2b3f46d191a2abef 100644 (file)
@@ -66,10 +66,8 @@ typedef void  (*uk_alloc_pfree_func_t)
                (struct uk_alloc *a, void *ptr, unsigned long num_pages);
 typedef int   (*uk_alloc_addmem_func_t)
                (struct uk_alloc *a, void *base, size_t size);
-#if CONFIG_LIBUKALLOC_IFSTATS
-typedef ssize_t (*uk_alloc_availmem_func_t)
+typedef ssize_t (*uk_alloc_getsize_func_t)
                (struct uk_alloc *a);
-#endif
 
 struct uk_alloc {
        /* memory allocation */
@@ -88,10 +86,9 @@ struct uk_alloc {
        /* page allocation interface */
        uk_alloc_palloc_func_t palloc;
        uk_alloc_pfree_func_t pfree;
-#if CONFIG_LIBUKALLOC_IFSTATS
-       /* optional interface */
-       uk_alloc_availmem_func_t availmem;
-#endif
+       /* optional interfaces, but recommended */
+       uk_alloc_getsize_func_t maxalloc; /* biggest alloc req. (bytes) */
+       uk_alloc_getsize_func_t availmem; /* total memory available (bytes) */
        /* optional interface */
        uk_alloc_addmem_func_t addmem;
 
@@ -237,7 +234,16 @@ static inline int uk_alloc_addmem(struct uk_alloc *a, void *base,
        else
                return -ENOTSUP;
 }
-#if CONFIG_LIBUKALLOC_IFSTATS
+
+/* current biggest allocation request possible */
+static inline ssize_t uk_alloc_maxalloc(struct uk_alloc *a)
+{
+       UK_ASSERT(a);
+       if (!a->maxalloc)
+               return (ssize_t) -ENOTSUP;
+       return a->maxalloc(a);
+}
+
 static inline ssize_t uk_alloc_availmem(struct uk_alloc *a)
 {
        UK_ASSERT(a);
@@ -245,7 +251,6 @@ static inline ssize_t uk_alloc_availmem(struct uk_alloc *a)
                return (ssize_t) -ENOTSUP;
        return a->availmem(a);
 }
-#endif /* CONFIG_LIBUKALLOC_IFSTATS */
 
 #ifdef __cplusplus
 }
index 844eca9a25ba1e559b1c783b92e9bfe4b8797e03..beeb59f0096760869edc444dbc6eb2ef89b98723 100644 (file)
@@ -79,7 +79,8 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
  * palloc() or pfree()
  */
 #define uk_alloc_init_malloc(a, malloc_f, calloc_f, realloc_f, free_f, \
-                               posix_memalign_f, memalign_f, addmem_f) \
+                            posix_memalign_f, memalign_f, maxalloc_f,  \
+                            availmem_f, addmem_f)                      \
        do {                                                            \
                (a)->malloc         = (malloc_f);                       \
                (a)->calloc         = (calloc_f);                       \
@@ -89,13 +90,16 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
                (a)->free           = (free_f);                         \
                (a)->palloc         = uk_palloc_compat;                 \
                (a)->pfree          = uk_pfree_compat;                  \
+               (a)->availmem       = (availmem_f);                     \
+               (a)->maxalloc       = (maxalloc_f);                     \
                (a)->addmem         = (addmem_f);                       \
                                                                        \
                uk_alloc_register((a));                                 \
        } while (0)
 
 #if CONFIG_LIBUKALLOC_IFMALLOC
-#define uk_alloc_init_malloc_ifmalloc(a, malloc_f, free_f, addmem_f)   \
+#define uk_alloc_init_malloc_ifmalloc(a, malloc_f, free_f, maxalloc_f, \
+                                     availmem_f, addmem_f)             \
        do {                                                            \
                (a)->malloc         = uk_malloc_ifmalloc;               \
                (a)->calloc         = uk_calloc_compat;                 \
@@ -107,6 +111,8 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
                (a)->free           = uk_free_ifmalloc;                 \
                (a)->palloc         = uk_palloc_compat;                 \
                (a)->pfree          = uk_pfree_compat;                  \
+               (a)->availmem       = (availmem_f);                     \
+               (a)->maxalloc       = (maxalloc_f);                     \
                (a)->addmem         = (addmem_f);                       \
                                                                        \
                uk_alloc_register((a));                                 \
index 85f3e8db46d155e49c2ae8d8cf2a3d2459d5cae2..3730eeb2ed8ba9437993e4f57c3053ef67046e3c 100644 (file)
@@ -214,7 +214,6 @@ static void map_free(struct uk_bbpalloc *b, uintptr_t first_page,
        b->nr_free_pages += nr_pages;
 }
 
-#if CONFIG_LIBUKALLOC_IFSTATS
 static ssize_t bbuddy_availmem(struct uk_alloc *a)
 {
        struct uk_bbpalloc *b;
@@ -223,7 +222,6 @@ static ssize_t bbuddy_availmem(struct uk_alloc *a)
        b = (struct uk_bbpalloc *)&a->priv;
        return (ssize_t) b->nr_free_pages << __PAGE_SHIFT;
 }
-#endif
 
 /* return log of the next power of two of passed number */
 static inline unsigned long num_pages_to_order(unsigned long num_pages)
@@ -504,9 +502,7 @@ struct uk_alloc *uk_allocbbuddy_init(void *base, size_t len)
        /* initialize and register allocator interface */
        uk_alloc_init_palloc(a, bbuddy_palloc, bbuddy_pfree,
                             bbuddy_addmem);
-#if CONFIG_LIBUKALLOC_IFSTATS
        a->availmem = bbuddy_availmem;
-#endif
 
        if (max > min + metalen) {
                /* add left memory - ignore return value */
index 390f6b92c13cb0853f23f2bd5b58c80d27d3173a..4c711fe52a873712441a1fb87dd9b7dec9327892 100644 (file)
@@ -208,14 +208,19 @@ void uk_allocpool_return_batch(struct uk_allocpool *p,
                _prepend_free_obj(p, obj[i]);
 }
 
-#if CONFIG_LIBUKALLOC_IFSTATS
 static ssize_t pool_availmem(struct uk_alloc *a)
 {
        struct uk_allocpool *p = ukalloc2pool(a);
 
-       return (size_t) p->free_obj_count * p->obj_len;
+       return (ssize_t) (p->free_obj_count * p->obj_len);
+}
+
+static ssize_t pool_maxalloc(struct uk_alloc *a)
+{
+       struct uk_allocpool *p = ukalloc2pool(a);
+
+       return (ssize_t) p->obj_len;
 }
-#endif
 
 size_t uk_allocpool_reqmem(unsigned int obj_count, size_t obj_len,
                           size_t obj_align)
@@ -300,10 +305,9 @@ out:
                             pool_free,
                             pool_posix_memalign,
                             uk_memalign_compat,
+                            pool_maxalloc,
+                            pool_availmem,
                             NULL);
-#if CONFIG_LIBUKALLOC_IFSTATS
-       p->self.availmem = pool_availmem;
-#endif
 
        uk_pr_debug("%p: Pool created (%"__PRIsz" B): %u objs of %"__PRIsz" B, aligned to %"__PRIsz" B\n",
                    p, len, p->obj_count, p->obj_len, p->obj_align);
index ae8fcb822ee3c2bbe537d8a721ea240f4fb3378d..54b2276e1d5a5ee45121f3649196e496cc6aa65f 100644 (file)
@@ -131,6 +131,22 @@ void uk_allocregion_free(struct uk_alloc *a __unused, void *ptr __unused)
                        "ukallocregion\n", a);
 }
 
+/* NOTE: We use `uk_allocregion_leftspace()` for `maxalloc` and `availmem`
+ *       because it is the same for this region allocator
+ */
+static ssize_t uk_allocregion_leftspace(struct uk_alloc *a)
+{
+       struct uk_allocregion *b;
+
+       UK_ASSERT(a != NULL);
+
+       b = (struct uk_allocregion *) &a->priv;
+
+       UK_ASSERT(b != NULL);
+
+       return (uintptr_t) b->heap_top - (uintptr_t) b->heap_base;
+}
+
 int uk_allocregion_addmem(struct uk_alloc *a __unused, void *base __unused,
                                size_t size __unused)
 {
@@ -177,7 +193,9 @@ struct uk_alloc *uk_allocregion_init(void *base, size_t len)
        uk_alloc_init_malloc(a, uk_allocregion_malloc, uk_calloc_compat,
                                uk_realloc_compat, uk_allocregion_free,
                                uk_allocregion_posix_memalign,
-                               uk_memalign_compat, NULL);
+                               uk_memalign_compat, uk_allocregion_leftspace,
+                               uk_allocregion_leftspace,
+                               uk_allocregion_addmem);
 
        return a;
 }