Added remapping functionality for malloc.
authorSimon Gerber <simon.gerber@hp.com>
Fri, 18 Jul 2014 16:56:24 +0000 (09:56 -0700)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Mon, 4 May 2015 09:28:13 +0000 (11:28 +0200)
Signed-off-by: Simon Gerber <simon.gerber@hp.com>

include/barrelfish/morecore.h
include/barrelfish/vspace_mmu_aware.h
lib/barrelfish/init.c
lib/barrelfish/morecore.c
lib/barrelfish/vspace/mmu_aware.c

index 37bcf76..2c49b22 100644 (file)
@@ -5,11 +5,12 @@
 
 /*
  * Copyright (c) 2007, 2008, 2009, ETH Zurich.
+ * Copyright (c) 2014, HP Labs.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
  * If you do not find this file, copies can be found by writing to:
- * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ * ETH Zurich D-INFK, Universitaetstr. 6, CH-8092 Zurich. Attn: Systems Group.
  */
 
 #ifndef BARRELFISH_MORECORE_H
@@ -21,6 +22,7 @@ __BEGIN_DECLS
 
 errval_t morecore_init(void);
 void morecore_use_optimal(void);
+errval_t morecore_reinit(void);
 
 __END_DECLS
 
index 4cb28e3..14446e5 100644 (file)
@@ -40,6 +40,8 @@ errval_t vspace_mmu_aware_init(struct vspace_mmu_aware *state, size_t size);
 errval_t vspace_mmu_aware_init_aligned(struct vspace_mmu_aware *state,
                                        size_t size, size_t alignment,
                                        vregion_flags_t flags);
+errval_t vspace_mmu_aware_reset(struct vspace_mmu_aware *state,
+                                struct capref frame, size_t size);
 errval_t vspace_mmu_aware_map(struct vspace_mmu_aware *state,
                               struct capref frame, size_t req_size,
                               void **retbuf, size_t *retsize);
index a803a54..c82eadc 100644 (file)
@@ -4,7 +4,8 @@
  */
 
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
+ * Copyright (c) 2007-2012, ETH Zurich.
+ * Copyright (c) 2014, HP Labs.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
@@ -245,6 +246,12 @@ errval_t barrelfish_init_onthread(struct spawn_domain_params *params)
         return err_push(err, LIB_ERR_RAM_ALLOC_SET);
     }
 
+    // switch morecore to intended configuration
+    err = morecore_reinit();
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_MORECORE_INIT);
+    }
+
 #ifdef CONFIG_TRACE
     err = trace_my_setup();
     if (err_is_fail(err)) {
index 0f061d1..28b671a 100644 (file)
@@ -126,3 +126,24 @@ errval_t morecore_init(void)
 
     return SYS_ERR_OK;
 }
+
+errval_t morecore_reinit(void)
+{
+    errval_t err;
+    struct morecore_state *state = get_morecore_state();
+
+    size_t mapoffset = state->mmu_state.mapoffset;
+    size_t remapsize = ROUND_UP(mapoffset, state->mmu_state.alignment);
+    if (remapsize == mapoffset) {
+        // don't need to do anything if we only recreate the exact same
+        // mapping
+        return SYS_ERR_OK;
+    }
+    struct capref frame;
+    size_t retsize;
+    err = frame_alloc(&frame, remapsize, &retsize);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    return vspace_mmu_aware_reset(&state->mmu_state, frame, remapsize);
+}
index 3c5a9ec..b5f4cd5 100644 (file)
@@ -19,6 +19,7 @@
 #include <barrelfish/barrelfish.h>
 #include <barrelfish/vspace_mmu_aware.h>
 #include <barrelfish/core_state.h>
+#include <string.h>
 
 /// Minimum free memory before we return it to memory server
 #define MIN_MEM_FOR_FREE        (1 * 1024 * 1024)
@@ -140,6 +141,74 @@ errval_t vspace_mmu_aware_map(struct vspace_mmu_aware *state,
     return SYS_ERR_OK;
 }
 
+errval_t vspace_mmu_aware_reset(struct vspace_mmu_aware *state,
+                                struct capref frame, size_t size)
+{
+    errval_t err;
+    struct vregion *vregion;
+    struct capref oldframe;
+    void *vbuf;
+    // create copy of new region
+    err = slot_alloc(&oldframe);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    err = cap_copy(oldframe, frame);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    err = vspace_map_one_frame_attr_aligned(&vbuf, size, oldframe,
+            VREGION_FLAGS_READ_WRITE | VREGION_FLAGS_LARGE, LARGE_PAGE_SIZE,
+            NULL, &vregion);
+    if (err_is_fail(err)) {
+        return err;
+    }
+    // copy over data to new frame
+    genvaddr_t gen_base = vregion_get_base_addr(&state->vregion);
+    memcpy(vbuf, (void*)gen_base, state->mapoffset);
+
+    err = vregion_destroy(vregion);
+    if (err_is_fail(err)) {
+        return err;
+    }
+
+    size_t offset = 0;
+    // Unmap backing frames for [0, size) in state.vregion
+    do {
+        err = state->memobj.m.f.unfill(&state->memobj.m, 0, &oldframe,
+                &offset);
+        if (err_is_fail(err) &&
+            err_no(err) != LIB_ERR_MEMOBJ_UNFILL_TOO_HIGH_OFFSET)
+        {
+            return err_push(err, LIB_ERR_MEMOBJ_UNMAP_REGION);
+        }
+        struct frame_identity fi;
+        // increase address
+        err = invoke_frame_identify(oldframe, &fi);
+        if (err_is_fail(err)) {
+            return err;
+        }
+        offset += (1UL<<fi.bits);
+        err = cap_destroy(oldframe);
+        if (err_is_fail(err)) {
+            return err;
+        }
+    } while(offset < state->mapoffset);
+
+    // Map new frame in
+    err = state->memobj.m.f.fill(&state->memobj.m, 0, frame, size);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_MEMOBJ_FILL);
+    }
+    err = state->memobj.m.f.pagefault(&state->memobj.m, &state->vregion, 0, 0);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_MEMOBJ_PAGEFAULT_HANDLER);
+    }
+
+    state->mapoffset = size;
+    return SYS_ERR_OK;
+}
+
 errval_t vspace_mmu_aware_unmap(struct vspace_mmu_aware *state,
                                 lvaddr_t base, size_t bytes)
 {