Preallocate an L2 cnode and fill it with domain caps in proc_mgmt.
authorRazvan Damachi <damachir@emmentaler2.ethz.ch>
Fri, 25 Aug 2017 12:50:06 +0000 (14:50 +0200)
committerSimon Gerber <simon.gerber@inf.ethz.ch>
Thu, 31 Aug 2017 14:35:10 +0000 (16:35 +0200)
Instead of repyting domain capabilities individually, the process manager now
preallocates an L2 cnode and fills it with 256 domain capabilities at a time.

Signed-off-by: Razvan Damachi <razvan.damachi@gmail.com>

kernel/capabilities.c
usr/proc_mgmt/domain.c

index dc05297..a668b8e 100644 (file)
@@ -440,6 +440,9 @@ static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t o
             return srcsize / OBJSIZE_KCB;
         }
 
+    case ObjType_Domain:
+        return L2_CNODE_SLOTS;
+
     case ObjType_Kernel:
     case ObjType_IRQTable:
     case ObjType_IRQDest:
@@ -451,7 +454,6 @@ static size_t caps_max_numobjs(enum objtype type, gensize_t srcsize, gensize_t o
     case ObjType_PerfMon:
     case ObjType_IPI:
     case ObjType_ProcessManager:
-    case ObjType_Domain:
     case ObjType_VNode_ARM_l1_Mapping:
     case ObjType_VNode_ARM_l2_Mapping:
     case ObjType_VNode_AARCH64_l0_Mapping:
@@ -1024,19 +1026,23 @@ static errval_t caps_create(enum objtype type, lpaddr_t lpaddr, gensize_t size,
         assert(lpaddr  == 0);
         assert(size    == 0);
         assert(objsize == 0);
-        assert(count   == 1);
+        assert(count   <= L2_CNODE_SLOTS);
 
         // Prevent wrap around
-        if (domain_cap_counter >= UINT32_MAX) {
+        if (domain_cap_counter + count >= UINT32_MAX) {
             return SYS_ERR_DOMAIN_SPACE_EXHAUSTED;
         }
 
-        // Generate a new ID, core_local_id monotonically increases
-        temp_cap.u.domain.coreid = my_core_id;
-        temp_cap.u.domain.core_local_id = domain_cap_counter++;
-
-        // Insert the capability
-        err = set_cap(&dest_caps->cap, &temp_cap);
+        for(size_t i = 0; i < count; i++) {
+            // Initialize type specific fields
+            temp_cap.u.domain.coreid = my_core_id;
+            temp_cap.u.domain.core_local_id = domain_cap_counter++;
+            // Insert the capability
+            err = set_cap(&dest_caps[i].cap, &temp_cap);
+            if (err_is_fail(err)) {
+                break;
+            }
+        }
         break;
     case ObjType_IO:
         temp_cap.u.io.start = 0;
index 15d6987..e8cc437 100644 (file)
@@ -19,7 +19,7 @@
 #define HASH_INDEX_BUCKETS 6151
 static collections_hash_table* domain_table = NULL;
 
-#define DOMAIN_CAP_REFILL_COUNT 128
+#define DOMAIN_CAP_REFILL_COUNT L2_CNODE_SLOTS//1
 static struct domain_cap_node *domain_cap_list = NULL;
 static uint32_t free_domain_caps = 0;
 
@@ -50,24 +50,63 @@ inline bool domain_should_refill_caps(void) {
 
 errval_t domain_prealloc_caps(void)
 {
-    for (size_t i = 0; i < DOMAIN_CAP_REFILL_COUNT; ++i) {
+    // for (size_t i = 0; i < DOMAIN_CAP_REFILL_COUNT; ++i) {
+    //     struct domain_cap_node *node = (struct domain_cap_node*) malloc(
+    //             sizeof(struct domain_cap_node));
+    //     errval_t err = slot_alloc(&node->domain_cap);
+    //     if (err_is_fail(err)) {
+    //         DEBUG_ERR(err, "slot_alloc domain_cap");
+    //         return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
+    //     }
+
+    //     err = cap_retype(node->domain_cap, cap_procmng, 0, ObjType_Domain, 0, 1);
+    //     if (err_is_fail(err)) {
+    //         DEBUG_ERR(err, "cap_retype domain_cap");
+    //         return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
+    //     }
+
+    //     err = domain_cap_hash(node->domain_cap, &node->hash);
+    //     if (err_is_fail(err)) {
+    //         DEBUG_ERR(err, "domain_cap_hash");
+    //         return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
+    //     }
+
+    //     node->next = domain_cap_list;
+    //     domain_cap_list = node;
+    //     ++free_domain_caps;
+    // }
+
+    // return SYS_ERR_OK;
+
+
+    struct capref new_cnode_cap;
+    struct cnoderef new_cnode;
+    errval_t err = cnode_create_l2(&new_cnode_cap, &new_cnode);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "cnode_create_l2");
+        return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
+    }
+
+    struct capref cap_iter = {
+        .cnode = new_cnode,
+        .slot = 0
+    };
+    err = cap_retype(cap_iter, cap_procmng, 0, ObjType_Domain, 0,
+                     DOMAIN_CAP_REFILL_COUNT);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "cap_retype");
+        return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
+    }
+
+    for (cap_iter.slot = 0; cap_iter.slot < DOMAIN_CAP_REFILL_COUNT; ++cap_iter.slot) {
         struct domain_cap_node *node = (struct domain_cap_node*) malloc(
                 sizeof(struct domain_cap_node));
-        errval_t err = slot_alloc(&node->domain_cap);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "slot_alloc domain_cap");
-            return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
-        }
-
-        err = cap_retype(node->domain_cap, cap_procmng, 0, ObjType_Domain, 0, 1);
-        if (err_is_fail(err)) {
-            DEBUG_ERR(err, "cap_retype domain_cap");
-            return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
-        }
+        node->domain_cap = cap_iter;
 
         err = domain_cap_hash(node->domain_cap, &node->hash);
         if (err_is_fail(err)) {
-            return err;
+            DEBUG_ERR(err, "domain_cap_hash");
+            return err_push(err, PROC_MGMT_ERR_CREATE_DOMAIN_CAP);
         }
 
         node->next = domain_cap_list;