ev_q option VCORE_MUST_RUN (XCC)
authorBarret Rhoden <brho@cs.berkeley.edu>
Sat, 17 Sep 2011 00:59:44 +0000 (17:59 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:07 +0000 (17:36 -0700)
Some event queues need to have their alerts sent to a vcore that will
definitely run (as of the time alert_vcore() was called), and not just a
can_rcv_msg.  The one (and probably only) example of this is the
preempt_msg ev_q.  Simply put, you can't send the preempt message about
a given vcore to that vcore, which could happen without this option.

Note that the vcore that receives this message can be yielding or
getting preempted or whatever - so long as it wasn't the vcore that
was preempted (and thus generated the preempt message) (unless it will
be forced to run in the ultimate_fallback area).

Even if you want to just poll your preeempt ev_q (and not want an
INDIR), you still need the MUST_RUN flag to make sure the IPI gets
there.  If you don't want an IPI either, you'll have issues with locking
in uthread context and with preemption response latency.

kern/include/ros/event.h
kern/src/event.c

index d4e89fa..7736a85 100644 (file)
@@ -20,6 +20,7 @@
 #define EVENT_ROUNDROBIN               0x010   /* pick a vcore, RR style */
 #define EVENT_VCORE_APPRO              0x020   /* send to where the kernel wants */
 #define EVENT_NOTHROTTLE               0x040   /* send all alerts (no throttling) */
+#define EVENT_VCORE_MUST_RUN   0x080   /* Alerts go to a vcore that will run */
 /* Flags from the program to the 2LS */
 #define EVENT_JUSTHANDLEIT             0x100   /* 2LS should handle the ev_q */
 #define EVENT_THREAD                   0x200   /* spawn thread to handle ev_q */
index 692b174..b71a92a 100644 (file)
@@ -214,9 +214,10 @@ static void alert_vcore(struct proc *p, struct event_queue *ev_q,
                return;
        }
        /* If we're here, we care about FALLBACK. First, try posting to the desired
-        * vcore. */
-       /* TODO: need a ONLINE_ONLY flag or something, for preempt messages */
-       if (try_alert_vcore(p, ev_q, vcoreid))
+        * vcore (so long as we don't have to send it to a vcore that will run, like
+        * we do for preempt messages). */
+       if (!(ev_q->ev_flags & EVENT_VCORE_MUST_RUN) &&
+          (try_alert_vcore(p, ev_q, vcoreid)))
                return;
        /* If the process is WAITING, let's just jump to the fallback */
        if (p->state == PROC_WAITING)