x86boot can give kcb from a core to core 0.
authorGerd Zellweger <mail@gerdzellweger.com>
Mon, 13 Jan 2014 14:43:45 +0000 (15:43 +0100)
committerGerd Zellweger <mail@gerdzellweger.com>
Tue, 14 Oct 2014 06:47:45 +0000 (08:47 +0200)
invoke by calling: x86boot auto give 1 0
Give kcb to other cores than 0 currently untested, and probably does not yet
work.

if/intermon.if
if/monitor_blocking.if
include/arch/x86_64/barrelfish/invocations_arch.h
kernel/arch/x86/startup_x86.c
kernel/arch/x86_64/init.c
usr/drivers/cpuboot/x86boot.c
usr/monitor/inter.c
usr/monitor/monitor_rpc_server.c

index 6a36cbd..c78140d 100644 (file)
@@ -167,4 +167,7 @@ interface intermon "The Interface between monitors" {
 
     call power_down_request();
     response power_down_response();
+
+    call give_kcb_request(caprep kcb);
+    response give_kcb_response(errval err);
 };
index ee224d3..a764b4f 100644 (file)
@@ -61,4 +61,6 @@ interface monitor_blocking "The monitor to client RPC interface" {
 
     /* Scary */
     rpc get_kernel_cap(out cap cap);
+
+    rpc forward_kcb_request(in coreid destination, in cap kcb, out errval err);
 };
