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

[UNIKRAFT PATCH 06/18] lib/ukalloc: Introduce `uk_alloc_pavail()`, `uk_alloc_pmaxalloc()`



This commit introduces
- `uk_alloc_pavail()` as an equivalent for `uk_alloc_availmem()`
  for page allocators.
- `uk_alloc_pmaxalloc()` as an equivalent for `uk_alloc_maxalloc()`
  for page allocators.

Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
 lib/ukalloc/include/uk/alloc.h      | 21 +++++++++++++++
 lib/ukalloc/include/uk/alloc_impl.h |  7 +++--
 lib/ukallocbbuddy/bbuddy.c          | 41 ++++++++++++++++++++++-------
 3 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/lib/ukalloc/include/uk/alloc.h b/lib/ukalloc/include/uk/alloc.h
index af5a71cd..b711b56a 100644
--- a/lib/ukalloc/include/uk/alloc.h
+++ b/lib/ukalloc/include/uk/alloc.h
@@ -68,6 +68,8 @@ typedef int   (*uk_alloc_addmem_func_t)
                (struct uk_alloc *a, void *base, size_t size);
 typedef ssize_t (*uk_alloc_availmem_func_t)
                (struct uk_alloc *a);
+typedef long  (*uk_alloc_pavail_func_t)
+               (struct uk_alloc *a);
 
 struct uk_alloc {
        /* memory allocation */
@@ -89,6 +91,8 @@ struct uk_alloc {
        /* optional interfaces, but recommended */
        uk_alloc_availmem_func_t maxalloc; /* biggest alloc req. (bytes) */
        uk_alloc_availmem_func_t availmem; /* total memory available (bytes) */
+       uk_alloc_pavail_func_t pmaxalloc; /* biggest alloc req. (pages) */
+       uk_alloc_pavail_func_t pavail; /* total pages available */
        /* optional interface */
        uk_alloc_addmem_func_t addmem;
 
@@ -244,6 +248,15 @@ static inline ssize_t uk_alloc_maxalloc(struct uk_alloc *a)
        return a->maxalloc(a);
 }
 
+static inline long uk_alloc_pmaxalloc(struct uk_alloc *a)
+{
+       UK_ASSERT(a);
+       if (!a->pmaxalloc)
+               return (long) -ENOTSUP;
+       return a->pmaxalloc(a);
+}
+
+/* total free memory of the allocator */
 static inline ssize_t uk_alloc_availmem(struct uk_alloc *a)
 {
        UK_ASSERT(a);
@@ -252,6 +265,14 @@ static inline ssize_t uk_alloc_availmem(struct uk_alloc *a)
        return a->availmem(a);
 }
 
+static inline long uk_alloc_pavail(struct uk_alloc *a)
+{
+       UK_ASSERT(a);
+       if (!a->pavail)
+               return (long) -ENOTSUP;
+       return a->pavail(a);
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/ukalloc/include/uk/alloc_impl.h 
b/lib/ukalloc/include/uk/alloc_impl.h
index beeb59f0..7e96ed94 100644
--- a/lib/ukalloc/include/uk/alloc_impl.h
+++ b/lib/ukalloc/include/uk/alloc_impl.h
@@ -120,9 +120,10 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, 
unsigned long num_pages);
 #endif
 
 /* Shortcut for doing a registration of an allocator that only
- * implements palloc(), pfree(), addmem()
+ * implements palloc(), pfree(), pavail(), addmem()
  */
-#define uk_alloc_init_palloc(a, palloc_func, pfree_func, addmem_func)  \
+#define uk_alloc_init_palloc(a, palloc_func, pfree_func, pmaxalloc_func, \
+                            pavail_func, addmem_func)                  \
        do {                                                            \
                (a)->malloc         = uk_malloc_ifpages;                \
                (a)->calloc         = uk_calloc_compat;                 \
@@ -132,6 +133,8 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, 
unsigned long num_pages);
                (a)->free           = uk_free_ifpages;                  \
                (a)->palloc         = (palloc_func);                    \
                (a)->pfree          = (pfree_func);                     \
+               (a)->pavail         = (pavail_func);                    \
+               (a)->pmaxalloc      = (pmaxalloc_func);                 \
                (a)->addmem         = (addmem_func);                    \
                                                                        \
                uk_alloc_register((a));                                 \
diff --git a/lib/ukallocbbuddy/bbuddy.c b/lib/ukallocbbuddy/bbuddy.c
index 3730eeb2..b63e2fd3 100644
--- a/lib/ukallocbbuddy/bbuddy.c
+++ b/lib/ukallocbbuddy/bbuddy.c
@@ -214,15 +214,6 @@ static void map_free(struct uk_bbpalloc *b, uintptr_t 
first_page,
        b->nr_free_pages += nr_pages;
 }
 
-static ssize_t bbuddy_availmem(struct uk_alloc *a)
-{
-       struct uk_bbpalloc *b;
-
-       UK_ASSERT(a != NULL);
-       b = (struct uk_bbpalloc *)&a->priv;
-       return (ssize_t) b->nr_free_pages << __PAGE_SHIFT;
-}
-
 /* return log of the next power of two of passed number */
 static inline unsigned long num_pages_to_order(unsigned long num_pages)
 {
@@ -360,6 +351,36 @@ static void bbuddy_pfree(struct uk_alloc *a, void *obj, 
unsigned long num_pages)
        b->free_head[order] = freed_ch;
 }
 
+static long bbuddy_pmaxalloc(struct uk_alloc *a)
+{
+       struct uk_bbpalloc *b;
+       size_t i, order;
+
+       UK_ASSERT(a != NULL);
+       b = (struct uk_bbpalloc *)&a->priv;
+
+       /* Find biggest order that has still elements available */
+       order = FREELIST_SIZE;
+       for (i = 0; i < FREELIST_SIZE; i++) {
+               if (!FREELIST_EMPTY(b->free_head[i]))
+                       order = i;
+       }
+       if (order == FREELIST_SIZE)
+               return 0; /* no memory left */
+
+       return (long) (1 << order);
+}
+
+static long bbuddy_pavail(struct uk_alloc *a)
+{
+       struct uk_bbpalloc *b;
+
+       UK_ASSERT(a != NULL);
+       b = (struct uk_bbpalloc *)&a->priv;
+
+       return (long) b->nr_free_pages;
+}
+
 static int bbuddy_addmem(struct uk_alloc *a, void *base, size_t len)
 {
        struct uk_bbpalloc *b;
@@ -501,8 +522,8 @@ 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_pmaxalloc, bbuddy_pavail,
                             bbuddy_addmem);
-       a->availmem = bbuddy_availmem;
 
        if (max > min + metalen) {
                /* add left memory - ignore return value */
-- 
2.20.1



 


Rackspace

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