BNX2X: spatch signed typedefs
[akaros.git] / kern / src / event.c
index f835423..04f16ba 100644 (file)
@@ -71,7 +71,7 @@ static void set_vcore_msgable(uint32_t vcoreid)
 static void post_ev_msg(struct proc *p, struct event_mbox *mbox,
                         struct event_msg *msg, int ev_flags)
 {
-       printd("[kernel] Sending event type %d to mbox %08p\n", msg->ev_type, mbox);
+       printd("[kernel] Sending event type %d to mbox %p\n", msg->ev_type, mbox);
        /* Sanity check */
        assert(p);
        /* If they just want a bit (NOMSG), just set the bit */
@@ -156,14 +156,10 @@ static bool spam_list_member(struct vcore_tailq *list, struct proc *p,
                 * something more customized for the lists. */
                spam_vcore(p, vcoreid, ev_msg, ev_flags);
                wrmb(); /* prev write (notif_pending) must come before following reads*/
-               /* if they are still alertable after we sent the msg, then they'll get
-                * it before yielding (racing with userspace yield here).  This check is
-                * not as critical as the next one, but will allow us to alert vcores
-                * that happen to concurrently be moved from the active to the
-                * bulk_preempt list. */
-               if (can_msg_vcore(vcoreid))
-                       return TRUE;
-               /* As a backup, if they are still the first on the list, then they are
+               /* I used to check can_msg_vcore(vcoreid) here, but that would make
+                * spamming list members unusable for MUST_RUN scenarios.
+                *
+                * Regardless, if they are still the first on the list, then they are
                 * still going to get the message.  For the online list, proc_yield()
                 * will return them to userspace (where they will get the message)
                 * because __alert_vcore() set notif_pending.  For the BP list, they
@@ -213,10 +209,21 @@ static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
                                                        uint32_t vcoreid, int ev_flags)
 {
        struct vcore *vc;
-       /* First, try posting to the desired 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_flags & EVENT_VCORE_MUST_RUN) &&
-          (try_spam_vcore(p, vcoreid, ev_msg, ev_flags)))
+       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. */
+               if (vcore_is_mapped(p, vcoreid)) {      /* check, signal, check again */
+                       spam_vcore(p, vcoreid, ev_msg, ev_flags);
+                       wrmb(); /* notif_pending write must come before following read */
+                       if (vcore_is_mapped(p, vcoreid))
+                               return;
+               }
+               if (spam_list_member(&p->online_vcs, p, ev_msg, ev_flags))
+                       return;
+               goto ultimate_fallback;
+       }
+       /* First, try posting to the desired vcore */
+       if (try_spam_vcore(p, vcoreid, ev_msg, ev_flags))
                return;
        /* If the process is WAITING, let's just jump to the fallback */
        if (p->state == PROC_WAITING)
@@ -251,7 +258,7 @@ ultimate_fallback:
         * empty and the process is simply WAITING (yielded all of its vcores and is
         * waiting on an event).  Time for the ultimate fallback: locking.  Note
         * that when we __alert_vcore(), there is a chance we need to mmap, which
-        * grabs the mm_lock. */
+        * grabs the vmr_lock and pte_lock. */
        spin_lock(&p->proc_lock);
        if (p->state != PROC_WAITING) {
                /* We need to check the online and bulk_preempt lists again, now that we are
@@ -342,8 +349,11 @@ void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
 {
        struct proc *old_proc;
        struct event_mbox *ev_mbox = 0;
+       assert(!in_irq_ctx(&per_cpu_info[core_id()]));
        assert(p);
-       printd("[kernel] sending msg to proc %08p, ev_q %08p\n", p, ev_q);
+       if (p->state == PROC_DYING)
+               return;
+       printd("[kernel] sending msg to proc %p, ev_q %p\n", p, ev_q);
        if (!ev_q) {
                warn("[kernel] Null ev_q - kernel code should check before sending!");
                return;
@@ -357,7 +367,7 @@ void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
         * kernel PFs on the user's behalf.  For now, we catch common userspace bugs
         * (had this happen a few times). */
        if (!PTE_ADDR(ev_q)) {
-               printk("[kernel] Bad addr %08p for ev_q\n", ev_q);
+               printk("[kernel] Bad addr %p for ev_q\n", ev_q);
                return;
        }
        /* ev_q is a user pointer, so we need to make sure we're in the right