index c6df334..52b3d3f 100644 (file)
@@ -352,13 +352,13 @@ static inline errval_t invoke_dispatcher_dump_ptables(struct capref dispcap)
 }
 
 static inline errval_t invoke_perfmon_activate(struct capref perfmon_cap,
-                                               uint8_t event, uint8_t perf_umask, 
+                                               uint8_t event, uint8_t perf_umask,
                                                bool kernel, uint8_t counter_id,
-                                               uint64_t counter_value, 
+                                               uint64_t counter_value,
                                                capaddr_t ep_addr)
 {
-    return cap_invoke7(perfmon_cap, PerfmonCmd_Activate, 
-                       event, perf_umask, counter_id, kernel, 
+    return cap_invoke7(perfmon_cap, PerfmonCmd_Activate,
+                       event, perf_umask, counter_id, kernel,
                        counter_value, ep_addr).error;
 }
 
index e0fe86a..a171aab 100644 (file)
@@ -298,10 +298,6 @@ void kernel_startup(void)
         = (void *)((lvaddr_t)&_start_kernel - BASE_PAGE_SIZE);
 
     struct dcb *init_dcb;
-
-    kend = rdtscp();
-    printf("Time it took to initialize the kernel = %lu\n", kend-kstart);
-
     if (apic_is_bsp()) {
         if (bsp_coreid != 0) {
             my_core_id = bsp_coreid;
index 251e7c5..c433544 100644 (file)
@@ -484,12 +484,27 @@ static void  __attribute__ ((noreturn, noinline)) text_init(void)
     setup_default_idt();
     idt_initialized = true;
 
+    kend = rdtscp();
+    printf("Time for the kernel after setup_default_idt = %lu [ms]: %lu\n",
+           kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
     // Enable machine check reporting
     mcheck_init();
 
+    kend = rdtscp();
+    printf("Time for the kernel after mcheck_init = %lu [ms]: %lu\n",
+           kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
     // Initialize local APIC
     apic_init();
 
+    kend = rdtscp();
+    printf("Time for the kernel after apic_init = %lu [ms]: %lu\n",
+           kend-kstart, ((357*(kend-kstart))/1000000000));
+
+
     // do not remove/change this printf: needed by regression harness
     //printf("Barrelfish CPU driver starting on x86_64 apic_id %u\n", apic_id);
 
index de5e383..040ce0a 100644 (file)
@@ -47,8 +47,8 @@
 
 #include <bench/bench.h>
 
-//#define DEBUG(x...) debug_printf(x)
-#define DEBUG(x...) ((void)0)
+#define DEBUG(x...) debug_printf(x)
+//#define DEBUG(x...) ((void)0)
 
 uint64_t start = 0;
 uint64_t end = 0;
@@ -734,7 +734,15 @@ static errval_t create_or_get_kcb_cap(coreid_t coreid)
     DEBUG("%s:%s:%d: get capability\n",
            __FILE__, __FUNCTION__, __LINE__);
 
-    err = oct_get_capability("corexxx", &kcb);
+    int length = snprintf(NULL, 0, "kcb_id_%d", coreid) + 1; // +1 for \0
+    char* kcb_key = (char*)malloc(length);
+    assert (kcb_key != NULL);
+    snprintf(kcb_key, length+1, "kcb_id_%d", coreid);
+
+    DEBUG("%s:%s:%d: oct_get_capability for key = %s\n",
+           __FILE__, __FUNCTION__, __LINE__, kcb_key);
+
+    err = oct_get_capability(kcb_key, &kcb);
     if (err_is_ok(err)) {
         DEBUG("%s:%s:%d: kcb cap was cached\n",
                __FILE__, __FUNCTION__, __LINE__);
@@ -770,7 +778,7 @@ static errval_t create_or_get_kcb_cap(coreid_t coreid)
 
     DEBUG("%s:%s:%d: Store the kcb.\n",
            __FILE__, __FUNCTION__, __LINE__);
-    err = oct_put_capability("corexxx", kcb);
+    err = oct_put_capability(kcb_key, kcb);
     if (err_is_fail(err)) {
         DEBUG_ERR(err, "can not save the capability.");
     }
@@ -778,6 +786,24 @@ static errval_t create_or_get_kcb_cap(coreid_t coreid)
     return err;
 }
 
+static errval_t give_kcb_to_new_core(coreid_t destination_id, struct capref new_kcb)
+{
+    struct monitor_blocking_rpc_client *mc = get_monitor_blocking_rpc_client();
+    printf("%s:%s:%d: Send KCB to local monitor for forwarding to destination_id = %"PRIuCOREID"\n",
+           __FILE__, __FUNCTION__, __LINE__, destination_id);
+
+    errval_t ret_err;
+    errval_t err = mc->vtbl.forward_kcb_request(mc, destination_id, new_kcb, &ret_err);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "forward_kcb_request failed.");
+    }
+    if (err_is_fail(ret_err)) {
+        USER_PANIC_ERR(ret_err, "forward_kcb_request failed.");
+    }
+
+    printf("%s:%s:%d: KCB forwarded\n", __FILE__, __FUNCTION__, __LINE__);
+    return SYS_ERR_OK;
+}
 
 int main(int argc, char** argv)
 {
@@ -822,15 +848,15 @@ int main(int argc, char** argv)
 
     start = bench_tsc();
 
-    coreid_t destination = (coreid_t) atoi(argv[3]);
-    assert(destination < MAX_COREID);
+    coreid_t target_id = (coreid_t) atoi(argv[3]);
+    assert(target_id < MAX_COREID);
 
     err = oct_init();
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Octopus initialization failed.");
     }
 
-    err = create_or_get_kcb_cap(destination);
+    err = create_or_get_kcb_cap(target_id);
     if (err_is_fail(err)) {
         USER_PANIC_ERR(err, "Can not get kcb.");
     }
@@ -853,7 +879,7 @@ int main(int argc, char** argv)
              memcpy(sched, s, i);
              sched[i] = 0;
         }
-        err = spawn_xcore_monitor(destination, destination, CPU_X86_64, sched,
+        err = spawn_xcore_monitor(target_id, target_id, CPU_X86_64, sched,
                                   "loglevel=0 logmask=1", &new_binding, &frame);
         if (err_is_fail(err)) {
             USER_PANIC_ERR(err, "spawn xcore monitor failed.");
@@ -863,14 +889,32 @@ int main(int argc, char** argv)
                __FILE__, __FUNCTION__, __LINE__, end-start, bench_tsc_to_ms(end-start));
 
         struct monitor_binding *mb = get_monitor_binding();
-        err = mb->tx_vtbl.boot_core_request(mb, NOP_CONT, destination, frame);
+        err = mb->tx_vtbl.boot_core_request(mb, NOP_CONT, target_id, frame);
     }
     else if (!strcmp(argv[2], "down")) {
         DEBUG("%s:%d: Power it down...\n", __FILE__, __LINE__);
-        err = st->tx_vtbl.power_down(st, NOP_CONT, destination);
+        err = st->tx_vtbl.power_down(st, NOP_CONT, target_id);
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "power_down failed.");
+        }
+    }
+    else if (!strcmp(argv[2], "give")) {
+        assert (argc == 5);
+        DEBUG("%s:%d: Give kcb from core %s to core %s...\n",
+              __FILE__, __LINE__, argv[3], argv[4]);
+
+        coreid_t destination_id = (coreid_t) atoi(argv[4]);
+        assert(destination_id < MAX_COREID);
+
+        err = st->tx_vtbl.power_down(st, NOP_CONT, target_id);
         if (err_is_fail(err)) {
             USER_PANIC_ERR(err, "power_down failed.");
         }
+
+        err = give_kcb_to_new_core(destination_id, kcb);
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "Can not send KCB to another core.");
+        }
     }
     else if (!strcmp(argv[2], "resume")) {
         DEBUG("%s:%s:%d: Resume...\n", __FILE__, __FUNCTION__, __LINE__);
index f8871fc..e833fe9 100644 (file)
@@ -697,6 +697,35 @@ static void power_down_request(struct intermon_binding *b)
     //USER_PANIC("Return from power down request?");
 }
 
