Split PROC_DYING into DYING and DYING_ABORT
[akaros.git] / kern / src / event.c
1 /* Copyright (c) 2011 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Kernel utility functions for sending events and notifications (IPIs) to
6  * processes. */
7
8 #include <ucq.h>
9 #include <ceq.h>
10 #include <bitmask.h>
11 #include <event.h>
12 #include <atomic.h>
13 #include <process.h>
14 #include <smp.h>
15 #include <umem.h>
16 #include <stdio.h>
17 #include <assert.h>
18 #include <pmap.h>
19 #include <schedule.h>
20
21 /* Userspace could give us a vcoreid that causes us to compute a vcpd that is
22  * outside procdata.  If we hit UWLIM, then we've gone farther than we should.
23  * We check the vcoreid, instead of the resulting address, to avoid issues like
24  * address wrap-around. */
25 static bool vcoreid_is_safe(uint32_t vcoreid)
26 {
27         /* MAX_NUM_VCORES == MAX_NUM_CORES (check procinfo/procdata) */
28         return vcoreid < MAX_NUM_CORES;
29 }
30
31 /* Note these three helpers return the user address of the mbox, not the KVA.
32  * Load current to access this, and it will work for any process. */
33 static struct event_mbox *get_vcpd_mbox_priv(uint32_t vcoreid)
34 {
35         return &__procdata.vcore_preempt_data[vcoreid].ev_mbox_private;
36 }
37
38 static struct event_mbox *get_vcpd_mbox_pub(uint32_t vcoreid)
39 {
40         return &__procdata.vcore_preempt_data[vcoreid].ev_mbox_public;
41 }
42
43 static struct event_mbox *get_vcpd_mbox(uint32_t vcoreid, int ev_flags)
44 {
45         if (ev_flags & EVENT_VCORE_PRIVATE)
46                 return get_vcpd_mbox_priv(vcoreid);
47         else
48                 return get_vcpd_mbox_pub(vcoreid);
49 }
50
51 /* Can we message the vcore?  (Will it check its messages).  Note this checks
52  * procdata via the user pointer. */
53 static bool can_msg_vcore(uint32_t vcoreid)
54 {
55         struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
56         return atomic_read(&vcpd->flags) & VC_CAN_RCV_MSG;
57 }
58
59 /* Says a vcore can be messaged.  Only call this once you are sure this is true
60  * (holding the proc_lock, etc). */
61 static void set_vcore_msgable(uint32_t vcoreid)
62 {
63         struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
64         atomic_or(&vcpd->flags, VC_CAN_RCV_MSG);
65 }
66
67 static void send_evbitmap_msg(struct evbitmap *evbm, struct event_msg *msg)
68 {
69         SET_BITMASK_BIT_ATOMIC(evbm->bitmap, msg->ev_type);
70         wmb();
71         evbm->check_bits = TRUE;
72 }
73
74 /* Posts a message to the mbox.  mbox is a pointer to user-accessible memory.
75  * If mbox is a user-provided pointer, make sure that you've checked it.
76  * Regardless make sure you have that process's address space loaded. */
77 static void post_ev_msg(struct proc *p, struct event_mbox *mbox,
78                         struct event_msg *msg, int ev_flags)
79 {
80         printd("[kernel] Sending event type %d to mbox %p\n", msg->ev_type, mbox);
81         /* Sanity check */
82         assert(p);
83         switch (mbox->type) {
84                 case (EV_MBOX_UCQ):
85                         send_ucq_msg(&mbox->ucq, p, msg);
86                         break;
87                 case (EV_MBOX_BITMAP):
88                         send_evbitmap_msg(&mbox->evbm, msg);
89                         break;
90                 case (EV_MBOX_CEQ):
91                         send_ceq_msg(&mbox->ceq, p, msg);
92                         break;
93                 default:
94                         printk("[kernel] Unknown mbox type %d!\n", mbox->type);
95         }
96 }
97
98 /* Helper: use this when sending a message to a VCPD mbox.  It just posts to the
99  * ev_mbox and sets notif pending.  Note this uses a userspace address for the
100  * VCPD (though not a user's pointer). */
101 static void post_vc_msg(struct proc *p, uint32_t vcoreid,
102                         struct event_mbox *ev_mbox, struct event_msg *ev_msg,
103                         int ev_flags)
104 {
105         struct preempt_data *vcpd = &__procdata.vcore_preempt_data[vcoreid];
106         post_ev_msg(p, ev_mbox, ev_msg, ev_flags);
107         /* Set notif pending so userspace doesn't miss the message while yielding */
108         wmb(); /* Ensure ev_msg write is before notif_pending */
109         /* proc_notify() also sets this, but the ev_q might not have requested an
110          * IPI, so we have to do it here too. */
111         vcpd->notif_pending = TRUE;
112 }
113
114 /* Helper: will IPI / proc_notify if the flags say so.  We also check to make
115  * sure it is mapped (slight optimization) */
116 static void try_notify(struct proc *p, uint32_t vcoreid, int ev_flags)
117 {
118         /* Note this is an unlocked-peek at the vcoremap */
119         if ((ev_flags & EVENT_IPI) && vcore_is_mapped(p, vcoreid))
120                 proc_notify(p, vcoreid);
121 }
122
123 /* Helper: sends the message and an optional IPI to the vcore.  Sends to the
124  * public mbox. */
125 static void spam_vcore(struct proc *p, uint32_t vcoreid,
126                        struct event_msg *ev_msg, int ev_flags)
127 {
128         post_vc_msg(p, vcoreid, get_vcpd_mbox_pub(vcoreid), ev_msg, ev_flags);
129         try_notify(p, vcoreid, ev_flags);
130 }
131
132 /* Attempts to message a vcore that may or may not have VC_CAN_RCV_MSG set.  If
133  * so, we'll post the message and the message will eventually get dealt with
134  * (when the vcore runs or when it is preempte-recovered). */
135 static bool try_spam_vcore(struct proc *p, uint32_t vcoreid,
136                            struct event_msg *ev_msg, int ev_flags)
137 {
138         /* Not sure if we can or not, so check before spamming.  Technically, the
139          * only critical part is that we __alert, then check can_alert. */
140         if (can_msg_vcore(vcoreid)) {
141                 spam_vcore(p, vcoreid, ev_msg, ev_flags);
142                 wrmb(); /* prev write (notif_pending) must come before following reads*/
143                 if (can_msg_vcore(vcoreid))
144                         return TRUE;
145         }
146         return FALSE;
147 }
148
149 /* Helper: will try to message (INDIR/IPI) a list member (lists of vcores).  We
150  * use this on the online and bulk_preempted vcore lists.  If this succeeds in
151  * alerting a vcore on the list, it'll return TRUE.  We need to be careful here,
152  * since we're reading a list that could be concurrently modified.  The
153  * important thing is that we can always fail if we're unsure (such as with
154  * lists being temporarily empty).  The caller will be able to deal with it via
155  * the ultimate fallback. */
156 static bool spam_list_member(struct vcore_tailq *list, struct proc *p,
157                              struct event_msg *ev_msg, int ev_flags)
158 {
159         struct vcore *vc, *vc_first;
160         uint32_t vcoreid;
161         int loops = 0;
162         vc = TAILQ_FIRST(list);
163         /* If the list appears empty, we'll bail out (failing) after the loop. */
164         while (vc) {
165                 vcoreid = vcore2vcoreid(p, vc);
166                 /* post the alert.  Not using the try_spam_vcore() helper since I want
167                  * something more customized for the lists. */
168                 spam_vcore(p, vcoreid, ev_msg, ev_flags);
169                 wrmb(); /* prev write (notif_pending) must come before following reads*/
170                 /* I used to check can_msg_vcore(vcoreid) here, but that would make
171                  * spamming list members unusable for MUST_RUN scenarios.
172                  *
173                  * Regardless, if they are still the first on the list, then they are
174                  * still going to get the message.  For the online list, proc_yield()
175                  * will return them to userspace (where they will get the message)
176                  * because __alert_vcore() set notif_pending.  For the BP list, they
177                  * will either be turned on later, or have a preempt message sent about
178                  * their demise.
179                  *
180                  * We race on list membership (and not exclusively VC_CAN_RCV_MSG, so
181                  * that when it fails we can get a new vcore to try (or know WHP there
182                  * are none). */
183                 vc_first = TAILQ_FIRST(list);
184                 if (vc == vc_first)
185                         return TRUE;
186                 /* At this point, the list has changed and the vcore we tried yielded,
187                  * so we try the *new* list head.  Track loops for sanity reasons. */
188                 if (loops++ > 10) {
189                         warn("Too many (%d) attempts to find a vcore, failing!", loops);
190                         return FALSE;   /* always safe to fail! */
191                 }
192                 /* Get set up for your attack run! */
193                 vc = vc_first;
194         }
195         return FALSE;
196 }
197
198 /* This makes sure ev_msg is sent to some vcore, preferring vcoreid.
199  *
200  * One of the goals of SPAM_INDIR (and this func) is to allow processes to yield
201  * cores without fear of losing messages.  Even when yielding and getting
202  * preempted, if your message is spammed, it will get to some vcore.  If
203  * MUST_RUN is set, it'll get to a running vcore.  Messages that you send like
204  * this must be able to handle spurious reads, since more than one vcore is
205  * likely to get the message and handle it.
206  *
207  * We try the desired vcore, using VC_CAN_RCV_MSG.  Failing that, we'll search
208  * the online and then the bulk_preempted lists.  These lists serve as a way to
209  * find likely messageable vcores.  spam_list_member() helps us with them,
210  * failing if anything seems to go wrong.  At which point we just lock and try
211  * to deal with things.  In that scenario, we most likely would need to lock
212  * anyway to wake up the process (was WAITING).
213  *
214  * One tricky thing with sending to the bulk_preempt list is that we may want to
215  * send a message about a (bulk) preemption to someone on that list.  This works
216  * since a given vcore that was preempted will be removed from that list before
217  * we try to send_event() (in theory, there isn't code that can send that event
218  * yet).  Someone else will get the event and wake up the preempted vcore. */
219 static void spam_public_msg(struct proc *p, struct event_msg *ev_msg,
220                                                         uint32_t vcoreid, int ev_flags)
221 {
222         struct vcore *vc;
223         if (!__proc_is_mcp(p)) {
224                 spam_vcore(p, 0, ev_msg, ev_flags);
225                 return;
226         }
227         if (ev_flags & EVENT_VCORE_MUST_RUN) {
228                 /* Could check for waiting and skip these spams, which will fail.  Could
229                  * also skip trying for vcoreid, and just spam any old online VC. */
230                 if (vcore_is_mapped(p, vcoreid)) {      /* check, signal, check again */
231                         spam_vcore(p, vcoreid, ev_msg, ev_flags);
232                         wrmb(); /* notif_pending write must come before following read */
233                         if (vcore_is_mapped(p, vcoreid))
234                                 return;
235                 }
236                 if (spam_list_member(&p->online_vcs, p, ev_msg, ev_flags))
237                         return;
238                 goto ultimate_fallback;
239         }
240         /* First, try posting to the desired vcore */
241         if (try_spam_vcore(p, vcoreid, ev_msg, ev_flags))
242                 return;
243         /* If the process is WAITING, let's just jump to the fallback */
244         if (p->state == PROC_WAITING)
245                 goto ultimate_fallback;
246         /* If we're here, the desired vcore is unreachable, but the process is
247          * probably RUNNING_M (online_vs) or RUNNABLE_M (bulk preempted or recently
248          * woken up), so we'll need to find another vcore. */
249         if (spam_list_member(&p->online_vcs, p, ev_msg, ev_flags))
250                 return;
251         if (spam_list_member(&p->bulk_preempted_vcs, p, ev_msg, ev_flags))
252                 return;
253         /* Last chance, let's check the head of the inactives.  It might be
254          * alertable (the kernel set it earlier due to an event, or it was a
255          * bulk_preempt that didn't restart), and we can avoid grabbing the
256          * proc_lock. */
257         vc = TAILQ_FIRST(&p->inactive_vcs);
258         if (vc) {       /* might be none in rare circumstances */
259                 if (try_spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags)) {
260                         /* It's possible that we're WAITING here.  EVENT_WAKEUP will handle
261                          * it.  One way for this to happen is if a normal vcore was
262                          * preempted right as another vcore was yielding, and the preempted
263                          * message was sent after the last vcore yielded (which caused us to
264                          * be WAITING). */
265                         return;
266                 }
267         }
268 ultimate_fallback:
269         /* At this point, we can't find one.  This could be due to a (hopefully
270          * rare) weird yield/request storm, or more commonly because the lists were
271          * empty and the process is simply WAITING (yielded all of its vcores and is
272          * waiting on an event).  Time for the ultimate fallback: locking.  Note
273          * that when we __alert_vcore(), there is a chance we need to mmap, which
274          * grabs the vmr_lock and pte_lock. */
275         spin_lock(&p->proc_lock);
276         if (p->state != PROC_WAITING) {
277                 /* We need to check the online and bulk_preempt lists again, now that we
278                  * are sure no one is messing with them.  If we're WAITING, we can skip
279                  * these (or assert they are empty!). */
280                 vc = TAILQ_FIRST(&p->online_vcs);
281                 if (vc) {
282                         /* there's an online vcore, so just alert it (we know it isn't going
283                          * anywhere), and return */
284                         spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
285                         spin_unlock(&p->proc_lock);
286                         return;
287                 }
288                 vc = TAILQ_FIRST(&p->bulk_preempted_vcs);
289                 if (vc) {
290                         /* the process is bulk preempted, similar deal to above */
291                         spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
292                         spin_unlock(&p->proc_lock);
293                         return;
294                 }
295         }
296         /* At this point, we're sure all vcores are yielded, though we might not be
297          * WAITING.  Post to the first on the inactive list (which is the one that
298          * will definitely be woken up) */
299         vc = TAILQ_FIRST(&p->inactive_vcs);
300         assert(vc);
301         spam_vcore(p, vcore2vcoreid(p, vc), ev_msg, ev_flags);
302         /* Set the vcore's alertable flag, to short circuit our last ditch effort
303          * above */
304         set_vcore_msgable(vcore2vcoreid(p, vc));
305         /* The first event to catch the process with no online/bp vcores will need
306          * to wake it up, which is handled elsewhere if they requested EVENT_WAKEUP.
307          * We could be RUNNABLE_M here if another event already woke us and we
308          * didn't get lucky with the penultimate fallback. */
309         spin_unlock(&p->proc_lock);
310 }
311
312 /* Helper: sends an indirection event for an ev_q, preferring vcoreid */
313 static void send_indir(struct proc *p, struct event_queue *ev_q,
314                        uint32_t vcoreid)
315 {
316         struct event_msg local_msg = {0};
317         /* If an alert is already pending and they don't want repeats, just return.
318          * One of the few uses of NOTHROTTLE will be for preempt_msg ev_qs.  Ex: an
319          * INDIR was already sent to the preempted vcore, then alert throttling
320          * would stop another vcore from getting the message about the original
321          * vcore. */
322         if (!(ev_q->ev_flags & EVENT_NOTHROTTLE) && (ev_q->ev_alert_pending))
323                 return;
324         /* We'll eventually get an INDIR through, so don't send any more til
325          * userspace toggles this.  Regardless of other writers to this flag, we
326          * eventually send an alert that causes userspace to turn throttling off
327          * again (before handling all of the ev_q's events).
328          *
329          * This will also squelch IPIs, since there's no reason to send the IPI if
330          * the INDIR is still un-acknowledged.  The vcore is either in vcore
331          * context, attempting to deal with the INDIR, or offline.  This statement
332          * is probably true. */
333         ev_q->ev_alert_pending = TRUE;
334         wmb();  /* force this write to happen before any event writes */
335         local_msg.ev_type = EV_EVENT;
336         local_msg.ev_arg3 = ev_q;
337         /* If we're not spamming indirs, just send and be done with it.
338          *
339          * It's possible that the user does not want to poll their evq and wants an
340          * INDIR, but also doesn't care about sleeping or otherwise not getting the
341          * message right away.  The INDIR could sit in the VCPD of a vcore that
342          * doesn't run for a while.  Perhaps if the app always made sure VC 0 was
343          * on when it was running at all, and sent the INDIR there.  Or there was a
344          * per-vc evq that only needed to be handled when the VC turned on.  This
345          * gets at another aspect of INDIRs, other than it's need for "only once"
346          * operation: maybe the mbox type isn't a UCQ (like the VCPD mboxes). */
347         if (!(ev_q->ev_flags & EVENT_SPAM_INDIR)) {
348                 spam_vcore(p, vcoreid, &local_msg, ev_q->ev_flags);
349                 return;
350         }
351         /* At this point, we actually want to send and spam an INDIR.
352          * This will guarantee the message makes it to some vcore. */
353         spam_public_msg(p, &local_msg, vcoreid, ev_q->ev_flags);
354 }
355
356 /* Send an event to ev_q, based on the parameters in ev_q's flag.  We don't
357  * accept null ev_qs, since the caller ought to be checking before bothering to
358  * make a msg and send it to the event_q.  Vcoreid is who the kernel thinks the
359  * message ought to go to (for IPIs).  Appropriate for things like
360  * EV_PREEMPT_PENDING, where we tell the affected vcore.  To have the message go
361  * where the kernel suggests, set EVENT_VCORE_APPRO(priate). */
362 void send_event(struct proc *p, struct event_queue *ev_q, struct event_msg *msg,
363                 uint32_t vcoreid)
364 {
365         uintptr_t old_proc;
366         struct event_mbox *ev_mbox = 0;
367
368         assert(!in_irq_ctx(&per_cpu_info[core_id()]));
369         assert(p);
370         if (proc_is_dying(p))
371                 return;
372         printd("[kernel] sending msg to proc %p, ev_q %p\n", p, ev_q);
373         if (!ev_q) {
374                 warn("[kernel] Null ev_q - kernel code should check before sending!");
375                 return;
376         }
377         if (!is_user_rwaddr(ev_q, sizeof(struct event_queue))) {
378                 /* Ought to kill them, just warn for now */
379                 printk("[kernel] Illegal addr for ev_q\n");
380                 return;
381         }
382         /* This should be caught by "future technology" that can tell when the
383          * kernel PFs on the user's behalf.  For now, we catch common userspace bugs
384          * (had this happen a few times). */
385         if (!PTE_ADDR(ev_q)) {
386                 printk("[kernel] Bad addr %p for ev_q\n", ev_q);
387                 return;
388         }
389         /* ev_q is a user pointer, so we need to make sure we're in the right
390          * address space */
391         old_proc = switch_to(p);
392         /* Get the vcoreid that we'll message (if appropriate).  For INDIR and
393          * SPAMMING, this is the first choice of a vcore, but other vcores might get
394          * it.  Common case is !APPRO and !ROUNDROBIN.  Note we are clobbering the
395          * vcoreid parameter. */
396         if (!(ev_q->ev_flags & EVENT_VCORE_APPRO))
397                 vcoreid = ev_q->ev_vcore;       /* use the ev_q's vcoreid */
398         /* Note that RR overwrites APPRO */
399         if (ev_q->ev_flags & EVENT_ROUNDROBIN) {
400                 /* Pick a vcore, round-robin style.  Assuming ev_vcore was the previous
401                  * one used.  Note that round-robin overrides the passed-in vcoreid.
402                  * Also note this may be 'wrong' if num_vcores changes. */
403                 vcoreid = (ev_q->ev_vcore + 1) % p->procinfo->num_vcores;
404                 ev_q->ev_vcore = vcoreid;
405         }
406         if (!vcoreid_is_safe(vcoreid)) {
407                 /* Ought to kill them, just warn for now */
408                 printk("[kernel] Vcoreid %d unsafe! (too big?)\n", vcoreid);
409                 goto out;
410         }
411         /* If we're a SPAM_PUBLIC, they just want us to spam the message.  Note we
412          * don't care about the mbox, since it'll go to VCPD public mboxes, and
413          * we'll prefer to send it to whatever vcoreid we determined at this point
414          * (via APPRO or whatever). */
415         if (ev_q->ev_flags & EVENT_SPAM_PUBLIC) {
416                 spam_public_msg(p, msg, vcoreid, ev_q->ev_flags);
417                 goto wakeup;
418         }
419         /* We aren't spamming and we know the default vcore, and now we need to
420          * figure out which mbox to use.  If they provided an mbox, we'll use it.
421          * If not, we'll use a VCPD mbox (public or private, depending on the
422          * flags). */
423         ev_mbox = ev_q->ev_mbox;
424         if (!ev_mbox)
425                 ev_mbox = get_vcpd_mbox(vcoreid, ev_q->ev_flags);
426         /* At this point, we ought to have the right mbox to send the msg to, and
427          * which vcore to alert (IPI/INDIR) (if applicable).  The mbox could be the
428          * vcore's vcpd ev_mbox. */
429         if (!ev_mbox) {
430                 /* This shouldn't happen any more, this is more for sanity's sake */
431                 warn("[kernel] ought to have an mbox by now!");
432                 goto out;
433         }
434         /* Even if we're using an mbox in procdata (VCPD), we want a user pointer */
435         if (!is_user_rwaddr(ev_mbox, sizeof(struct event_mbox))) {
436                 /* Ought to kill them, just warn for now */
437                 printk("[kernel] Illegal addr for ev_mbox\n");
438                 goto out;
439         }
440         post_ev_msg(p, ev_mbox, msg, ev_q->ev_flags);
441         wmb();  /* ensure ev_msg write is before alerting the vcore */
442         /* Prod/alert a vcore with an IPI or INDIR, if desired.  INDIR will also
443          * call try_notify (IPI) later */
444         if (ev_q->ev_flags & EVENT_INDIR) {
445                 send_indir(p, ev_q, vcoreid);
446         } else {
447                 /* they may want an IPI despite not wanting an INDIR */
448                 try_notify(p, vcoreid, ev_q->ev_flags);
449         }
450 wakeup:
451         if ((ev_q->ev_flags & EVENT_WAKEUP) && (p->state == PROC_WAITING))
452                 proc_wakeup(p);
453         /* Fall through */
454 out:
455         /* Return to the old address space. */
456         switch_back(p, old_proc);
457 }
458
459 /* Send an event for the kernel event ev_num.  These are the "one sided" kernel
460  * initiated events, that require a lookup of the ev_q in procdata.  This is
461  * roughly equivalent to the old "proc_notify()" */
462 void send_kernel_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid)
463 {
464         uint16_t ev_num = msg->ev_type;
465         assert(ev_num < MAX_NR_EVENT);          /* events start at 0 */
466         struct event_queue *ev_q = p->procdata->kernel_evts[ev_num];
467         /* linux would put a rmb_depends() here too, i think. */
468         if (ev_q)
469                 send_event(p, ev_q, msg, vcoreid);
470 }
471
472 /* Writes the msg to the vcpd mbox of the vcore.  If you want the private mbox,
473  * send in the ev_flag EVENT_VCORE_PRIVATE.  If not, the message could
474  * be received by other vcores if the given vcore is offline/preempted/etc.
475  * Whatever other flags you pass in will get sent to post_ev_msg.  Currently,
476  * the only one that will get looked at is NO_MSG (set a bit).
477  *
478  * This needs to load current (switch_to), but doesn't need to care about what
479  * the process wants.  Note this isn't commonly used - just the monitor and
480  * sys_self_notify(). */
481 void post_vcore_event(struct proc *p, struct event_msg *msg, uint32_t vcoreid,
482                       int ev_flags)
483 {
484         /* Need to set p as current to post the event */
485         struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
486         uintptr_t old_proc = switch_to(p);
487
488         /* *ev_mbox is the user address of the vcpd mbox */
489         post_vc_msg(p, vcoreid, get_vcpd_mbox(vcoreid, ev_flags), msg, ev_flags);
490         switch_back(p, old_proc);
491 }
492
493 /* Attempts to send a posix signal to the process.  If they do not have an ev_q
494  * registered for EV_POSIX_SIGNAL, then nothing will happen. */
495 void send_posix_signal(struct proc *p, int sig_nr)
496 {
497         struct event_msg local_msg = {0};
498         local_msg.ev_type = EV_POSIX_SIGNAL;
499         local_msg.ev_arg1 = sig_nr;
500         send_kernel_event(p, &local_msg, 0);
501 }