[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [UNIKRAFT PATCH 07/18] lib/ukalloc: Wrappers for "fee memory" interfaces
The following allocation: struct uk_alloc *s = uk_alloc_get_default(); ssize_t maxalloc = uk_alloc_maxalloc(s); char *a = (char *)uk_malloc(s, maxalloc); would fail, because the real size that needs to be allocated is `maxalloc+sizeof(struct metadata_ifpages)`. Honestly, I don't know if we should substract, in the `uk_alloc_maxalloc_ifpages()` function, that extra metadata size which is necessary for every allocation, but basically the biggest allocation that an allocator can satisfy is `maxalloc-sizeof(struct metadata_ifpages)`. This commit provides cross compatibility wrappers between page and non-page
allocators: `uk_alloc_availmem()`, `uk_alloc_maxalloc()`,
`uk_alloc_pavail()`, and `uk_alloc_pmaxalloc()`.
Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
lib/ukalloc/alloc.c | 52 +++++++++++++++++++++++++++++
lib/ukalloc/exportsyms.uk | 4 +++
lib/ukalloc/include/uk/alloc_impl.h | 20 ++++++++++-
3 files changed, 75 insertions(+), 1 deletion(-)
diff --git a/lib/ukalloc/alloc.c b/lib/ukalloc/alloc.c
index 98a0e94f..bb92301d 100644
--- a/lib/ukalloc/alloc.c
+++ b/lib/ukalloc/alloc.c
@@ -271,6 +271,32 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
return 0;
}
+ssize_t uk_alloc_maxalloc_ifpages(struct uk_alloc *a)
+{
+ long num_pages;
+
+ UK_ASSERT(a);
+
+ num_pages = uk_alloc_pmaxalloc(a);
+ if (num_pages < 0)
+ return (ssize_t) num_pages;
+
+ return ((ssize_t) num_pages) << __PAGE_SHIFT;
+}
+
+ssize_t uk_alloc_availmem_ifpages(struct uk_alloc *a)
+{
+ long num_pages;
+
+ UK_ASSERT(a);
+
+ num_pages = uk_alloc_pavail(a);
+ if (num_pages < 0)
+ return (ssize_t) num_pages;
+
+ return ((ssize_t) num_pages) << __PAGE_SHIFT;
+}
+
#if CONFIG_LIBUKALLOC_IFMALLOC
struct metadata_ifmalloc {
@@ -490,3 +516,29 @@ void *uk_memalign_compat(struct uk_alloc *a, size_t align, size_t size)
return ptr;
}
+
+long uk_alloc_pmaxalloc_compat(struct uk_alloc *a)
+{
+ ssize_t mem;
+
+ UK_ASSERT(a);
+
+ mem = uk_alloc_maxalloc(a);
+ if (mem < 0)
+ return (long) mem;
+
+ return (long) (mem >> __PAGE_SHIFT);
+}
+
+long uk_alloc_pavail_compat(struct uk_alloc *a)
+{
+ ssize_t mem;
+
+ UK_ASSERT(a);
+
+ mem = uk_alloc_availmem(a);
+ if (mem < 0)
+ return (long) mem;
+
+ return (long) (mem >> __PAGE_SHIFT);
+}
diff --git a/lib/ukalloc/exportsyms.uk b/lib/ukalloc/exportsyms.uk
index 21c1996f..a99551bd 100644
--- a/lib/ukalloc/exportsyms.uk
+++ b/lib/ukalloc/exportsyms.uk
@@ -4,6 +4,8 @@ uk_malloc_ifpages
uk_free_ifpages
uk_realloc_ifpages
uk_posix_memalign_ifpages
+uk_alloc_maxalloc_ifpages
+uk_alloc_availmem_ifpages
uk_malloc_ifmalloc
uk_realloc_ifmalloc
uk_posix_memalign_ifmalloc
@@ -13,4 +15,6 @@ uk_memalign_compat
uk_realloc_compat
uk_palloc_compat
uk_pfree_compat
+uk_alloc_pmaxalloc_compat
+uk_alloc_pavail_compat
_uk_alloc_head
diff --git a/lib/ukalloc/include/uk/alloc_impl.h b/lib/ukalloc/include/uk/alloc_impl.h
index 7e96ed94..4811558e 100644
--- a/lib/ukalloc/include/uk/alloc_impl.h
+++ b/lib/ukalloc/include/uk/alloc_impl.h
@@ -53,12 +53,16 @@ int uk_alloc_register(struct uk_alloc *a);
* API functionality is actually implemented.
*/
-/* Functions that can be used by allocators that implement palloc(), pfree() only */
+/* Functions that can be used by allocators that implement palloc(),
+ * pfree() and potentially pavail(), pmaxalloc() only
+ */
void *uk_malloc_ifpages(struct uk_alloc *a, size_t size);
void *uk_realloc_ifpages(struct uk_alloc *a, void *ptr, size_t size);
int uk_posix_memalign_ifpages(struct uk_alloc *a, void **memptr,
size_t align, size_t size);
void uk_free_ifpages(struct uk_alloc *a, void *ptr);
+ssize_t uk_alloc_availmem_ifpages(struct uk_alloc *a);
+ssize_t uk_alloc_maxalloc_ifpages(struct uk_alloc *a);
#if CONFIG_LIBUKALLOC_IFMALLOC
void *uk_malloc_ifmalloc(struct uk_alloc *a, size_t size);
@@ -74,6 +78,8 @@ void *uk_realloc_compat(struct uk_alloc *a, void *ptr, size_t size);
void *uk_memalign_compat(struct uk_alloc *a, size_t align, size_t len);
void *uk_palloc_compat(struct uk_alloc *a, unsigned long num_pages);
void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
+long uk_alloc_pavail_compat(struct uk_alloc *a);
+long uk_alloc_pmaxalloc_compat(struct uk_alloc *a);
/* Shortcut for doing a registration of an allocator that does not implement
* palloc() or pfree()
@@ -91,7 +97,11 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
(a)->palloc = uk_palloc_compat; \
(a)->pfree = uk_pfree_compat; \
(a)->availmem = (availmem_f); \
+ (a)->pavail = (availmem_f != NULL) \
+ ? uk_alloc_pavail_compat : NULL; \
(a)->maxalloc = (maxalloc_f); \
+ (a)->pmaxalloc = (maxalloc_f != NULL) \
+ ? uk_alloc_pmaxalloc_compat : NULL; \
(a)->addmem = (addmem_f); \
\
uk_alloc_register((a)); \
@@ -112,7 +122,11 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
(a)->palloc = uk_palloc_compat; \
(a)->pfree = uk_pfree_compat; \
(a)->availmem = (availmem_f); \
+ (a)->pavail = (availmem_f != NULL) \
+ ? uk_alloc_pavail_compat : NULL; \
(a)->maxalloc = (maxalloc_f); \
+ (a)->pmaxalloc = (maxalloc_f != NULL) \
+ ? uk_alloc_pmaxalloc_compat : NULL; \
(a)->addmem = (addmem_f); \
\
uk_alloc_register((a)); \
@@ -134,7 +148,11 @@ void uk_pfree_compat(struct uk_alloc *a, void *ptr, unsigned long num_pages);
(a)->palloc = (palloc_func); \
(a)->pfree = (pfree_func); \
(a)->pavail = (pavail_func); \
+ (a)->availmem = (pavail_func != NULL) \
+ ? uk_alloc_availmem_ifpages : NULL; \
(a)->pmaxalloc = (pmaxalloc_func); \
+ (a)->maxalloc = (pmaxalloc_func != NULL) \
+ ? uk_alloc_maxalloc_ifpages : NULL; \
(a)->addmem = (addmem_func); \
\
uk_alloc_register((a)); \
--
2.20.1
|