Fix spantest and ump_bench by making sure all_spawnd_up is set correctly again.
authorGerd Zellweger <mail@gerdzellweger.com>
Fri, 21 Nov 2014 10:48:45 +0000 (11:48 +0100)
committerGerd Zellweger <mail@gerdzellweger.com>
Fri, 21 Nov 2014 10:48:45 +0000 (11:48 +0100)
errors/errno.fugu
include/octopus/getset.h
lib/octopus/client/getset.c
usr/kaluga/main.c
usr/kaluga/start_cpu.c
usr/kaluga/start_cpu.h
usr/kaluga/start_pci.c

index 5bdb1e7..e23488e 100755 (executable)
@@ -916,8 +916,12 @@ errors kaluga  KALUGA_ERR_ {
     failure MODULE_NOT_FOUND       "Boot module not found.",
     failure DRIVER_ALREADY_STARTED "Driver for this type of device is already running.",
     failure DRIVER_NOT_AUTO        "Driver not declared as auto in menu.lst.",
+    failure WAITING_FOR_ACPI       "Unable to wait for ACPI",
+    failure QUERY_LOCAL_APIC       "Unable to query local APIC.",
+
 };
 
+
 // errors generated by THC
 errors thc THC_ {
     failure CANCELED            "Operation canceled",
index a987d7e..808067f 100644 (file)
@@ -40,6 +40,7 @@ errval_t oct_mset(oct_mode_t, const char*, ...);
 errval_t oct_set_get(oct_mode_t, char**, const char*, ...);
 errval_t oct_del(const char*, ...);
 errval_t oct_exists(const char*, ...);
+errval_t oct_wait_for(char**, const char*, ...);
 
 errval_t oct_read(const char*, const char*, ...);
 
index e402909..89ea473 100644 (file)
@@ -476,3 +476,37 @@ errval_t oct_exists(const char* query, ...)
     free(buf);
     return err;
 }
+
+/**
+ * \brief Waits until a given record exists.
+ *
+ * \param record  Record that matched the query, callee has to free this.
+ * \param query Format of record to wait for.
+ * \param ... Additional arguments to format query.
+ *
+ * \note This call blocks on the octopus RPC waitset if the record is not there yet.
+ *
+ * \retval SYS_ERR_OK
+ */
+errval_t oct_wait_for(char** record, const char *query, ...)
+{
+    assert(query != NULL);
+    errval_t err = SYS_ERR_OK;
+    va_list args;
+
+    char* buf = NULL;
+    FORMAT_QUERY(query, args, buf);
+
+    struct octopus_thc_client_binding_t* cl = oct_get_thc_client();
+
+    errval_t error_code;
+    err = cl->call_seq.wait_for(cl, buf, record, &error_code);
+    if (err_is_fail(err)) {
+        goto out;
+    }
+    err = error_code;
+
+out:
+    free(buf);
+    return err;
+}
index 5f0c812..7c93984 100644 (file)
@@ -128,12 +128,11 @@ int main(int argc, char** argv)
         USER_PANIC_ERR(err, "Watching PCI devices.");
     }
 
-    // XXX: This is a bit silly, I add this record
-    // because it was previously in spawnd so
-    // there may be code out there who relies on this
-    // It might be better to get rid of this completely
-    err = oct_set("all_spawnds_up { iref: 0 }");
-    assert(err_is_ok(err));
+    err = wait_for_all_spawnds();
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "Unable to wait for spawnds failed.");
+    }
+
 #elif __pandaboard__
     printf("Kaluga running on Pandaboard.\n");
 
index 3faf451..932037e 100644 (file)
@@ -29,8 +29,6 @@
 
 #include "kaluga.h"
 
-//static coreid_t core_counter = 1;
-
 static void cpu_change_event(octopus_mode_t mode, char* record, void* state)
 {
     if (mode & OCT_ON_SET) {
@@ -74,14 +72,14 @@ out:
     free(record);
 }
 
+static char* local_apics = "r'hw\\.processor\\.[0-9]+' { processor_id: _, "
+                           "                             enabled: 1, "
+                           "                             apic_id: _, "
+                           "                             barrelfish_id: _ }";
 
 errval_t watch_for_cores(void)
 {
-    static char* local_apics = "r'hw\\.processor\\.[0-9]+' { processor_id: _, "
-                               "                             enabled: 1, "
-                               "                             apic_id: _, "
-                               "                             barrelfish_id: _ }";
-   octopus_trigger_id_t tid;
+    octopus_trigger_id_t tid;
    return oct_trigger_existing_and_watch(local_apics, cpu_change_event, NULL, &tid);
 }
 
@@ -167,3 +165,56 @@ errval_t start_boot_driver(coreid_t where, struct module_info* mi,
 
     return err;
 }
+
+
+static void spawnd_change_event(octopus_mode_t mode, char* record, void* state)
+{
+    size_t count = (size_t) state;
+    static coreid_t spawnd_counter = 0;
+
+    if (mode & OCT_ON_SET) {
+        KALUGA_DEBUG("spawnd found: %s\n", record);
+        spawnd_counter++;
+
+        if (spawnd_counter == count) {
+            KALUGA_DEBUG("Found enough spawnds, setting all_spawnds_up\n");
+            errval_t err = oct_set("all_spawnds_up { iref: 0 }");
+            assert(err_is_ok(err));
+        }
+    }   
+}
+
+errval_t wait_for_all_spawnds(void)
+{
+    // Note: The whole wait for all_spawnds_up thing is a hack.
+    // Our overall design goal is a system where cores
+    // come and go dynamically and we do not want / need
+    // to wait for a stable state.
+    // However, some of our code (for example domain spanning)
+    // still assumes a fixed set of cores and will deadlock
+    // otherwise. Therefore we need to fix those parts first.
+
+
+    KALUGA_DEBUG("Waiting for acpi");
+    char* record = NULL;
+    errval_t err = oct_wait_for(&record, "acpi { iref: _ }");
+    free(record);
+    if (err_is_fail(err)) {
+        return err_push(err, KALUGA_ERR_WAITING_FOR_ACPI);
+    }
+    
+    // No we should be able to get core count
+    // of all cores to estimate the amount of 
+    // spawnd's we have to expect (one per core)
+    char** names;
+    size_t count;
+    err = oct_get_names(&names, &count, local_apics);
+    if (err_is_fail(err)) {
+        return err_push(err, KALUGA_ERR_QUERY_LOCAL_APIC);
+    }
+    oct_free_names(names, count);
+
+    static char* spawnds = "r'spawn.[0-9]+' { iref: _ }";
+    octopus_trigger_id_t tid;
+    return oct_trigger_existing_and_watch(spawnds, spawnd_change_event, (void*)count, &tid);
+}
\ No newline at end of file
index 6117cd5..25f0a7e 100644 (file)
@@ -4,6 +4,7 @@
 #include <errors/errno.h>
 
 errval_t watch_for_cores(void);
+errval_t wait_for_all_spawnds(void);
 errval_t start_boot_driver(coreid_t where,
                            struct module_info* mi,
                            char* record);
index dd94d76..1937505 100644 (file)
@@ -53,7 +53,7 @@ static errval_t wait_for_spawnd(coreid_t core, void* state)
             octopus_BINDING_EVENT, OCT_ON_SET, spawnd_up_event, state);
 
     // Construct service name
-    static char* format = "spawn.%hhu { iref: _ }";
+    static char* format = "spawn.%"PRIuCOREID" { iref: _ }";
     int length = snprintf(NULL, 0, format, core);
     char* query = malloc(length+1);
     snprintf(query, length+1, format, core);