Debug helpers for BNX2X
[akaros.git] / user / parlib / 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  * Userspace utility functions for receiving events and notifications (IPIs).
6  * Some are higher level than others; just use what you need. */ 
7
8 #include <ros/event.h>
9 #include <ros/procdata.h>
10 #include <ucq.h>
11 #include <bitmask.h>
12 #include <vcore.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <assert.h>
16 #include <errno.h>
17 #include <parlib.h>
18 #include <event.h>
19 #include <uthread.h>
20 #include <spinlock.h>
21
22 /* For remote VCPD mbox event handling */
23 __thread bool __vc_handle_an_mbox = FALSE;
24 __thread uint32_t __vc_rem_vcoreid;
25
26 /********* Event_q Setup / Registration  ***********/
27
28 /* Get event_qs via these interfaces, since eventually we'll want to either
29  * allocate from pinned memory or use some form of a slab allocator.  Also,
30  * these stitch up the big_q so its ev_mbox points to its internal mbox.  Never
31  * access the internal mbox directly.
32  *
33  * Raw ones need to have their UCQs initialized.  If you're making a lot of
34  * these, you can do one big mmap and init the ucqs on your own, which ought to
35  * perform better.
36  *
37  * Use the 'regular' one for big_qs if you don't want to worry about the ucq
38  * initalization */
39 struct event_queue *get_big_event_q_raw(void)
40 {
41         /* TODO: (PIN) should be pinned memory */
42         struct event_queue_big *big_q = malloc(sizeof(struct event_queue_big));
43         memset(big_q, 0, sizeof(struct event_queue_big));
44         big_q->ev_mbox = &big_q->ev_imbox;
45         return (struct event_queue*)big_q;
46 }
47
48 struct event_queue *get_big_event_q(void)
49 {
50         struct event_queue *big_q = get_big_event_q_raw();
51         /* uses the simpler, internally mmapping ucq_init() */
52         ucq_init(&big_q->ev_mbox->ev_msgs);
53         return big_q;
54 }
55
56 /* Give it up.  I don't recommend calling these unless you're sure the queues
57  * aren't in use (unregistered, etc). (TODO: consider some checks for this) */
58 void put_big_event_q_raw(struct event_queue *ev_q)
59 {
60         /* if we use something other than malloc, we'll need to be aware that ev_q
61          * is actually an event_queue_big.  One option is to use the flags, though
62          * this could be error prone. */
63         free(ev_q);
64 }
65
66 void put_big_event_q(struct event_queue *ev_q)
67 {
68         ucq_free_pgs(&ev_q->ev_mbox->ev_msgs);
69         put_big_event_q_raw(ev_q);
70 }
71
72 /* Need to point this event_q to an mbox - usually to a vcpd */
73 struct event_queue *get_event_q(void)
74 {
75         /* TODO: (PIN) should be pinned memory */
76         struct event_queue *ev_q = malloc(sizeof(struct event_queue));
77         memset(ev_q, 0, sizeof(struct event_queue));
78         return ev_q;
79 }
80
81 /* Gets a small ev_q, with ev_mbox pointing to the vcpd mbox of vcoreid.  If
82  * ev_flags has EVENT_VCORE_PRIVATE set, it'll give you the private mbox.  o/w,
83  * you'll get the public one. */
84 struct event_queue *get_event_q_vcpd(uint32_t vcoreid, int ev_flags)
85 {
86         struct event_queue *ev_q = get_event_q();
87         if (ev_flags & EVENT_VCORE_PRIVATE)
88                 ev_q->ev_mbox = &vcpd_of(vcoreid)->ev_mbox_private;
89         else
90                 ev_q->ev_mbox = &vcpd_of(vcoreid)->ev_mbox_public;
91         return ev_q;
92 }
93
94 void put_event_q(struct event_queue *ev_q)
95 {
96         /* if we use something other than malloc, we'll need to be aware that ev_q
97          * is not an event_queue_big. */
98         free(ev_q);
99 }
100
101 /* Sets ev_q to be the receiving end for kernel event ev_type */
102 void register_kevent_q(struct event_queue *ev_q, unsigned int ev_type)
103 {
104         __procdata.kernel_evts[ev_type] = ev_q;
105 }
106
107 /* Clears the event, returning an ev_q if there was one there.  You'll need to
108  * free it. */
109 struct event_queue *clear_kevent_q(unsigned int ev_type)
110 {
111         struct event_queue *ev_q = __procdata.kernel_evts[ev_type];
112         __procdata.kernel_evts[ev_type] = 0;
113         return ev_q;
114 }
115
116 /* Enables an IPI/event combo for ev_type sent to vcoreid's default mbox.  IPI
117  * if you want one or not.  If you want the event to go to the vcore private
118  * mbox (meaning no other core should ever handle it), send in
119  * EVENT_VCORE_PRIVATE with ev_flags.
120  *
121  * This is the simplest thing applications may want, and shows how you can put
122  * the other event functions together to get similar things done. */
123 void enable_kevent(unsigned int ev_type, uint32_t vcoreid, int ev_flags)
124 {
125         struct event_queue *ev_q = get_event_q_vcpd(vcoreid, ev_flags);
126         ev_q->ev_flags = ev_flags;
127         ev_q->ev_vcore = vcoreid;
128         ev_q->ev_handler = 0;
129         wmb();  /* make sure ev_q is filled out before registering */
130         register_kevent_q(ev_q, ev_type);
131 }
132
133 /* Stop receiving the events (one could be on the way).  Caller needs to be
134  * careful, since the kernel might be sending an event to the ev_q.  Depending
135  * on the ev_q, it may be hard to know when it is done (for instance, if all
136  * syscalls you ever registered with the ev_q are done, then it would be okay).
137  * o/w, don't free it. */
138 struct event_queue *disable_kevent(unsigned int ev_type)
139 {
140         return clear_kevent_q(ev_type);
141 }
142
143 /********* Event Handling / Reception ***********/
144 /* Somewhat ghetto helper, for the lazy.  If all you care about is an event
145  * number, this will see if the event happened or not.  It will try for a
146  * message, but if there is none, it will go for a bit.  Note that multiple
147  * bit messages will turn into just one bit. */
148 unsigned int get_event_type(struct event_mbox *ev_mbox)
149 {
150         struct event_msg local_msg = {0};
151         /* UCQ returns 0 on success, so this will dequeue and return the type. */
152         if (!get_ucq_msg(&ev_mbox->ev_msgs, &local_msg)) {
153                 return local_msg.ev_type;
154         }
155         if (BITMASK_IS_CLEAR(&ev_mbox->ev_bitmap, MAX_NR_EVENT))
156                 return EV_NONE; /* aka, 0 */
157         for (int i = 0; i < MAX_NR_EVENT; i++) {
158                 if (GET_BITMASK_BIT(ev_mbox->ev_bitmap, i)) {
159                         CLR_BITMASK_BIT_ATOMIC(ev_mbox->ev_bitmap, i);
160                         return i;
161                 }
162         }
163         return EV_NONE;
164 }
165
166 /* Actual Event Handling */
167
168 /* List of handler lists, process-wide.  They all must return (don't context
169  * switch to a u_thread) */
170 struct ev_handler *ev_handlers[MAX_NR_EVENT] = {0};
171 spinpdrlock_t ev_h_wlock = SPINPDR_INITIALIZER;
172
173 int register_ev_handler(unsigned int ev_type, handle_event_t handler,
174                         void *data)
175 {
176         struct ev_handler *new_h = malloc(sizeof(struct ev_handler));
177         if (!new_h)
178                 return -1;
179         new_h->func = handler;
180         new_h->data = data;
181         spin_pdr_lock(&ev_h_wlock);
182         new_h->next = ev_handlers[ev_type];
183         wmb();  /* make sure new_h is done before publishing to readers */
184         ev_handlers[ev_type] = new_h;
185         spin_pdr_unlock(&ev_h_wlock);
186         return 0;
187 }
188
189 int deregister_ev_handler(unsigned int ev_type, handle_event_t handler,
190                           void *data)
191 {
192         /* TODO: User-level RCU */
193         printf("Failed to dereg handler, not supported yet!\n");
194 }
195
196 static void run_ev_handlers(unsigned int ev_type, struct event_msg *ev_msg)
197 {
198         struct ev_handler *handler;
199         /* TODO: RCU read lock */
200         handler = ev_handlers[ev_type];
201         while (handler) {
202                 handler->func(ev_msg, ev_type, handler->data);
203                 handler = handler->next;
204         }
205 }
206
207 /* Attempts to handle a message.  Returns 1 if we dequeued a msg, 0 o/w. */
208 int handle_one_mbox_msg(struct event_mbox *ev_mbox)
209 {
210         struct event_msg local_msg;
211         unsigned int ev_type;
212         /* get_ucq returns 0 on success, -1 on empty */
213         if (get_ucq_msg(&ev_mbox->ev_msgs, &local_msg) == -1)
214                 return 0;
215         ev_type = local_msg.ev_type;
216         assert(ev_type < MAX_NR_EVENT);
217         printd("[event] UCQ (mbox %08p), ev_type: %d\n", ev_mbox, ev_type);
218         run_ev_handlers(ev_type, &local_msg);
219         return 1;
220 }
221
222 /* Handle an mbox.  This is the receive-side processing of an event_queue.  It
223  * takes an ev_mbox, since the vcpd mbox isn't a regular ev_q.  Returns 1 if we
224  * handled something, 0 o/w. */
225 int handle_mbox(struct event_mbox *ev_mbox)
226 {
227         int retval = 0;
228         uint32_t vcoreid = vcore_id();
229         void bit_handler(unsigned int bit) {
230                 printd("[event] Bit: ev_type: %d\n", bit);
231                 run_ev_handlers(bit, 0);
232                 retval = 1;
233                 /* Consider checking the queue for incoming messages while we're here */
234         }
235         printd("[event] handling ev_mbox %08p on vcore %d\n", ev_mbox, vcore_id());
236         /* Some stack-smashing bugs cause this to fail */
237         assert(ev_mbox);
238         /* Handle all full messages, tracking if we do at least one. */
239         while (handle_one_mbox_msg(ev_mbox))
240                 retval = 1;
241         /* Process all bits, if the kernel tells us any bit is set.  We don't clear
242          * the flag til after we check everything, in case one of the handlers
243          * doesn't return.  After we clear it, we recheck. */
244         if (ev_mbox->ev_check_bits) {
245                 do {
246                         ev_mbox->ev_check_bits = TRUE;  /* in case we don't return */
247                         cmb();
248                         BITMASK_FOREACH_SET(ev_mbox->ev_bitmap, MAX_NR_EVENT, bit_handler,
249                                             TRUE);
250                         ev_mbox->ev_check_bits = FALSE;
251                         wrmb(); /* check_bits written before we check for it being clear */
252                 } while (!BITMASK_IS_CLEAR(ev_mbox->ev_bitmap, MAX_NR_EVENT));
253         }
254         return retval;
255 }
256
257 /* Empty if the UCQ is empty and the bits don't need checked */
258 bool mbox_is_empty(struct event_mbox *ev_mbox)
259 {
260         return (ucq_is_empty(&ev_mbox->ev_msgs) && (!ev_mbox->ev_check_bits));
261 }
262
263 /* The EV_EVENT handler - extract the ev_q from the message. */
264 void handle_ev_ev(struct event_msg *ev_msg, unsigned int ev_type, void *data)
265 {
266         struct event_queue *ev_q;
267         /* EV_EVENT can't handle not having a message / being a bit.  If we got a
268          * bit message, it's a bug somewhere */
269         assert(ev_msg);
270         ev_q = ev_msg->ev_arg3;
271         /* Same deal, a null ev_q is probably a bug, or someone being a jackass */
272         assert(ev_q);
273         /* Clear pending, so we can start getting INDIRs and IPIs again.  We must
274          * set this before (compared to handle_events, then set it, then handle
275          * again), since there is no guarantee handle_event_q() will return.  If
276          * there is a pending preemption, the vcore quickly yields and will deal
277          * with the remaining events in the future - meaning it won't return to
278          * here. */
279         ev_q->ev_alert_pending = FALSE;
280         wmb();  /* don't let the pending write pass the signaling of an ev recv */
281         handle_event_q(ev_q);
282 }
283
284 /* Handles VCPD events (public and private).  The kernel always sets
285  * notif_pending after posting a message to either public or private mailbox.
286  * When this returns, as far as we are concerned, notif_pending is FALSE.
287  * However, a concurrent kernel writer could have reset it to true.  This is
288  * fine; whenever we leave VC ctx we double check notif_pending.  Returns 1 or 2
289  * if we actually handled a message, 0 o/w.
290  *
291  * WARNING: this might not return and/or current_uthread may change. */
292 int handle_events(uint32_t vcoreid)
293 {
294         struct preempt_data *vcpd = vcpd_of(vcoreid);
295         int retval = 0;
296         vcpd->notif_pending = FALSE;
297         wrmb(); /* prevent future reads from happening before notif_p write */
298         retval += handle_mbox(&vcpd->ev_mbox_private);
299         retval += handle_mbox(&vcpd->ev_mbox_public);
300         return retval;
301 }
302
303 /* Handles the events on ev_q IAW the event_handlers[].  If the ev_q is
304  * application specific, then this will dispatch/handle based on its flags. */
305 void handle_event_q(struct event_queue *ev_q)
306 {
307         /* If the program wants to handle the ev_q on its own: */
308         if (ev_q->ev_flags & (EVENT_JUSTHANDLEIT | EVENT_THREAD)) {
309                 if (!ev_q->ev_handler) {
310                         printf("No ev_handler installed for ev_q %08p, aborting!\n", ev_q);
311                         return;
312                 }
313                 if (ev_q->ev_flags & EVENT_JUSTHANDLEIT) {
314                         /* Remember this can't block or page fault */
315                         ev_q->ev_handler(ev_q);
316                 } else if (ev_q->ev_flags & EVENT_THREAD) {
317                         /* 2LS sched op.  The 2LS can use an existing thread if it wants,
318                          * but do so inside spawn_thread() */
319                         if (sched_ops->spawn_thread)
320                                 sched_ops->spawn_thread((uintptr_t)ev_q->ev_handler, ev_q);
321                         else
322                                 printf("2LS can't spawn a thread for ev_q %08p\n", ev_q);
323                 }
324                 return;
325         }
326         printd("[event] handling ev_q %08p on vcore %d\n", ev_q, vcore_id());
327         /* Raw ev_qs that haven't been connected to an mbox, user bug: */
328         assert(ev_q->ev_mbox);
329         handle_mbox(ev_q->ev_mbox);
330 }
331
332 /* Sends the calling vcore a message to its public mbox.  This is purposefully
333  * limited to just the calling vcore, since in future versions, we can send via
334  * ucqs directly (in many cases).  That will require the caller to be the
335  * vcoreid, due to some preemption recovery issues (another ucq poller is
336  * waiting on us when we got preempted, and we never up nr_cons). */
337 void send_self_vc_msg(struct event_msg *ev_msg)
338 {
339         // TODO: try to use UCQs (requires additional support)
340         /* ev_type actually gets ignored currently.  ev_msg is what matters if it is
341          * non-zero.  FALSE means it's going to the public mbox */
342         sys_self_notify(vcore_id(), ev_msg->ev_type, ev_msg, FALSE);
343 }
344
345 /* Helper: makes the current core handle a remote vcore's VCPD public mbox events.
346  *
347  * Both cases (whether we are handling someone else's already or not) use some
348  * method of telling our future self what to do.  When we aren't already
349  * handling it, we use TLS, and jump to vcore entry.  When we are already
350  * handling, then we send a message to ourself, which we deal with when we
351  * handle our own events (which is later in vcore entry).
352  *
353  * We need to reset the stack and deal with it in vcore entry to avoid recursing
354  * deeply and running off the transition stack.  (handler calling handle event).
355  *
356  * Note that we might not be the one that gets the message we send.  If we pull
357  * a sys_change_to, someone else might be polling our public message box.  All
358  * we're doing is making sure that we don't forget to check rem_vcoreid's mbox.
359  *
360  * Finally, note that this function might not return.  However, it'll handle the
361  * details related to vcpd mboxes, so you don't use the ev_might_not_return()
362  * helpers with this. */
363 void handle_vcpd_mbox(uint32_t rem_vcoreid)
364 {
365         uint32_t vcoreid = vcore_id();
366         struct preempt_data *vcpd = vcpd_of(vcoreid);
367         struct event_msg local_msg = {0};
368         assert(vcoreid != rem_vcoreid);                 /* this shouldn't happen */
369         /* If they are empty, then we're done */
370         if (mbox_is_empty(&vcpd_of(rem_vcoreid)->ev_mbox_public))
371                 return;
372         if (__vc_handle_an_mbox) {
373                 /* we might be already handling them, in which case, abort */
374                 if (__vc_rem_vcoreid == rem_vcoreid)
375                         return;
376                 /* Already handling message for someone, need to send ourselves a
377                  * message to check rem_vcoreid, which we'll process later. */
378                 local_msg.ev_type = EV_CHECK_MSGS;
379                 local_msg.ev_arg2 = rem_vcoreid;        /* 32bit arg */
380                 send_self_vc_msg(&local_msg);
381                 return;
382         }
383         /* No return after here */
384         /* At this point, we aren't in the process of handling someone else's
385          * messages, so just tell our future self what to do */
386         __vc_handle_an_mbox = TRUE;
387         __vc_rem_vcoreid = rem_vcoreid;
388         /* Reset the stack and start over in vcore context */
389         set_stack_pointer((void*)vcpd->transition_stack);
390         vcore_entry();
391         assert(0);
392 }
393
394 /* Handle remote vcpd public mboxes, if that's what we want to do.  Call this
395  * from vcore entry, pairs with handle_vcpd_mbox(). */
396 void try_handle_remote_mbox(void)
397 {
398         if (__vc_handle_an_mbox) {
399                 handle_mbox(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public);
400                 /* only clear the flag when we have returned from handling messages.  if
401                  * an event handler (like preempt_recover) doesn't return, we'll clear
402                  * this flag elsewhere. (it's actually not a big deal if we don't). */
403                 cmb();
404                 __vc_handle_an_mbox = FALSE;
405         }
406 }
407
408 /* Event handler helpers */
409
410 /* For event handlers that might not return, we need to call this before the
411  * command that might not return.  In the event we were handling a remote
412  * vcore's messages, it'll send ourselves a messages that we (or someone who
413  * polls us) will get so that someone finishes off that vcore's messages).
414  * Doesn't matter who does, so long as someone does.
415  *
416  * This returns whether or not we were handling someone's messages.  Pass the
417  * parameter to ev_we_returned() */
418 bool ev_might_not_return(void)
419 {
420         struct event_msg local_msg = {0};
421         bool were_handling_remotes = FALSE;
422         if (__vc_handle_an_mbox) {
423                 /* slight chance we finished with their mbox (were on the last one) */
424                 if (!mbox_is_empty(&vcpd_of(__vc_rem_vcoreid)->ev_mbox_public)) {
425                         /* But we aren't, so we'll need to send a message */
426                         local_msg.ev_type = EV_CHECK_MSGS;
427                         local_msg.ev_arg2 = __vc_rem_vcoreid;   /* 32bit arg */
428                         send_self_vc_msg(&local_msg);
429                 }
430                 /* Either way, we're not working on this one now.  Note this is more of
431                  * an optimization - it'd be harmless (I think) to poll another vcore's
432                  * pub mbox once when we pop up in vc_entry in the future */
433                 __vc_handle_an_mbox = FALSE;
434                 return TRUE;
435         }
436         return FALSE;
437 }
438
439 /* Call this when you return, paired up with ev_might_not_return().  If
440  * ev_might_not_return turned off uth_handle, we'll turn it back on. */
441 void ev_we_returned(bool were_handling_remotes)
442 {
443         if (were_handling_remotes)
444                 __vc_handle_an_mbox = TRUE;
445 }
446
447 /* Debugging */
448 void print_ev_msg(struct event_msg *msg)
449 {
450         printf("MSG at %08p\n", msg);
451         printf("\ttype: %d\n", msg->ev_type);
452         printf("\targ1 (16): 0x%4x\n", msg->ev_arg1);
453         printf("\targ2 (32): 0x%8x\n", msg->ev_arg2);
454         printf("\targ3 (32): 0x%8x\n", msg->ev_arg3);
455         printf("\targ4 (64): 0x%16x\n", msg->ev_arg4);
456 }