Allow all event queue functionality for SCPs (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 4 Aug 2015 18:00:32 +0000 (14:00 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Mon, 28 Sep 2015 19:14:00 +0000 (15:14 -0400)
Previously, SCPs event delivery would be short-circuited.  Regardless of
where you wanted the event to go, we'd just spam it to vcore 0.  This
would bypass whatever ev_q you set up, including its mailbox and custom
handlers.  It worked if all you do is use a UCQ.

With this change, SCPs have full access to the ev_q functionality,
including INDIRs, spam requests, and wakeups.  Since SCPs are no longer
short-circuited, they need to use EVENT_WAKEUP to ensure they wake up
and receive the message, if that is desired.

Spamming works, e.g. for indirs or public messages; the message goes to
the only vcore: VC 0.  It's unnecessary for the common case.  If you use
an INDIR and WAKEUP, you'll wake up and see the INDIR in VC 0 - no need
to spam.  But code that is used for both MCPs and SCPs can safely use
EVENT_SPAM_* without worry.

Rebuild everything. (make xcc-upgrade-from-scratch)

Documentation/async_events.txt
kern/src/event.c
tools/compilers/gcc-glibc/glibc-2.19-akaros/sysdeps/akaros/syscall.c

index 767c6cf..6d7b3ec 100644 (file)
@@ -873,11 +873,6 @@ again.
 
 4.3 Extra Tidbits:
 ---------------------------------------
-One minor point: SCPs can't receive INDIRs, at least for now.  The kernel event
-code short circuits all the fallback business and just spams vcore0's public
-mbox.  If we ever change that, we need to be sure to post a notif_pending to
-vcore0 (that's the signal to trigger a wakeup).
-
 If we receive an event right as we transition from SCP to MCP, vcore0 could get
 spammed with a message that is never received.  Right now, it's not a problem,
 since vcore0 is the first vcore that will get woken up as an MCP.  This could be
index 31c74f9..f98322d 100644 (file)
@@ -209,6 +209,10 @@ static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
                                                        uint32_t vcoreid, int ev_flags)
 {
        struct vcore *vc;
+       if (!__proc_is_mcp(p)) {
+               spam_vcore(p, 0, ev_msg, ev_flags);
+               return;
+       }
        if (ev_flags & EVENT_VCORE_MUST_RUN) {
                /* Could check for waiting and skip these spams, which will fail.  Could
                 * also skip trying for vcoreid, and just spam any old online VC. */
@@ -374,16 +378,6 @@ void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
        /* ev_q is a user pointer, so we need to make sure we're in the right
         * address space */
        old_proc = switch_to(p);
-       /* If we're an _S, just spam vcore0, and wake up if necessary. */
-       if (!__proc_is_mcp(p)) {
-               spam_vcore(p, 0, msg, ev_q->ev_flags);
-               wrmb(); /* don't let the notif_pending write pass the state read */
-               /* using the same pattern as in spam_public (which can have multiple
-                * unblock callbacks */
-               if (p->state == PROC_WAITING)
-                       proc_wakeup(p);
-               goto out;
-       }
        /* Get the vcoreid that we'll message (if appropriate).  For INDIR and
         * SPAMMING, this is the first choice of a vcore, but other vcores might get
         * it.  Common case is !APPRO and !ROUNDROBIN.  Note we are clobbering the
index ab49fc1..a60f2c2 100644 (file)
 /* This is a simple ev_q that routes notifs to vcore0's public mbox.  This
  * should work for any bit messages, even if the process hasn't done any set up
  * yet, since the memory for the mbox is allocted by the kernel (procdata).
- * Don't send full messages to it, since the UCQ won't be initialized.  Note
- * that the kernel will actually ignore your ev_mbox and just about everything
- * other than flags if you're an SCP, but that might change later. */
+ * Don't send full messages to it, since the UCQ won't be initialized. */
 struct event_queue __ros_scp_simple_evq =
                   { .ev_mbox = &__procdata.vcore_preempt_data[0].ev_mbox_public,
-                    .ev_flags = EVENT_IPI | EVENT_NOMSG, 
+                    .ev_flags = EVENT_NOMSG | EVENT_WAKEUP,
                     .ev_alert_pending = FALSE,
                     .ev_vcore = 0,
                     .ev_handler = 0 };