[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [UNIKRAFT PATCH 05/18] lib/ukalloc: Introduce `uk_alloc_maxalloc()` and make `uk_alloc_availmem()` available



I have 2 inline comments for this patch.

On Fri, Nov 20, 2020 at 5:47 PM Simon Kuenzer <simon.kuenzer@xxxxxxxxx> wrote:
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@xxxxxxxxx>
---
 lib/ukalloc/Config.uk               |  5 -----
 lib/ukalloc/include/uk/alloc.h      | 21 +++++++++++++--------
 lib/ukalloc/include/uk/alloc_impl.h | 10 ++++++++--
 lib/ukallocbbuddy/bbuddy.c          |  4 ----
 lib/ukallocregion/region.c          | 16 +++++++++++++++-
 5 files changed, 36 insertions(+), 20 deletions(-)

diff --git a/lib/ukalloc/Config.uk b/lib/ukalloc/Config.uk
index c965d080..59a6aa78 100644
--- a/lib/ukalloc/Config.uk
+++ b/lib/ukalloc/Config.uk
@@ -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
diff --git a/lib/ukalloc/include/uk/alloc.h b/lib/ukalloc/include/uk/alloc.h
index 4c6bb872..af5a71cd 100644
--- a/lib/ukalloc/include/uk/alloc.h
+++ b/lib/ukalloc/include/uk/alloc.h
@@ -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)
                (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 */
To avoid any confusions, I suggest to use either a more-general type name for both function
pointers(like `uk_alloc_meminfo_func_t`), preferable if there is a chance to add more memory
statistics functions, or a new type for maxalloc, i.e. `uk_alloc_maxalloc_func_t`. 
+       uk_alloc_availmem_func_t maxalloc; /* biggest alloc req. (bytes) */
+       uk_alloc_availmem_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
 }
diff --git a/lib/ukalloc/include/uk/alloc_impl.h b/lib/ukalloc/include/uk/alloc_impl.h
index 844eca9a..beeb59f0 100644
--- a/lib/ukalloc/include/uk/alloc_impl.h
+++ b/lib/ukalloc/include/uk/alloc_impl.h
@@ -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));                                 \
diff --git a/lib/ukallocbbuddy/bbuddy.c b/lib/ukallocbbuddy/bbuddy.c
index 85f3e8db..3730eeb2 100644
--- a/lib/ukallocbbuddy/bbuddy.c
+++ b/lib/ukallocbbuddy/bbuddy.c
@@ -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 */
diff --git a/lib/ukallocregion/region.c b/lib/ukallocregion/region.c
index ae8fcb82..fc8a63b2 100644
--- a/lib/ukallocregion/region.c
+++ b/lib/ukallocregion/region.c
@@ -131,6 +131,19 @@ void uk_allocregion_free(struct uk_alloc *a __unused, void *ptr __unused)
                        "ukallocregion\n", a);
 }

+static ssize_t uk_allocregion_availmem(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 +190,8 @@ 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);
Instead of using `uk_allocregion_availmem` for the argument which corresponds to
`maxalloc_f`, I suggest to implement a stub function for `uk_allocregion_maxalloc`. 
+                               uk_memalign_compat, uk_allocregion_availmem,
+                               uk_allocregion_availmem, uk_allocregion_addmem);

        return a;
 }
--
2.20.1


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.