The initrd now works.
[akaros.git] / user / parlib / vcore.c
1 #include <parlib/arch/arch.h>
2 #include <stdbool.h>
3 #include <errno.h>
4 #include <parlib/vcore.h>
5 #include <parlib/mcs.h>
6 #include <sys/param.h>
7 #include <parlib/parlib.h>
8 #include <unistd.h>
9 #include <stdlib.h>
10 #include <sys/mman.h>
11 #include <stdio.h>
12 #include <parlib/event.h>
13 #include <parlib/uthread.h>
14 #include <parlib/ucq.h>
15 #include <ros/arch/membar.h>
16 #include <parlib/printf-ext.h>
17 #include <parlib/poke.h>
18 #include <parlib/assert.h>
19 #include <parlib/stdio.h>
20
21 __thread int __vcoreid = 0;
22 __thread bool __vcore_context = FALSE;
23
24 __thread struct syscall __vcore_one_sysc = {.flags = (atomic_t)SC_DONE, 0};
25
26 /* Per vcore entery function used when reentering at the top of a vcore's stack */
27 static __thread void (*__vcore_reentry_func)(void) = NULL;
28
29 /* The default user vcore_entry function. */
30 void __attribute__((noreturn)) __vcore_entry(void)
31 {
32         extern void uthread_vcore_entry(void);
33         uthread_vcore_entry();
34         fprintf(stderr, "vcore_entry() should never return!\n");
35         abort();
36         __builtin_unreachable();
37 }
38 void vcore_entry(void) __attribute__((weak, alias ("__vcore_entry")));
39
40 static void __fake_start(void)
41 {
42 }
43 void _start(void) __attribute__((weak, alias ("__fake_start")));
44
45 /* Shared libraries also contain parlib.  That'll be true until we start making
46  * parlib a .so, which has some TLS implications (and maybe others).  The real
47  * parlib is the one in the program binary, not the shared libraries.  This
48  * detection works because all shared libs, both the -l and the dlopens, are
49  * mapped above the BRK.
50  *
51  * Previously, we tried using weak symbols, specifically _start or _end, but be
52  * careful.  If you pass e.g. _start or _end to a function or inline asm, the
53  * program binary will do something slightly different, which may make the
54  * shared library load different values. */
55 bool __in_fake_parlib(void)
56 {
57         static char dummy;
58
59         return (uintptr_t)&dummy > BRK_START;
60 }
61
62 /* TODO: probably don't want to dealloc.  Considering caching */
63 static void free_transition_tls(int id)
64 {
65         if (get_vcpd_tls_desc(id)) {
66                 /* Note we briefly have no TLS desc in VCPD.  This is fine so long as
67                  * that vcore doesn't get started fresh before we put in a new desc */
68                 free_tls(get_vcpd_tls_desc(id));
69                 set_vcpd_tls_desc(id, NULL);
70         }
71 }
72
73 static int allocate_transition_tls(int id)
74 {
75         /* Libc function to initialize TLS-based locale info for ctype functions. */
76         extern void __ctype_init(void);
77
78         /* We want to free and then reallocate the tls rather than simply 
79          * reinitializing it because its size may have changed.  TODO: not sure if
80          * this is right.  0-ing is one thing, but freeing and reallocating can be
81          * expensive, esp if syscalls are involved.  Check out glibc's
82          * allocatestack.c for what might work. */
83         free_transition_tls(id);
84
85         void *tcb = allocate_tls();
86         if (!tcb) {
87                 errno = ENOMEM;
88                 return -1;
89         }
90
91         /* Setup some intitial TLS data for the newly allocated transition tls. */
92         void *temp_tcb = get_tls_desc();
93         set_tls_desc(tcb);
94         begin_safe_access_tls_vars();
95         __vcoreid = id;
96         __vcore_context = TRUE;
97         __ctype_init();
98         end_safe_access_tls_vars();
99         set_tls_desc(temp_tcb);
100
101         /* Install the new tls into the vcpd. */
102         set_vcpd_tls_desc(id, tcb);
103         return 0;
104 }
105
106 static void free_vcore_stack(int id)
107 {
108         // don't actually free stacks
109 }
110
111 static int allocate_vcore_stack(int id)
112 {
113         struct preempt_data *vcpd = vcpd_of(id);
114         if (vcpd->vcore_stack)
115                 return 0; // reuse old stack
116
117         void* stackbot = mmap(0, TRANSITION_STACK_SIZE,
118                               PROT_READ | PROT_WRITE | PROT_EXEC,
119                               MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
120
121         if(stackbot == MAP_FAILED)
122                 return -1; // errno set by mmap
123
124         vcpd->vcore_stack = (uintptr_t)stackbot + TRANSITION_STACK_SIZE;
125
126         return 0;
127 }
128
129 /* Helper: prepares a vcore for use.  Takes a block of pages for the UCQs.
130  *
131  * Vcores need certain things, such as a stack and TLS.  These are determined by
132  * userspace.  Every vcore needs these set up before we drop into vcore context
133  * on that vcore.  This means we need to prep before asking the kernel for those
134  * vcores.
135  *
136  * We could have this function do its own mmap, at the expense of O(n) syscalls
137  * when we prepare the extra vcores. */
138 static void __prep_vcore(int vcoreid, uintptr_t mmap_block)
139 {
140         struct preempt_data *vcpd = vcpd_of(vcoreid);
141         int ret;
142
143         ret = allocate_vcore_stack(vcoreid);
144                 assert(!ret);
145         ret = allocate_transition_tls(vcoreid);
146                 assert(!ret);
147
148         vcpd->ev_mbox_public.type = EV_MBOX_UCQ;
149         ucq_init_raw(&vcpd->ev_mbox_public.ucq,
150                      mmap_block + 0 * PGSIZE,
151                      mmap_block + 1 * PGSIZE);
152         vcpd->ev_mbox_private.type = EV_MBOX_UCQ;
153         ucq_init_raw(&vcpd->ev_mbox_private.ucq,
154                      mmap_block + 2 * PGSIZE,
155                      mmap_block + 3 * PGSIZE);
156
157         /* Set the lowest level entry point for each vcore. */
158         vcpd->vcore_entry = (uintptr_t)__kernel_vcore_entry;
159 }
160
161 static void prep_vcore_0(void)
162 {
163         uintptr_t mmap_block;
164
165         mmap_block = (uintptr_t)mmap(0, PGSIZE * 4,
166                                      PROT_WRITE | PROT_READ,
167                                      MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE,
168                                      -1, 0);
169         assert((void*)mmap_block != MAP_FAILED);
170         __prep_vcore(0, mmap_block);
171 }
172
173 static void prep_remaining_vcores(void)
174 {
175         uintptr_t mmap_block;
176
177         mmap_block = (uintptr_t)mmap(0, PGSIZE * 4 * (max_vcores() - 1),
178                                      PROT_WRITE | PROT_READ,
179                                      MAP_POPULATE | MAP_ANONYMOUS | MAP_PRIVATE,
180                                      -1, 0);
181         assert((void*)mmap_block != MAP_FAILED);
182         for (int i = 1; i < max_vcores(); i++)
183                 __prep_vcore(i, mmap_block + 4 * (i - 1) * PGSIZE);
184 }
185
186 /* Run libc specific early setup code. */
187 static void vcore_libc_init(void)
188 {
189         register_printf_specifier('r', printf_errstr, printf_errstr_info);
190         /* TODO: register for other kevents/signals and whatnot (can probably reuse
191          * the simple ev_q).  Could also do this via explicit functions from the
192          * program. */
193 }
194
195 void __attribute__((constructor)) vcore_lib_init(void)
196 {
197         if (__in_fake_parlib())
198                 return;
199         /* Note this is racy, but okay.  The first time through, we are _S.
200          * Also, this is the "lowest" level constructor for now, so we don't need
201          * to call any other init functions after our run_once() call. This may
202          * change in the future. */
203         parlib_init_once_racy(return);
204         /* Need to alloc vcore0's transition stuff here (technically, just the TLS)
205          * so that schedulers can use vcore0's transition TLS before it comes up in
206          * vcore_entry() */
207         prep_vcore_0();
208         assert(!in_vcore_context());
209         vcore_libc_init();
210 }
211
212 /* Helper functions used to reenter at the top of a vcore's stack for an
213  * arbitrary function */
214 static void __attribute__((noinline, noreturn)) 
215 __vcore_reenter()
216 {
217   __vcore_reentry_func();
218   assert(0);
219 }
220
221 void vcore_reenter(void (*entry_func)(void))
222 {
223   assert(in_vcore_context());
224   struct preempt_data *vcpd = vcpd_of(vcore_id());
225
226   __vcore_reentry_func = entry_func;
227   set_stack_pointer((void*)vcpd->vcore_stack);
228   cmb();
229   __vcore_reenter();
230 }
231
232 /* Helper, picks some sane defaults and changes the process into an MCP */
233 void vcore_change_to_m(void)
234 {
235         int ret;
236
237         prep_remaining_vcores();
238         __procdata.res_req[RES_CORES].amt_wanted = 1;
239         __procdata.res_req[RES_CORES].amt_wanted_min = 1;       /* whatever */
240         assert(!in_multi_mode());
241         assert(!in_vcore_context());
242         ret = sys_change_to_m();
243         assert(!ret);
244         assert(in_multi_mode());
245         assert(!in_vcore_context());
246 }
247
248 static void __vc_req_poke(void *nr_vc_wanted)
249 {
250         long nr_vcores_wanted = *(long*)nr_vc_wanted;
251
252         /* We init'd up to max_vcores() VCs during init.  This assumes the kernel
253          * doesn't magically change that value (which it should not do). */
254         nr_vcores_wanted = MIN(nr_vcores_wanted, max_vcores());
255         if (nr_vcores_wanted > __procdata.res_req[RES_CORES].amt_wanted)
256                 __procdata.res_req[RES_CORES].amt_wanted = nr_vcores_wanted;
257         if (nr_vcores_wanted > num_vcores())
258                 sys_poke_ksched(0, RES_CORES);  /* 0 -> poke for ourselves */
259 }
260 static struct poke_tracker vc_req_poke = POKE_INITIALIZER(__vc_req_poke);
261
262 /* Requests the kernel that we have a total of nr_vcores_wanted.
263  *
264  * This is callable by multiple threads/vcores concurrently.  Exactly one of
265  * them will actually run __vc_req_poke.  The others will just return.
266  *
267  * This means that two threads could ask for differing amounts, and only one of
268  * them will succeed.  This is no different than a racy write to a shared
269  * variable.  The poke provides a single-threaded environment, so that we don't
270  * worry about racing on VCPDs or hitting the kernel with excessive SYS_pokes.
271  *
272  * Since we're using the post-and-poke style, we can do a 'last write wins'
273  * policy for the value used in the poke (and subsequent pokes). */
274 void vcore_request_total(long nr_vcores_wanted)
275 {
276         static long nr_vc_wanted;
277
278         if (parlib_never_vc_request || !parlib_wants_to_be_mcp)
279                 return;
280         if (nr_vcores_wanted == __procdata.res_req[RES_CORES].amt_wanted)
281                 return;
282
283         /* We race to "post our work" here.  Whoever handles the poke will get the
284          * latest value written here. */
285         nr_vc_wanted = nr_vcores_wanted;
286         poke(&vc_req_poke, &nr_vc_wanted);
287 }
288
289 /* This tries to get "more vcores", based on the number we currently have.
290  *
291  * What happens is we can have a bunch of threads trying to get "another vcore",
292  * which currently means more than num_vcores().  If you have someone ask for
293  * two more, and then someone else ask for one more, how many you ultimately ask
294  * for depends on if the kernel heard you and adjusted num_vcores in between the
295  * two calls.  Or maybe your amt_wanted already was num_vcores + 5, so neither
296  * call is telling the kernel anything new.  It comes down to "one more than I
297  * have" vs "one more than I've already asked for".
298  *
299  * So for now, this will keep the older behavior (one more than I have).  This
300  * is all quite racy, so we can just guess and request a total number of vcores.
301  */
302 void vcore_request_more(long nr_new_vcores)
303 {
304         vcore_request_total(nr_new_vcores + num_vcores());
305 }
306
307 /* This can return, if you failed to yield due to a concurrent event.  Note
308  * we're atomicly setting the CAN_RCV flag, and aren't bothering with CASing
309  * (either with the kernel or uthread's handle_indirs()).  We don't particularly
310  * care what other code does - we intend to set those flags no matter what. */
311 void vcore_yield(bool preempt_pending)
312 {
313         unsigned long old_nr;
314         uint32_t vcoreid = vcore_id();
315         struct preempt_data *vcpd = vcpd_of(vcoreid);
316
317         if (!preempt_pending && parlib_never_yield)
318                 return;
319         __sync_fetch_and_and(&vcpd->flags, ~VC_CAN_RCV_MSG);
320         /* no wrmb() necessary, handle_events() has an mb() if it is checking */
321         /* Clears notif pending and tries to handle events.  This is an optimization
322          * to avoid the yield syscall if we have an event pending.  If there is one,
323          * we want to unwind and return to the 2LS loop, where we may not want to
324          * yield anymore.
325          * Note that the kernel only cares about CAN_RCV_MSG for the desired vcore;
326          * when spamming, it relies on membership of lists within the kernel.  Look
327          * at spam_list_member() for more info (k/s/event.c). */
328         if (handle_events(vcoreid)) {
329                 __sync_fetch_and_or(&vcpd->flags, VC_CAN_RCV_MSG);
330                 return;
331         }
332         /* If we are yielding since we don't want the core, tell the kernel we want
333          * one less vcore (vc_yield assumes a dumb 2LS).
334          *
335          * If yield fails (slight race), we may end up having more vcores than
336          * amt_wanted for a while, and might lose one later on (after a
337          * preempt/timeslicing) - the 2LS will have to notice eventually if it
338          * actually needs more vcores (which it already needs to do).  amt_wanted
339          * could even be 0.
340          *
341          * In general, any time userspace decrements or sets to 0, it could get
342          * preempted, so the kernel will still give us at least one, until the last
343          * vcore properly yields without missing a message (and becomes a WAITING
344          * proc, which the ksched will not give cores to).
345          *
346          * I think it's possible for userspace to do this (lock, read amt_wanted,
347          * check all message queues for all vcores, subtract amt_wanted (not set to
348          * 0), unlock) so long as every event handler +1s the amt wanted, but that's
349          * a huge pain, and we already have event handling code making sure a
350          * process can't sleep (transition to WAITING) if a message arrives (can't
351          * yield if notif_pending, can't go WAITING without yielding, and the event
352          * posting the notif_pending will find the online VC or be delayed by
353          * spinlock til the proc is WAITING). */
354         if (!preempt_pending) {
355                 do {
356                         old_nr = __procdata.res_req[RES_CORES].amt_wanted;
357                         if (old_nr == 0)
358                                 break;
359                 } while (!__sync_bool_compare_and_swap(
360                              &__procdata.res_req[RES_CORES].amt_wanted,
361                              old_nr, old_nr - 1));
362         }
363         /* We can probably yield.  This may pop back up if notif_pending became set
364          * by the kernel after we cleared it and we lost the race. */
365         sys_yield(preempt_pending);
366         __sync_fetch_and_or(&vcpd->flags, VC_CAN_RCV_MSG);
367 }
368
369 /* Enables notifs, and deals with missed notifs by self notifying.  This should
370  * be rare, so the syscall overhead isn't a big deal.  The other alternative
371  * would be to uthread_yield(), which would require us to revert some uthread
372  * interface changes. */
373 void enable_notifs(uint32_t vcoreid)
374 {
375         __enable_notifs(vcoreid);
376         wrmb(); /* need to read after the write that enabled notifs */
377         /* Note we could get migrated before executing this.  If that happens, our
378          * vcore had gone into vcore context (which is what we wanted), and this
379          * self_notify to our old vcore is spurious and harmless. */
380         if (vcpd_of(vcoreid)->notif_pending)
381                 sys_self_notify(vcoreid, EV_NONE, 0, TRUE);
382 }
383
384 /* Helper to disable notifs.  It simply checks to make sure we disabled uthread
385  * migration, which is a common mistake. */
386 void disable_notifs(uint32_t vcoreid)
387 {
388         if (!in_vcore_context() && current_uthread)
389                 assert(current_uthread->flags & UTHREAD_DONT_MIGRATE);
390         __disable_notifs(vcoreid);
391 }
392
393 /* Like smp_idle(), this will put the core in a state that it can only be woken
394  * up by an IPI.  For now, this is a halt.  Maybe an mwait in the future.
395  *
396  * This will return if an event was pending (could be the one you were waiting
397  * for) or if the halt failed for some reason, such as a concurrent RKM.  If
398  * successful, this will not return at all, and the vcore will restart from the
399  * top next time it wakes.  Any sort of IRQ will wake the core.
400  *
401  * Alternatively, I might make this so it never returns, if that's easier to
402  * work with (similar issues with yield). */
403 void vcore_idle(void)
404 {
405         uint32_t vcoreid = vcore_id();
406         /* Once we enable notifs, the calling context will be treated like a uthread
407          * (saved into the uth slot).  We don't want to ever run it again, so we
408          * need to make sure there's no cur_uth. */
409         assert(!current_uthread);
410         /* This clears notif_pending (check, signal, check again pattern). */
411         if (handle_events(vcoreid))
412                 return;
413         /* This enables notifs, but also checks notif pending.  At this point, any
414          * new notifs will restart the vcore from the top. */
415         enable_notifs(vcoreid);
416         /* From now, til we get into the kernel, any notifs will permanently destroy
417          * this context and start the VC from the top.
418          *
419          * Once we're in the kernel, any messages (__notify, __preempt), will be
420          * RKMs.  halt will need to check for those atomically.  Checking for
421          * notif_pending in the kernel (sleep only if not set) is not enough, since
422          * not all reasons for the kernel to stay awak set notif_pending (e.g.,
423          * __preempts and __death).
424          *
425          * At this point, we're out of VC ctx, so anyone who sets notif_pending
426          * should also send an IPI / __notify */
427         sys_halt_core(0);
428         /* in case halt returns without actually restarting the VC ctx. */
429         disable_notifs(vcoreid);
430 }
431
432 /* Helper, that actually makes sure a vcore is running.  Call this is you really
433  * want vcoreid.  More often, you'll want to call the regular version. */
434 static void __ensure_vcore_runs(uint32_t vcoreid)
435 {
436         if (vcore_is_preempted(vcoreid)) {
437                 printd("[vcore]: VC %d changing to VC %d\n", vcore_id(), vcoreid);
438                 /* Note that at this moment, the vcore could still be mapped (we're
439                  * racing with __preempt.  If that happens, we'll just fail the
440                  * sys_change_vcore(), and next time __ensure runs we'll get it. */
441                 /* We want to recover them from preemption.  Since we know they have
442                  * notifs disabled, they will need to be directly restarted, so we can
443                  * skip the other logic and cut straight to the sys_change_vcore() */
444                 sys_change_vcore(vcoreid, FALSE);
445         }
446 }
447
448 /* Helper, looks for any preempted vcores, making sure each of them runs at some
449  * point.  This is pretty heavy-weight, and should be used to help get out of
450  * weird deadlocks (spinning in vcore context, waiting on another vcore).  If
451  * you might know which vcore you are waiting on, use ensure_vc_runs. */
452 static void __ensure_all_run(void)
453 {
454         for (int i = 0; i < max_vcores(); i++)
455                 __ensure_vcore_runs(i);
456 }
457
458 /* Makes sure a vcore is running.  If it is preempted, we'll switch to
459  * it.  This will return, either immediately if the vcore is running, or later
460  * when someone preempt-recovers us.
461  *
462  * If you pass in your own vcoreid, this will make sure all other preempted
463  * vcores run. */
464 void ensure_vcore_runs(uint32_t vcoreid)
465 {
466         /* if the vcoreid is ourselves, make sure everyone else is running */
467         if (vcoreid == vcore_id()) {
468                 __ensure_all_run();
469                 return;
470         }
471         __ensure_vcore_runs(vcoreid);
472 }
473
474 #define NR_RELAX_SPINS 1000
475 /* If you are spinning and waiting on another vcore, call this.  Pass in the
476  * vcoreid of the core you are waiting on, or your own vcoreid if you don't
477  * know.  It will spin for a bit before firing up the potentially expensive
478  * __ensure_all_run(). */
479 void cpu_relax_vc(uint32_t other_vcoreid)
480 {
481         static __thread unsigned int __vc_relax_spun = 0;
482
483         /* Uthreads with notifs enabled can just spin normally.  This actually
484          * depends on the 2LS preemption policy.  Currently, we receive notifs
485          * whenever another core is preempted, so we don't need to poll. */
486         if (notif_is_enabled(vcore_id())) {
487                 cpu_relax();
488                 return;
489         }
490         if (__vc_relax_spun++ >= NR_RELAX_SPINS) {
491                 /* if other_vcoreid == vcore_id(), this might be expensive */
492                 ensure_vcore_runs(other_vcoreid);
493                 __vc_relax_spun = 0;
494         }
495         cpu_relax();
496 }
497
498 /* Check with the kernel to determine what vcore we are.  Normally, you should
499  * never call this, since your vcoreid is stored in your TLS.  Also, if you call
500  * it from a uthread, you could get migrated, so you should drop into some form
501  * of vcore context (DONT_MIGRATE on) */
502 uint32_t get_vcoreid(void)
503 {
504         if (!in_vcore_context()) {
505                 assert(current_uthread);
506                 assert(current_uthread->flags & UTHREAD_DONT_MIGRATE);
507         }
508         return __get_vcoreid();
509 }
510
511 /* Debugging helper.  Pass in the string you want printed if your vcoreid is
512  * wrong, and pass in what vcoreid you think you are.  Don't call from uthread
513  * context unless migrations are disabled.  Will print some stuff and return
514  * FALSE if you were wrong. */
515 bool check_vcoreid(const char *str, uint32_t vcoreid)
516 {
517         uint32_t kvcoreid = get_vcoreid();
518         if (vcoreid != kvcoreid) {
519                 printf("%s: VC %d thought it was VC %d\n", str, kvcoreid, vcoreid);
520                 return FALSE;
521         }
522         return TRUE;
523 }
524
525 /* Helper.  Yields the vcore, or restarts it from scratch. */
526 void __attribute__((noreturn)) vcore_yield_or_restart(void)
527 {
528         struct preempt_data *vcpd = vcpd_of(vcore_id());
529
530         vcore_yield(FALSE);
531         /* If vcore_yield returns, we have an event.  Just restart vcore context. */
532         set_stack_pointer((void*)vcpd->vcore_stack);
533         vcore_entry();
534 }