libbarrelfish: memobj_anon: fix vregion slab refilling
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Fri, 16 Dec 2016 07:37:18 +0000 (08:37 +0100)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 22 Dec 2016 21:47:02 +0000 (22:47 +0100)
Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

include/barrelfish/memobj.h
lib/barrelfish/vspace/memobj_anon.c

index d6867de..3475cee 100644 (file)
@@ -113,6 +113,7 @@ struct memobj_anon {
     struct memobj_frame_list *frame_list; ///< List of frames tracked by the obj
     struct slab_allocator frame_slab;         ///< Slab to back the frame list
     bool frame_slab_refilling;      ///< True, iff we're currently refilling `frame_slab`
+    bool vregion_slab_refilling;    ///< True, iff we're currently refilling `vregion_slab`
 };
 
 /**
index 5a47b24..caff280 100644 (file)
@@ -38,7 +38,8 @@ static errval_t map_region(struct memobj *memobj, struct vregion *vregion)
 
     // Allocate space
     struct vregion_list *data = slab_alloc(&anon->vregion_slab);
-    if (!data) { // Grow
+    if (slab_freecount(&anon->vregion_slab) <= 1 && !anon->vregion_slab_refilling) { // Grow
+        anon->vregion_slab_refilling = true;
         void *buf;
         err = vspace_pinned_alloc(&buf, VREGION_LIST);
         if (err_is_fail(err)) {
@@ -46,10 +47,13 @@ static errval_t map_region(struct memobj *memobj, struct vregion *vregion)
         }
         slab_grow(&anon->vregion_slab, buf,
                   VSPACE_PINNED_UNIT * sizeof(struct vregion_list));
-        data = slab_alloc(&anon->vregion_slab);
-        if (!data) {
-            return LIB_ERR_SLAB_ALLOC_FAIL;
+        if (data == NULL) {
+            data = slab_alloc(&anon->vregion_slab);
         }
+        anon->vregion_slab_refilling = false;
+    }
+    if (!data) {
+        return LIB_ERR_SLAB_ALLOC_FAIL;
     }
     data->region = vregion;
 
@@ -490,6 +494,7 @@ errval_t memobj_create_anon(struct memobj_anon *anon, size_t size,
     slab_init(&anon->vregion_slab, sizeof(struct vregion_list), NULL);
     slab_init(&anon->frame_slab, sizeof(struct memobj_frame_list), NULL);
 
+    anon->vregion_slab_refilling = false;
     anon->frame_slab_refilling = false;
 
     anon->vregion_list = NULL;