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

On Fri, Nov 20, 2020 at 5:47 PM Simon Kuenzer <simon.kuenzer@xxxxxxxxx> wrote:
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


 


Rackspace

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