devif: debug fixed case when IDC backend us used
authorRoni Häcki <roni.haecki@inf.ethz.ch>
Mon, 28 Aug 2017 09:14:37 +0000 (11:14 +0200)
committerRoni Häcki <roni.haecki@inf.ethz.ch>
Mon, 28 Aug 2017 09:14:37 +0000 (11:14 +0200)
When both endpoints of the IDC backend are were using the debug queue
on top, the regions were not consistent in the debug layer

Signed-off-by: Roni Häcki <roni.haecki@inf.ethz.ch>

include/devif/backends/debug.h
lib/devif/backends/debug/devif_backend_debug.c
usr/tests/devif/idc_endpoint.c

index 164213e..19f7eb3 100644 (file)
@@ -27,4 +27,30 @@ errval_t debug_destroy(struct debug_q* q, struct devq* other_q);
 errval_t debug_dump_region(struct debug_q* que, regionid_t rid);
 
 void debug_dump_history(struct debug_q* q);
+
+
+/**
+ * @brief Adding region to debug queue. When using two endpoints
+ *        Only the lowest layer is consistent with the regions
+ *        To mache the debugging layer consistent, this method adds the region
+ *        to the known regions so that the ckecks when dequeueing work
+ *
+ * @param q                     Return pointer to the descriptor queue
+ * @param cap                   cap to the region
+ * @param rid                  the regionid of the region
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t debug_add_region(struct debug_q*, struct capref cap,
+                         regionid_t rid);
+
+/**
+ * @brief Removing region from debug queue
+ *
+ * @param q                     Return pointer to the descriptor queue
+ * @param rid                  the regionid of the region
+ *
+ * @returns error on failure or SYS_ERR_OK on success
+ */
+errval_t debug_remove_region(struct debug_q*, regionid_t rid);
 #endif /* DEVIF_DEBUG_H_ */
index de76067..442f09e 100644 (file)
  * If a buffer is dequeued the buffer is added to the existing memory
  * chunks if possible, otherwise a new memory chunk is added to the
  * list of chunks. If a buffer is dequeued that is in between two
- * memory chunks, the memory chunks are merged to one big chunk. 
+ * memory chunks, the memory chunks are merged to one big chunk.
+ * We might fail to find the region id in our list of regions. In this
+ * case we add the region with the deqeued offset+length as a size.
+ * We can be sure that this region exists since the devq library itself
+ * does these checks if the region is known to the endpoint. This simply
+ * means the debugging queue on top of the other queue does not have a 
+ * consistant view of the registered regions (but the queue below does)
  *
  * When a region is deregistered, the list of chunks has to only 
  * contain a single chunk that descirbes the whole region. Otherwise
