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

[Minios-devel] [UNIKRAFT PATCH v4 1/4] lib/ukalloc: use size instead of order in palloc and pfree apis



Change palloc, pfree and all calls to them within the main tree to take
size instead of order as argument. Size to order calculations are now done
within the binary buddy allocator.

This allows for a cleaner interface and simplifies the implementation of
new memory allocators.

Signed-off-by: Hugo Lefeuvre <hugo.lefeuvre@xxxxxxxxx>

---
Changes v4:
  - call uk_palloc and uk_pfree with size argument __PAGE_SIZE in uk_malloc_page
    and uk_free_page.

diff --git a/lib/ukalloc/alloc.c b/lib/ukalloc/alloc.c
index 708bd02..7ba1fac 100644
--- a/lib/ukalloc/alloc.c
+++ b/lib/ukalloc/alloc.c
@@ -141,7 +141,7 @@ static size_t uk_getmallocsize(const void *ptr)
                /*
                 * special case: the memory was page-aligned
                 * In this case the allocated size should not account for the
-                * previous page which was used for storing the order
+                * previous page which was used for storing the size
                 */
                mallocsize -= __PAGE_SIZE;
        } else {
@@ -155,34 +155,22 @@ static size_t uk_getmallocsize(const void *ptr)
        return mallocsize;
 }
 
-/* return the smallest order (1<<order pages) that can fit size bytes */
-static inline size_t uk_alloc_size_to_order(size_t size)
-{
-       size_t order = 0;
-
-       while ((__PAGE_SIZE << order) < size)
-               order++;
-       return order;
-}
-
 void *uk_malloc_ifpages(struct uk_alloc *a, size_t size)
 {
        uintptr_t intptr;
-       size_t order;
-       size_t realsize = sizeof(order) + size;
+       size_t realsize = sizeof(realsize) + size;
 
        UK_ASSERT(a);
        if (!size)
                return NULL;
 
-       order = uk_alloc_size_to_order(realsize);
-       intptr = (uintptr_t)uk_palloc(a, order);
+       intptr = (uintptr_t)uk_palloc(a, realsize);
 
        if (!intptr)
                return NULL;
 
-       *(size_t *)intptr = order;
-       return (void *)(intptr + sizeof(order));
+       *(size_t *)intptr = realsize;
+       return (void *)(intptr + sizeof(realsize));
 }
 
 void uk_free_ifpages(struct uk_alloc *a, void *ptr)
