Added invocation to remove kcb from kcb scheduling ring.
authorSimon Gerber <simon.gerber@inf.ethz.ch>
Tue, 14 Jan 2014 10:39:08 +0000 (11:39 +0100)
committerGerd Zellweger <mail@gerdzellweger.com>
Tue, 14 Oct 2014 06:47:46 +0000 (08:47 +0200)
errors/errno.fugu
include/barrelfish_kpi/capabilities.h
kernel/arch/x86_64/irq.c
kernel/arch/x86_64/syscall.c
kernel/include/kcb.h
usr/monitor/include/arch/x86_64/monitor_invocations.h

index 4764ec1..7cf4279 100644 (file)
@@ -136,6 +136,8 @@ errors kernel SYS_ERR_ {
     failure I2C_WAIT_FOR_BUS            "Wait for bus free timed out",
     failure I2C_FAILURE                 "I2C subsystem failure",
 
+    // KCB and related errors
+    failure KCB_NOT_FOUND               "Did not find the given kcb.",
 };
 
 // errors generated by libcaps
index 7e0c970..1a52024 100644 (file)
@@ -195,6 +195,7 @@ enum kernel_cmd {
     KernelCmd_GetGlobalPhys,      ///< Get physical address of kernel variable struct global;
     KernelCmd_StartCore,          ///<
     KernelCmd_Add_kcb,            ///< add extra kcb to be scheduled
+    KernelCmd_Remove_kcb,         ///< remove kcb from scheduling ring
     KernelCmd_Count
 };
 
index 21ddf8b..c819e53 100644 (file)
@@ -368,7 +368,6 @@ HW_EXCEPTION_NOERR(666);
 static struct gate_descriptor idt[NIDT] __attribute__ ((aligned (16)));
 
 static int timer_fired = 0;
-extern struct dcb *queue_tail; // from rbed scheduler
 
 #if CONFIG_TRACE && NETWORK_STACK_TRACE
 #define TRACE_ETHERSRV_MODE 1
@@ -820,10 +819,7 @@ static __attribute__ ((used)) void handle_irq(int vector)
         // switch kcb every 5 time slices (SG: I just picked 5 arbitrarily)
         if (timer_fired % 5 == 0 && kcb_current->next) {
             printk(LOG_NOTE, "switching from kcb(%p) to kcb(%p)\n", kcb_current, kcb_current->next);
-            kcb_current = kcb_current->next;
-            mdb_init(kcb_current);
-            // update queue tail to make associated assembly not choke
-            queue_tail = kcb_current->queue_tail;
+            switch_kcb(kcb_current->next);
         }
         apic_eoi();
         assert(kernel_ticks_enabled);
index ae50cef..7d743a9 100644 (file)
@@ -383,6 +383,42 @@ static struct sysret kernel_add_kcb(struct capability *kern_cap,
     return SYSRET(SYS_ERR_OK);
 }
 
+static struct sysret kernel_remove_kcb(struct capability *kern_cap,
+                                       int cmd, uintptr_t *args)
+{
+    uint64_t kcb_addr = args[0];
+
+    struct kcb *to_remove = (struct kcb *)kcb_addr;
+    struct kcb *k = kcb_current;
+
+    do {
+        if (k == to_remove) {
+            if (k == kcb_current) {
+                // switch to next available kcb if we're removing the kcb that
+                // is currently being scheduled.
+                switch_kcb(kcb_current->next);
+            }
+            // remove kcb from ring
+            k->prev->next = k->next;
+            k->next->prev = k->prev;
+            if (k->next->next == k->next) {
+                // clear ring to disable switching mechanism if only one kcb
+                // left
+                k->next->next = k->next->prev = NULL;
+            }
+            // clear next and prev of removed kcb to not leak other kcb addrs
+            k->next = k->prev = NULL;
+
+            // break out if we're done
+            return SYSRET(SYS_ERR_OK);
+        }
+        k = k->next;
+    } while (k != kcb_current);
+
+    return SYSRET(SYS_ERR_KCB_NOT_FOUND);
+}
+
+
 
 static struct sysret monitor_get_core_id(struct capability *kernel_cap,
                                          int cmd, uintptr_t *args)
@@ -951,6 +987,7 @@ static invocation_handler_t invocations[ObjType_Num][CAP_MAX_CMD] = {
         [KernelCmd_GetGlobalPhys] = kernel_get_global_phys,
         [KernelCmd_StartCore] = kernel_start_core,
         [KernelCmd_Add_kcb]      = kernel_add_kcb,
+        [KernelCmd_Remove_kcb]   = kernel_remove_kcb,
     },
     [ObjType_IRQTable] = {
         [IRQTableCmd_Set] = handle_irq_table_set,
index 2763637..296a1d3 100644 (file)
@@ -18,6 +18,7 @@
 #include <kernel.h>
 #include <capabilities.h>
 #include <irq.h>
+#include <mdb/mdb_tree.h>
 
 struct cte;
 struct dcb;
@@ -83,5 +84,15 @@ static inline void print_kcb(void)
     // TODO interrupt state
 }
 
+// XXX: this is from RBED, don't know how to properly have this here -SG
+extern struct dcb *queue_tail;
+static inline void switch_kcb(struct kcb *next)
+{
+    kcb_current = next;
+    mdb_init(kcb_current);
+    // update queue tail to make associated assembly not choke
+    queue_tail = kcb_current->queue_tail;
+}
+
 
 #endif
index 2c31958..f0fa991 100644 (file)
@@ -185,4 +185,12 @@ invoke_monitor_add_kcb(uintptr_t kcb_base)
     return cap_invoke2(cap_kernel, KernelCmd_Add_kcb, kcb_base).error;
 }
 
+static inline errval_t
+invoke_monitor_remove_kcb(uintptr_t kcb_base)
+{
+    assert(kcb_base);
+
+    return cap_invoke2(cap_kernel, KernelCmd_Remove_kcb, kcb_base).error;
+}
+
 #endif