@@ -62,6 +68,8 @@ struct memory_ele {
 struct memory_list {
     regionid_t rid;
     genoffset_t length;
+    // is a region that we did not register ourselves
+    bool not_consistent;
     struct memory_ele* buffers;
     struct memory_list* next; // next in list of lists
 };
@@ -179,6 +187,7 @@ static errval_t debug_register(struct devq* q, struct capref cap,
         que->regions = calloc(1, sizeof(struct memory_list));
         que->regions->rid = rid;
         que->regions->length = id.bytes;
+        que->regions->not_consistent = false;
         que->regions->next = NULL;
         // add the whole regions as a buffer
         que->regions->buffers = slab_alloc(&que->alloc);
@@ -208,6 +217,7 @@ static errval_t debug_register(struct devq* q, struct capref cap,
     ele->rid = rid;
     ele->next = NULL;
     ele->length = id.bytes;
+    ele->not_consistent = false;
     // add the whole regions as a buffer
     ele->buffers = slab_alloc(&que->alloc);
     memset(ele->buffers, 0, sizeof(ele->buffers));
@@ -708,22 +718,70 @@ static errval_t debug_dequeue(struct devq* q, regionid_t* rid, genoffset_t* offs
 {
     errval_t err;
     struct debug_q* que = (struct debug_q*) q;
+    assert(que->q->f.deq != NULL);
     err = que->q->f.deq(que->q, rid, offset, length, valid_data,
                         valid_length, flags);
     if (err_is_fail(err)) {
         return err;
     }
-
     DEBUG("dequeued offset=%lu \n", *offset);
 
     struct memory_list* region = NULL;
 
     err = find_region(que, &region, *rid);
     if (err_is_fail(err)){
-        return err;
+        // region ids are checked bythe devq library, if we do not find
+        // the region id when dequeueing here we do not have a consistant
+        // view of two endpoints
+        //
+        // Add region
+        if (que->regions == NULL) {
+            printf("Adding region frirst %d len \n", *offset + *length);
+            que->regions = calloc(1, sizeof(struct memory_list));
+            que->regions->rid = *rid;
+            que->regions->not_consistent = true;
+            // region is at least offset + length
+            que->regions->length = *offset + *length;
+            que->regions->next = NULL;
+            // add the whole regions as a buffer
+            que->regions->buffers = slab_alloc(&que->alloc);
+            memset(que->regions->buffers, 0, sizeof(que->regions->buffers));
+            que->regions->buffers->offset = 0;
+            que->regions->buffers->length = *offset + *length;
+            que->regions->buffers->next = NULL;
+            return SYS_ERR_OK;
+        }
+
+        struct memory_list* ele = que->regions;
+        while (ele->next != NULL) {
+            ele = ele->next;
+        }
+
+        printf("Adding region second %d len \n", *offset + *length);
+        // add the reigon
+        ele->next = calloc(1,sizeof(struct memory_list));
+        ele = ele->next;
+
+        ele->rid = *rid;
+        ele->next = NULL;
+        ele->not_consistent = true;
+        ele->length = *offset + *length;
+        // add the whole regions as a buffer
+        ele->buffers = slab_alloc(&que->alloc);
+        memset(ele->buffers, 0, sizeof(ele->buffers));
+        ele->buffers->offset = 0;
+        ele->buffers->length = *offset + *length;
+        ele->buffers->next = NULL;
+        return SYS_ERR_OK;
     }
 
-    check_consistency(region);
+    if (region->not_consistent) {
+        if ((*offset + *length) > region->length) {
+            region->length = *offset + *length;
+        }
+    }
+
+    //check_consistency(region);
 
     // find the buffer 
     struct memory_ele* buffer = region->buffers;
@@ -831,3 +889,14 @@ void debug_dump_history(struct debug_q* q)
 {
     dump_history(q);
 }
+
+errval_t debug_add_region(struct debug_q* q, struct capref cap,
+                         regionid_t rid)
+{
+    return devq_add_region((struct devq*) q, cap, rid);
+}
+
+errval_t debug_remove_region(struct debug_q* q, regionid_t rid)
+{
+    return devq_remove_region((struct devq*) q, rid);
+}
index 3615851..0d47a9d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2008, 2009, 2010, 2011, 2012, ETH Zurich.
+ * Copyright (c) 2017 ETH Zurich.
  * All rights reserved.
  *
  * This file is distributed under the terms in the attached LICENSE file.
 #include <barrelfish/deferred.h>
 #include <devif/queue_interface.h>
 #include <devif/backends/descq.h>
+#include <devif/backends/debug.h>
 
 
 static uint16_t qid = 0;
 
 static struct ele* list = NULL;
 static struct ele* end = NULL;
+static struct devq* descq;
+static struct devq* debug;
+
 
 struct ele {
     struct  descq* q;
@@ -45,7 +49,14 @@ static errval_t create(struct descq* q, bool notifications, uint8_t role,
         end->next = item;
         end = item;
     }
-    
+
+    // stack debug queue on top
+    errval_t err;
+    err = debug_create((struct debug_q**) &debug, (struct devq*) q);
+    if (err_is_fail(err)) {
+        USER_PANIC("Allocating debug q failed \n");
+    }
+   
     qid++;
     return SYS_ERR_OK;
 }
@@ -59,7 +70,8 @@ static errval_t destroy(struct descq* q)
 static errval_t notify(struct descq* q)
 {
 
-    struct devq* queue = (struct devq*) q;
+    //struct devq* queue = (struct devq*) q;
+    struct devq* queue = (struct devq*) debug;
     errval_t err = SYS_ERR_OK;
     //errval_t err2 = SYS_ERR_OK;
     regionid_t rid;
@@ -100,13 +112,13 @@ static errval_t notify(struct descq* q)
 static errval_t reg(struct descq* q, struct capref cap,
                     regionid_t rid)
 {
-    return SYS_ERR_OK;
+    return debug_add_region((struct debug_q*) debug, cap, rid);
 }
 
 
 static errval_t dereg(struct descq* q, regionid_t rid)
 {
-    return SYS_ERR_OK;
+    return debug_remove_region((struct debug_q*) debug, rid);
 }
 
 
@@ -129,13 +141,13 @@ int main(int argc, char *argv[])
     f->dereg = dereg;
     f->control = control;
 
-    struct descq* exp_queue;
-
-    err = descq_create(&exp_queue, DESCQ_DEFAULT_SIZE, "test_queue", 
+    err = descq_create((struct descq**)&descq, DESCQ_DEFAULT_SIZE, "test_queue", 
                        true, true, 0, &id, f);
+    if (err_is_fail(err)) {
+        USER_PANIC("Allocating debug q failed \n");
+    }
 
     assert(err_is_ok(err));
-
     while(true) {
         event_dispatch(get_default_waitset());
     }