[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. 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
|