@@ -231,7 +219,6 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
 {
        uintptr_t *intptr;
        size_t realsize;
-       size_t order;
 
        UK_ASSERT(a);
        if (((align - 1) & align) != 0
@@ -251,16 +238,15 @@ int uk_posix_memalign_ifpages(struct uk_alloc *a,
        if (align == __PAGE_SIZE)
                realsize = ALIGN_UP(size + __PAGE_SIZE, align);
        else
-               realsize = ALIGN_UP(size + sizeof(order), align);
+               realsize = ALIGN_UP(size + sizeof(realsize), align);
 
-       order = uk_alloc_size_to_order(realsize);
-       intptr = uk_palloc(a, order);
+       intptr = uk_palloc(a, realsize);
 
        if (!intptr)
                return ENOMEM;
 
-       *(size_t *)intptr = order;
-       *memptr = (void *) ALIGN_UP((uintptr_t)intptr + sizeof(order), align);
+       *(size_t *)intptr = realsize;
+       *memptr = (void *) ALIGN_UP((uintptr_t)intptr + sizeof(realsize), 
align);
        return 0;
 }
 
diff --git a/lib/ukalloc/include/uk/alloc.h b/lib/ukalloc/include/uk/alloc.h
index 798d45a..5dd5d1e 100644
--- a/lib/ukalloc/include/uk/alloc.h
+++ b/lib/ukalloc/include/uk/alloc.h
@@ -43,6 +43,7 @@
 #include <uk/config.h>
 #include <uk/assert.h>
 #include <uk/essentials.h>
+#include <uk/arch/limits.h>
 
 struct uk_alloc;
 
@@ -70,9 +71,9 @@ typedef void  (*uk_alloc_free_func_t)
                (struct uk_alloc *a, void *ptr);
 #if CONFIG_LIBUKALLOC_IFPAGES
 typedef void* (*uk_alloc_palloc_func_t)
-               (struct uk_alloc *a, size_t order);
+               (struct uk_alloc *a, size_t size);
 typedef void  (*uk_alloc_pfree_func_t)
-               (struct uk_alloc *a, void *ptr, size_t order);
+               (struct uk_alloc *a, void *ptr, size_t size);
 #endif
 typedef int   (*uk_alloc_addmem_func_t)
                (struct uk_alloc *a, void *base, size_t size);
@@ -194,33 +195,33 @@ static inline void uk_free(struct uk_alloc *a, void *ptr)
 }
 
 #if CONFIG_LIBUKALLOC_IFPAGES
-static inline void *uk_do_palloc(struct uk_alloc *a, size_t order)
+static inline void *uk_do_palloc(struct uk_alloc *a, size_t size)
 {
        UK_ASSERT(a);
-       return a->palloc(a, order);
+       return a->palloc(a, size);
 }
-static inline void *uk_palloc(struct uk_alloc *a, size_t order)
+static inline void *uk_palloc(struct uk_alloc *a, size_t size)
 {
        if (unlikely(!a || !a->palloc))
                return NULL;
-       return a->palloc(a, order);
+       return a->palloc(a, size);
 }
 static inline void *uk_malloc_page(struct uk_alloc *a)
 {
-       return uk_palloc(a, 0);
+       return uk_palloc(a, __PAGE_SIZE);
 }
-static inline void uk_do_pfree(struct uk_alloc *a, void *ptr, size_t order)
+static inline void uk_do_pfree(struct uk_alloc *a, void *ptr, size_t size)
 {
        UK_ASSERT(a);
-       a->pfree(a, ptr, order);
+       a->pfree(a, ptr, size);
 }
-static inline void uk_pfree(struct uk_alloc *a, void *ptr, size_t order)
+static inline void uk_pfree(struct uk_alloc *a, void *ptr, size_t size)
 {
-       uk_do_pfree(a, ptr, order);
+       uk_do_pfree(a, ptr, size);
 }
 static inline void uk_free_page(struct uk_alloc *a, void *ptr)
 {
-       return uk_pfree(a, ptr, 0);
+       return uk_pfree(a, ptr, __PAGE_SIZE);
 }
 #endif
 static inline int uk_alloc_addmem(struct uk_alloc *a, void *base,
diff --git a/lib/ukallocbbuddy/bbuddy.c b/lib/ukallocbbuddy/bbuddy.c
index 7de3b84..3ea2049 100644
--- a/lib/ukallocbbuddy/bbuddy.c
+++ b/lib/ukallocbbuddy/bbuddy.c
@@ -224,10 +224,20 @@ static ssize_t bbuddy_availmem(struct uk_alloc *a)
 }
 #endif
 
+/* return the smallest order (1<<order pages) that can fit size bytes */
+static inline size_t uk_alloc_size_to_order(size_t size)
+{
+       size_t order = 0;
+
+       while ((__PAGE_SIZE << order) < size)
+               order++;
+       return order;
+}
+
 /*********************
  * BINARY BUDDY PAGE ALLOCATOR
  */
-static void *bbuddy_palloc(struct uk_alloc *a, size_t order)
+static void *bbuddy_palloc(struct uk_alloc *a, size_t size)
 {
        struct uk_bbpalloc *b;
        size_t i;
@@ -237,6 +247,8 @@ static void *bbuddy_palloc(struct uk_alloc *a, size_t order)
        UK_ASSERT(a != NULL);
        b = (struct uk_bbpalloc *)&a->priv;
 
+       size_t order = uk_alloc_size_to_order(size);
+
        /* Find smallest order which can satisfy the request. */
        for (i = order; i < FREELIST_SIZE; i++) {
                if (!FREELIST_EMPTY(b->free_head[i]))
@@ -280,7 +292,7 @@ no_memory:
        return NULL;
 }
 
-static void bbuddy_pfree(struct uk_alloc *a, void *obj, size_t order)
+static void bbuddy_pfree(struct uk_alloc *a, void *obj, size_t size)
 {
        struct uk_bbpalloc *b;
        chunk_head_t *freed_ch, *to_merge_ch;
@@ -290,6 +302,8 @@ static void bbuddy_pfree(struct uk_alloc *a, void *obj, 
size_t order)
        UK_ASSERT(a != NULL);
        b = (struct uk_bbpalloc *)&a->priv;
 
+       size_t order = uk_alloc_size_to_order(size);
+
        /* if the object is not page aligned it was clearly not from us */
        UK_ASSERT((((uintptr_t)obj) & (__PAGE_SIZE - 1)) == 0);
 
diff --git a/lib/uksched/sched.c b/lib/uksched/sched.c
index a250547..c67f7ce 100644
--- a/lib/uksched/sched.c
+++ b/lib/uksched/sched.c
@@ -141,7 +141,7 @@ static void *create_stack(struct uk_alloc *allocator)
 {
        void *stack;
 
-       stack = uk_palloc(allocator, STACK_SIZE_PAGE_ORDER);
+       stack = uk_palloc(allocator, STACK_SIZE);
        if (stack == NULL) {
                uk_pr_warn("Error allocating thread stack.");
                return NULL;
@@ -250,7 +250,7 @@ void uk_sched_thread_destroy(struct uk_sched *sched, struct 
uk_thread *thread)
 
        UK_TAILQ_REMOVE(&sched->exited_threads, thread, thread_list);
        uk_thread_fini(thread, sched->allocator);
-       uk_pfree(sched->allocator, thread->stack, STACK_SIZE_PAGE_ORDER);
+       uk_pfree(sched->allocator, thread->stack, STACK_SIZE);
        if (thread->tls)
                uk_free(sched->allocator, thread->tls);
        uk_free(sched->allocator, thread);
diff --git a/plat/xen/drivers/9p/9pfront.c b/plat/xen/drivers/9p/9pfront.c
index da55fd6..37559d8 100644
--- a/plat/xen/drivers/9p/9pfront.c
+++ b/plat/xen/drivers/9p/9pfront.c
@@ -55,6 +55,8 @@
 
 #define DRIVER_NAME    "xen-9pfront"
 
+#define order_to_size(order) ((__PAGE_SIZE) << (size_t)(order))
+
 static struct uk_alloc *a;
 static UK_LIST_HEAD(p9front_device_list);
 static DEFINE_SPINLOCK(p9front_device_list_lock);
@@ -189,10 +191,10 @@ static void p9front_free_dev_ring(struct p9front_dev 
*p9fdev, int idx)
        unbind_evtchn(ring->evtchn);
        for (i = 0; i < (1 << p9fdev->ring_order); i++)
                gnttab_end_access(ring->intf->ref[i]);
-       uk_pfree(a, ring->data.in,
-               p9fdev->ring_order + XEN_PAGE_SHIFT - PAGE_SHIFT);
+       size_t data_bytes_size = order_to_size(p9fdev->ring_order + 
XEN_PAGE_SHIFT - PAGE_SHIFT);
+       uk_pfree(a, ring->data.in, data_bytes_size);
        gnttab_end_access(ring->ref);
-       uk_pfree(a, ring->intf, 0);
+       uk_pfree(a, ring->intf, __PAGE_SIZE);
        ring->initialized = false;
 }
 
@@ -226,7 +228,7 @@ static int p9front_allocate_dev_ring(struct p9front_dev 
*p9fdev, int idx)
        ring->dev = p9fdev;
 
        /* Allocate ring intf page. */
-       ring->intf = uk_palloc(a, 0);
+       ring->intf = uk_palloc(a, __PAGE_SIZE);
        if (!ring->intf) {
                rc = -ENOMEM;
                goto out;
@@ -239,8 +241,8 @@ static int p9front_allocate_dev_ring(struct p9front_dev 
*p9fdev, int idx)
        UK_ASSERT(ring->ref != GRANT_INVALID_REF);
 
        /* Allocate memory for the data. */
-       data_bytes = uk_palloc(a,
-                       p9fdev->ring_order + XEN_PAGE_SHIFT - PAGE_SHIFT);
+       size_t data_bytes_size = order_to_size(p9fdev->ring_order + 
XEN_PAGE_SHIFT - PAGE_SHIFT);
+       data_bytes = uk_palloc(a, data_bytes_size);
        if (!data_bytes) {
                rc = -ENOMEM;
                goto out_free_intf;
@@ -295,11 +297,11 @@ out_free_thread:
 out_free_grants:
        for (i = 0; i < (1 << p9fdev->ring_order); i++)
                gnttab_end_access(ring->intf->ref[i]);
-       uk_pfree(a, data_bytes,
-               p9fdev->ring_order + XEN_PAGE_SHIFT - PAGE_SHIFT);
+       size_t data_bytes_size = order_to_size(p9fdev->ring_order + 
XEN_PAGE_SHIFT - PAGE_SHIFT);
+       uk_pfree(a, data_bytes, data_bytes_size);
 out_free_intf:
        gnttab_end_access(ring->ref);
-       uk_pfree(a, ring->intf, 0);
+       uk_pfree(a, ring->intf, __PAGE_SIZE);
 out:
        return rc;
 }
-- 
2.7.4


_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel

 


Rackspace

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