T258: refactor creation of new cspaces to make it cleaner
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 16 Aug 2016 16:29:22 +0000 (18:29 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 16 Aug 2016 16:32:09 +0000 (18:32 +0200)
This removes the need for manual updating of cnoderefs in libspawndomain. We
introduce a new function cnode_create_l1() for creating new L1 cnodes in L2
slots in our cspace, and rewrite cnode_create_foreign() to
cnode_create_foreign_l2() which takes a capref to an L1 cnode and a slot in
the L1 cnode for where to put the new L2 cnode.

Signed-off-by: Simon Gerber <simon.gerber@inf.ethz.ch>

errors/errno.fugu
include/barrelfish/capabilities.h
lib/barrelfish/capabilities.c
lib/spawndomain/spawn.c

index 51cb292..ee699a0 100755 (executable)
@@ -205,6 +205,7 @@ errors libbarrelfish LIB_ERR_ {
     // cspace
     failure CNODE_TYPE          "Type requested for cnode creation is not valid cnode type",
     failure CNODE_SLOTS         "#slots requested for cnode creation is invalid",
+    failure CROOT_NULL          "Destination root cnode null in cnode_create_foreign_l2",
 
     // nested errors in specific functions
     failure FRAME_ALLOC         "Failure in frame_alloc()",
@@ -213,6 +214,7 @@ errors libbarrelfish LIB_ERR_ {
     failure VNODE_CREATE        "Failure in vnode_create()",
     failure CNODE_CREATE        "Failure in cnode_create()",
     failure CNODE_CREATE_FROM_MEM "Failure in cnode_create_from_mem()",
+    failure CNODE_CREATE_FOREIGN_L2 "Failure in cnode_create_foreign_l2()",
     failure RAM_ALLOC           "Failure in ram_alloc()",
     failure RAM_ALLOC_WRONG_SIZE "Wrong size of memory requested in ram alloc",
     failure RAM_ALLOC_MS_CONSTRAINTS "Ram alloc failed due to constraints to mem_serv",
index 584378e..2915856 100644 (file)
@@ -29,9 +29,9 @@ __BEGIN_DECLS
 
 errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
                  cslot_t slots, cslot_t *retslots);
-errval_t cnode_create_foreign(struct capref *ret_dest, struct cnoderef *cnoderef,
-                              enum objtype cntype);
+errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot, struct cnoderef *cnoderef);
 errval_t cnode_create_l2(struct capref *ret_dest, struct cnoderef *cnoderef);
+errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef);
 errval_t cnode_create_raw(struct capref dest, struct cnoderef *cnoderef,
                           enum objtype cntype, cslot_t slots, cslot_t *retslots);
 errval_t cnode_create_with_guard(struct capref dest, struct cnoderef *cnoderef,
index d7dfa53..45e7a1d 100644 (file)
@@ -446,7 +446,6 @@ errval_t cnode_create_from_mem(struct capref dest, struct capref src,
 
 
     // Retype it to the destination
-    // debug_printf("objsize =%zu\n", slots * (1UL << OBJBITS_CTE));
     err = cap_retype(dest, src, 0, cntype, slots * (1UL << OBJBITS_CTE), 1);
     if (err_is_fail(err)) {
         return err_push(err, LIB_ERR_CAP_RETYPE);
@@ -455,7 +454,6 @@ errval_t cnode_create_from_mem(struct capref dest, struct capref src,
     // Construct the cnoderef to return
     if (cnoderef != NULL) {
         enum cnode_type ref_cntype = cntype == ObjType_L1CNode ? CNODE_TYPE_ROOT : CNODE_TYPE_OTHER;
-        // debug_printf("building cnoderef for objtype = %d, cntype = %d\n", cntype, ref_cntype);
         *cnoderef = build_cnoderef(dest, ref_cntype);
     }
 
@@ -473,7 +471,7 @@ errval_t cnode_create_from_mem(struct capref dest, struct capref src,
 errval_t cnode_create(struct capref *ret_dest, struct cnoderef *cnoderef,
                       cslot_t slots, cslot_t *retslots)
 {
-    USER_PANIC("cnode_create deprecated; use cnode_create_l1 or cnode_create_l2: %p %p %p %p\n",
+    USER_PANIC("cnode_create deprecated; use cnode_create_l1, cnode_create_l2, or cnode_create_foreign_l2: %p %p %p %p\n",
             __builtin_return_address(0),
 #ifdef __x86_64__
             __builtin_return_address(1),
@@ -515,36 +513,66 @@ errval_t cnode_create_l2(struct capref *ret_dest, struct cnoderef *cnoderef)
     return err;
 }
 
+errval_t cnode_create_l1(struct capref *ret_dest, struct cnoderef *cnoderef)
+{
+    errval_t err;
+
+    // Allocate a slot in root cn for destination
+    assert(ret_dest != NULL);
+    err = slot_alloc(ret_dest);
+    if (err_is_fail(err)) {
+        return err_push(err, LIB_ERR_SLOT_ALLOC);
+    }
+
+    cslot_t retslots;
+    err = cnode_create_raw(*ret_dest, cnoderef, ObjType_L1CNode,
+                           L2_CNODE_SLOTS, &retslots);
+    if (retslots != L2_CNODE_SLOTS) {
+        debug_printf("Unable to create initial L1 CNode: got %"PRIuCSLOT" slots instead of %"PRIuCSLOT"\n",
+                     retslots, (cslot_t)L2_CNODE_SLOTS);
+    }
+    return err;
+}
+
 /**
  * \brief Create a CNode for another cspace from newly-allocated RAM in a
  *        newly-allocated slot
  *
- * \param ret_dest capref struct to be filled-in with location of CNode
- * \param cnoderef cnoderef struct, filled-in if non-NULL with relevant info
- * \param cntype   the type for the new cnode
+ * \param dest_l1   capref to L1 (root) cnode of destination cspace
+ * \param dest_slot slot to fill with new cnode in destination L1 cnode
+ * \param cnoderef  cnoderef struct, filled-in if non-NULL with relevant info
  *
  * This function creates a CNode which contains 256 capabilities initially
  * and puts it in a slot in our cspace.
  */
-errval_t cnode_create_foreign(struct capref *ret_dest, struct cnoderef *cnoderef,
-                              enum objtype cntype)
+errval_t cnode_create_foreign_l2(struct capref dest_l1, cslot_t dest_slot,
+                                 struct cnoderef *cnoderef)
 {
     errval_t err;
 
-    // Allocate a slot in our cspace
-    assert(ret_dest != NULL);
-    err = slot_alloc(ret_dest);
-    if (err_is_fail(err)) {
-        return err_push(err, LIB_ERR_SLOT_ALLOC);
+    if (capref_is_null(dest_l1)) {
+        return LIB_ERR_CROOT_NULL;
     }
+    assert(!capref_is_null(dest_l1));
+
+    struct capref dest;
+    dest.cnode = build_cnoderef(dest_l1, CNODE_TYPE_ROOT);
+    dest.slot = dest_slot;
 
     cslot_t retslots;
-    err = cnode_create_raw(*ret_dest, cnoderef, cntype, L2_CNODE_SLOTS, &retslots);
+    err = cnode_create_raw(dest, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, &retslots);
     if (retslots != L2_CNODE_SLOTS) {
         debug_printf("Unable to create properly sized foreign CNode: "
                      "got %"PRIuCSLOT" slots instead of %"PRIuCSLOT"\n",
                      retslots, (cslot_t)L2_CNODE_SLOTS);
     }
+
+    // Create proper cnoderef for foreign L2
+    if (cnoderef) {
+        cnoderef->croot = get_cap_addr(dest_l1);
+        cnoderef->cnode = ROOTCN_SLOT_ADDR(dest_slot);
+        cnoderef->level = CNODE_TYPE_OTHER;
+    }
     return err;
 }
 
index f8850e9..a44d96c 100644 (file)
@@ -39,47 +39,27 @@ static errval_t spawn_setup_cspace(struct spawninfo *si)
     struct capref t1;
 
     /* Create root CNode */
-    err = cnode_create_foreign(&si->rootcn_cap, &si->rootcn, ObjType_L1CNode);
+    err = cnode_create_l1(&si->rootcn_cap, &si->rootcn);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_ROOTCN);
     }
 
     /* Create taskcn */
-    err = cnode_create_foreign(&si->taskcn_cap, &si->taskcn, ObjType_L2CNode);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_TASKCN, &si->taskcn);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_TASKCN);
     }
 
-    /* Copy taskcn into rootcn */
-    t1.cnode = si->rootcn;
-    t1.slot  = ROOTCN_SLOT_TASKCN;
-
-    err = cap_copy(t1, si->taskcn_cap);
-    if (err_is_fail(err)) {
-        return err_push(err, SPAWN_ERR_MINT_TASKCN);
-    }
-
-    /* Update taskcn cnoderef to refer to copy in new cspace */
-    si->taskcn.croot = get_cap_addr(si->rootcn_cap);
-    si->taskcn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_TASKCN);
-    si->taskcn.level = CNODE_TYPE_OTHER;
-
     /* Create slot_alloc_cnode */
-    t1.cnode = si->rootcn;
-    t1.slot  = ROOTCN_SLOT_SLOT_ALLOC0;
-    err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC0, NULL);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
     }