+static void give_kcb_request(struct intermon_binding *b, intermon_caprep_t kcb_rep)
+{
+    struct capability kcb_cap;
+    caprep_to_capability(&kcb_rep, &kcb_cap);
+    assert(kcb_cap.type != ObjType_Null);
+
+    struct capref kcb_capref;
+    errval_t err = monitor_cap_create(kcb_capref, &kcb_cap, my_core_id);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "monitor_cap_create failed");
+    }
+
+    printf("%s:%s:%d: Remote monitor: give kcb to kernel\n",
+                __FILE__, __FUNCTION__, __LINE__);
+
+    // kcb.u.base ...
+    err = invoke_monitor_add_kcb((uintptr_t)kcb_cap.u.kernelcontrolblock.kcb);
+
+    err = b->tx_vtbl.give_kcb_response(b, NOP_CONT, SYS_ERR_OK);
+    assert(err_is_ok(err));
+}
+
+static void give_kcb_response(struct intermon_binding *b, errval_t error)
+{
+    printf("%s:%s:%d: Local montior received answer\n",
+                __FILE__, __FUNCTION__, __LINE__);
+
+}
+
 extern struct monitor_binding* cpuboot_driver;
 
 static void power_down_response(struct intermon_binding* b)
@@ -741,6 +770,9 @@ static struct intermon_rx_vtbl the_intermon_vtable = {
 
     .power_down_request = power_down_request,
     .power_down_response = power_down_response,
+
+    .give_kcb_request = give_kcb_request,
+    .give_kcb_response = give_kcb_response,
 };
 
 errval_t intermon_init(struct intermon_binding *b, coreid_t coreid)
index 8b79199..d594b13 100644 (file)
@@ -687,6 +687,57 @@ static void get_kernel_cap(struct monitor_blocking_binding *b)
     }
 }
 
+static void forward_kcb_request(struct monitor_blocking_binding *b,
+                                coreid_t destination, struct capref kcb)
+{
+    printf("%s:%s:%d: forward_kcb_request in monitor\n",
+           __FILE__, __FUNCTION__, __LINE__);
+
+    errval_t err = SYS_ERR_OK;
+
+    struct capability kcb_cap;
+    err = monitor_cap_identify(kcb, &kcb_cap);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "monitor_cap_identify failed");
+        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+        assert(err_is_ok(err));
+        return;
+    }
+
+    if (destination == my_core_id) {
+        printf("%s:%s:%d: Invoke syscall directly, destination==my_core_id\n",
+               __FILE__, __FUNCTION__, __LINE__);
+        err = invoke_monitor_add_kcb((uintptr_t)kcb_cap.u.kernelcontrolblock.kcb);
+        if (err_is_fail(err)) {
+            USER_PANIC_ERR(err, "invoke_montitor_add_kcb failed.");
+        }
+
+        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+        assert(err_is_ok(err));
+        return;
+    }
+
+    struct intermon_binding *ib;
+    err = intermon_binding_get(destination, &ib);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "intermon_binding_get failed");
+        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+        assert(err_is_ok(err));
+        return;
+    }
+
+    intermon_caprep_t kcb_rep;
+    capability_to_caprep(&kcb_cap, &kcb_rep);
+
+    err = ib->tx_vtbl.give_kcb_request(ib, NOP_CONT, kcb_rep);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "give_kcb send failed");
+        err = b->tx_vtbl.forward_kcb_request_response(b, NOP_CONT, err);
+        assert(err_is_ok(err));
+        return;
+    }
+}
+
 /*------------------------- Initialization functions -------------------------*/
 
 static struct monitor_blocking_rx_vtbl rx_vtbl = {
@@ -710,6 +761,8 @@ static struct monitor_blocking_rx_vtbl rx_vtbl = {
 
     .cap_set_remote_call     = cap_set_remote,
     .get_kernel_cap_call = get_kernel_cap,
+
+    .forward_kcb_request_call = forward_kcb_request,
 };
 
 static void export_callback(void *st, errval_t err, iref_t iref)