[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [UNIKRAFT PATCH 06/18] lib/ukalloc: Introduce `uk_alloc_pavail()`, `uk_alloc_pmaxalloc()`
I have 2 inline comments for this patch.
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) */
Similar to the previous patch, I suggest to use either a more-general type name for both function pointers(like `uk_alloc_pmeminfo_func_t`), preferable if there is a chance to add more memory statistics functions, or a new type for pmaxalloc, i.e. `uk_alloc_pmaxalloc_func_t`.
+ 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()
You omitted to mention `pmaxalloc()`.
+ * 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
|