-    t1.cnode = si->rootcn;
-    t1.slot  = ROOTCN_SLOT_SLOT_ALLOC1;
-    err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC1, NULL);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
     }
-    t1.cnode = si->rootcn;
-    t1.slot  = ROOTCN_SLOT_SLOT_ALLOC2;
-    err = cnode_create_raw(t1, NULL, ObjType_L2CNode, L2_CNODE_SLOTS, NULL);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_SLOT_ALLOC2, NULL);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_SLOTALLOC_CNODE);
     }
@@ -134,27 +114,14 @@ static errval_t spawn_setup_cspace(struct spawninfo *si)
     memset(&si->argspg, 0, sizeof(si->argspg));
 
     /* Fill up basecn */
-    struct capref   basecn_cap;
     struct cnoderef basecn;
 
     // Create basecn in our rootcn so we can copy stuff in there
-    err = cnode_create_foreign(&basecn_cap, &basecn, ObjType_L2CNode);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_BASE_PAGE_CN, &basecn);
     if (err_is_fail(err)) {
         return err_push(err, LIB_ERR_CNODE_CREATE);
     }
 
-    // copy basecn into new cspace's rootcn
-    t1.cnode = si->rootcn;
-    t1.slot  = ROOTCN_SLOT_BASE_PAGE_CN;
-    err = cap_copy(t1, basecn_cap);
-    if (err_is_fail(err)) {
-        return err_push(err, SPAWN_ERR_MINT_BASE_PAGE_CN);
-    }
-
-    basecn.croot = get_cap_addr(si->rootcn_cap);
-    basecn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_BASE_PAGE_CN);
-    basecn.level = CNODE_TYPE_OTHER;
-
     // get big RAM cap for L2_CNODE_SLOTS BASE_PAGE_SIZEd caps
     struct capref ram;
     err = ram_alloc(&ram, L2_CNODE_BITS + BASE_PAGE_BITS);
