Fixes SCP wakeup latency
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 10 Sep 2014 03:38:17 +0000 (20:38 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 10 Sep 2014 03:38:17 +0000 (20:38 -0700)
When an SCP syscall completes on a CG core, which ultimately wakes up
the process, the SCP was not running until the next ksched timer tick.

This scenario could happen if an SCP blocks on a read on a pipe that
gets written to by an MCP.  The pipe write wakes the reader, and since
the kthread code is primitive, it just finishes the bottom half of the
syscall on the MCPs core (a CG core).  Core 0 could have been halted the
entire time, and had no reason to wake up.  It may have called
cpu_bored() a long time ago and has not woken up yet.

Btw, note that syscalls in the trace are written in the order of
*completion*, not submission.  This is more clear from the TSC
timestamp, but the pretty output only has msec granularity.

kern/arch/riscv/trap.h
kern/src/schedule.c

index 99daf57..8810234 100644 (file)
@@ -18,6 +18,9 @@
 
 /* Kernel message interrupt vector.  ignored, for the most part */
 #define I_KERNEL_MSG 255
+#warning "make sure this poke vector is okay"
+/* this is for an ipi that just wakes a core, but has no handler (for now) */
+#define I_POKE_CORE 254
 
 /* For kernel contexts, when we save/restore/move them around. */
 struct kernel_ctx {
index 01dfbea..e80f321 100644 (file)
@@ -304,6 +304,19 @@ void __sched_scp_wakeup(struct proc *p)
        remove_from_any_list(p);
        add_to_list(p, &runnable_scps);
        spin_unlock(&sched_lock);
+       /* we could be on a CG core, and all the mgmt cores could be halted.  if we
+        * don't tell one of them about the new proc, they will sleep until the
+        * timer tick goes off. */
+       if (!management_core()) {
+               /* TODO: pick a better core and only send if halted.
+                *
+                * ideally, we'd know if a specific mgmt core is sleeping and wake it
+                * up.  o/w, we could interrupt an already-running mgmt core that won't
+                * get to our new proc anytime soon.  also, by poking core 0, a
+                * different mgmt core could remain idle (and this process would sleep)
+                * until its tick goes off */
+               send_ipi(0, I_POKE_CORE);
+       }
 }
 
 /* Callback to return a core to the ksched, which tracks it as idle and