@@ -186,23 +153,14 @@ static errval_t spawn_setup_vspace(struct spawninfo *si)
     errval_t err;
 
     /* Create pagecn */
-    err = cnode_create_foreign(&si->pagecn_cap, &si->pagecn, ObjType_L2CNode);
+    err = cnode_create_foreign_l2(si->rootcn_cap, ROOTCN_SLOT_PAGECN, &si->pagecn);
     if (err_is_fail(err)) {
         return err_push(err, SPAWN_ERR_CREATE_PAGECN);
     }
-    // fixup si->pagecn
-    si->pagecn.croot = get_cap_addr(si->rootcn_cap);
-    si->pagecn.cnode = ROOTCN_SLOT_ADDR(ROOTCN_SLOT_PAGECN);
-    si->pagecn.level = CNODE_TYPE_OTHER;
-
-    /* Mint pagecn into si->rootcn */
-    struct capref pagecn = (struct capref){.cnode = si->rootcn, .slot = ROOTCN_SLOT_PAGECN};
-    err = cap_copy(pagecn, si->pagecn_cap);
-    if (err_is_fail(err)) {
-        return err_push(err, SPAWN_ERR_MINT_PAGECN);
-    }
 
     /* Init pagecn's slot allocator */
+    si->pagecn_cap.cnode = si->rootcn;
+    si->pagecn_cap.slot = ROOTCN_SLOT_PAGECN;
 
     // XXX: satisfy a peculiarity of the single_slot_alloc_init_raw API
     size_t bufsize = SINGLE_SLOT_ALLOC_BUFLEN(PAGE_CNODE_SLOTS);
@@ -1027,12 +985,9 @@ errval_t spawn_run(struct spawninfo *si)
 errval_t spawn_free(struct spawninfo *si)
 {
     cap_destroy(si->rootcn_cap);
-    cap_destroy(si->taskcn_cap);
-    cap_destroy(si->pagecn_cap);
     cap_destroy(si->dispframe);
     cap_destroy(si->dcb);
     cap_destroy(si->argspg);
-    cap_destroy(si->vtree);
 
     return SYS_ERR_OK;
 }