Merge branch 'net-dev'. See body of commit for details.
[akaros.git] / kern / src / process.c
1 /*
2  * Copyright (c) 2009 The Regents of the University of California
3  * Barret Rhoden <brho@cs.berkeley.edu>
4  * See LICENSE for details.
5  */
6
7 #ifdef __SHARC__
8 #pragma nosharc
9 #endif
10
11 #include <arch/arch.h>
12 #include <process.h>
13 #include <atomic.h>
14 #include <smp.h>
15 #include <pmap.h>
16 #include <schedule.h>
17 #include <manager.h>
18 #include <stdio.h>
19 #include <assert.h>
20 #include <timing.h>
21 #include <sys/queue.h>
22
23 /* Process Lists */
24 struct proc_list proc_freelist = TAILQ_HEAD_INITIALIZER(proc_freelist);
25 spinlock_t freelist_lock = 0;
26 struct proc_list proc_runnablelist = TAILQ_HEAD_INITIALIZER(proc_runnablelist);
27 spinlock_t runnablelist_lock = 0;
28
29 /* Tracks which cores are idle, similar to the vcoremap.  Each value is the
30  * physical coreid of an unallocated core. */
31 spinlock_t idle_lock = 0;
32 uint32_t LCKD(&idle_lock) (RO idlecoremap)[MAX_NUM_CPUS];
33 uint32_t LCKD(&idle_lock) num_idlecores = 0;
34
35 /*
36  * While this could be done with just an assignment, this gives us the
37  * opportunity to check for bad transitions.  Might compile these out later, so
38  * we shouldn't rely on them for sanity checking from userspace.
39  */
40 int proc_set_state(struct proc *p, uint32_t state)
41 {
42         uint32_t curstate = p->state;
43         /* Valid transitions:
44          * C   -> RBS
45          * RBS -> RGS
46          * RGS -> RBS
47          * RGS -> W
48          * W   -> RBS
49          * RGS -> RBM
50          * RBM -> RGM
51          * RGM -> RBM
52          * RGM -> RBS
53          * RGS -> D
54          * RGM -> D
55          *
56          * These ought to be implemented later (allowed, not thought through yet).
57          * RBS -> D
58          * RBM -> D
59          *
60          * This isn't allowed yet, may be later.
61          * C   -> D
62          */
63         #if 1 // some sort of correctness flag
64         switch (curstate) {
65                 case PROC_CREATED:
66                         if (state != PROC_RUNNABLE_S)
67                                 panic("Invalid State Transition! PROC_CREATED to %d", state);
68                         break;
69                 case PROC_RUNNABLE_S:
70                         if (!(state & (PROC_RUNNING_S | PROC_DYING)))
71                                 panic("Invalid State Transition! PROC_RUNNABLE_S to %d", state);
72                         break;
73                 case PROC_RUNNING_S:
74                         if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_WAITING |
75                                        PROC_DYING)))
76                                 panic("Invalid State Transition! PROC_RUNNING_S to %d", state);
77                         break;
78                 case PROC_WAITING:
79                         if (state != PROC_RUNNABLE_S)
80                                 panic("Invalid State Transition! PROC_WAITING to %d", state);
81                         break;
82                 case PROC_DYING:
83                         if (state != PROC_CREATED) // when it is reused (TODO)
84                                 panic("Invalid State Transition! PROC_DYING to %d", state);
85                         break;
86                 case PROC_RUNNABLE_M:
87                         if (!(state & (PROC_RUNNING_M | PROC_DYING)))
88                                 panic("Invalid State Transition! PROC_RUNNABLE_M to %d", state);
89                         break;
90                 case PROC_RUNNING_M:
91                         if (!(state & (PROC_RUNNABLE_S | PROC_RUNNABLE_M | PROC_DYING)))
92                                 panic("Invalid State Transition! PROC_RUNNING_M to %d", state);
93                         break;
94         }
95         #endif
96         p->state = state;
97         return 0;
98 }
99
100 /* Change this when we aren't using an array */
101 struct proc *get_proc(unsigned pid)
102 {
103         // should have some error checking when we do this for real
104         return &envs[ENVX(pid)];
105 }
106
107 /* Whether or not actor can control target */
108 bool proc_controls(struct proc *actor, struct proc *target)
109 {
110         return target->env_parent_id == actor->env_id;
111 }
112
113 /*
114  * Dispatches a process to run, either on the current core in the case of a
115  * RUNNABLE_S, or on its partition in the case of a RUNNABLE_M.
116  * This should never be called to "restart" a core.
117  */
118 void proc_run(struct proc *p)
119 {
120         spin_lock_irqsave(&p->proc_lock);
121         switch (p->state) {
122                 case (PROC_DYING):
123                         spin_unlock_irqsave(&p->proc_lock);
124                         printk("Process %d not starting due to async death\n", p->env_id);
125                         // There should be no core cleanup to do (like decref).
126                         assert(current != p);
127                         // if we're a worker core, smp_idle, o/w return
128                         if (!management_core())
129                                 smp_idle(); // this never returns
130                         return;
131                 case (PROC_RUNNABLE_S):
132                         proc_set_state(p, PROC_RUNNING_S);
133                         // We will want to know where this process is running, even if it is
134                         // only in RUNNING_S.  can use the vcoremap, which makes death easy.
135                         // we may need the pcoremap entry to mark it as a RUNNING_S core, or
136                         // else update it here. (TODO) (PCORE)
137                         p->num_vcores = 0;
138                         p->vcoremap[0] = core_id();
139                         spin_unlock_irqsave(&p->proc_lock);
140                         // This normally doesn't return, but might error out in the future.
141                         proc_startcore(p, &p->env_tf);
142                         break;
143                 case (PROC_RUNNABLE_M):
144                         proc_set_state(p, PROC_RUNNING_M);
145                         /* vcoremap[i] holds the coreid of the physical core allocated to
146                          * this process.  It is set outside proc_run.  For the active
147                          * message, a0 = struct proc*, a1 = struct trapframe*.   */
148                         if (p->num_vcores) {
149                                 // TODO: handle silly state (HSS)
150                                 // set virtual core 0 to run the main context
151 #ifdef __IVY__
152                                 send_active_msg_sync(p->vcoremap[0], __startcore, p,
153                                                      &p->env_tf, (void *SNT)0);
154 #else
155                                 send_active_msg_sync(p->vcoremap[0], (void *)__startcore,
156                                                      (void *)p, (void *)&p->env_tf, 0);
157 #endif
158                                 /* handle the others.  note the sync message will spin until
159                                  * there is a free active message slot, which could lock up the
160                                  * system.  think about this. (TODO) */
161                                 for (int i = 1; i < p->num_vcores; i++)
162 #ifdef __IVY__
163                                         send_active_msg_sync(p->vcoremap[i], __startcore,
164                                                              p, (trapframe_t *CT(1))NULL, (void *SNT)i);
165 #else
166                                         send_active_msg_sync(p->vcoremap[i], (void *)__startcore,
167                                                              (void *)p, (void *)0, (void *)i);
168 #endif
169                         }
170                         /* There a subtle (attempted) race avoidance here.  proc_startcore
171                          * can handle a death message, but we can't have the startcore come
172                          * after the death message.  Otherwise, it would look like a new
173                          * process.  So we hold the lock to make sure our message went out
174                          * before a possible death message.
175                          * - Likewise, we need interrupts to be disabled, in case one of the
176                          *   messages was for us, and reenable them after letting go of the
177                          *   lock.  This is done by spin_lock_irqsave, so be careful if you
178                          *   change this.
179                          * - This can also be done far more intelligently / efficiently,
180                          *   like skipping in case it's busy and coming back later.
181                          * - Note there is no guarantee this core's interrupts were on, so
182                          *   it may not get the message for a while... */
183                         spin_unlock_irqsave(&p->proc_lock);
184                         break;
185                 default:
186                         spin_unlock_irqsave(&p->proc_lock);
187                         panic("Invalid process state in proc_run()!!");
188         }
189 }
190
191 /*
192  * Runs the given context (trapframe) of process p on the core this code
193  * executes on.  The refcnt tracks how many cores have "an interest" in this
194  * process, which so far just means it uses the process's page table.  See the
195  * massive comments around the incref function
196  *
197  * Given we are RUNNING_*, an IPI for death or preemption could come in:
198  * 1. death attempt (IPI to kill whatever is on your core):
199  *              we don't need to worry about protecting the stack, since we're
200  *              abandoning ship - just need to get a good cr3 and decref current, which
201  *              the death handler will do.
202  *              If a death IPI comes in, we immediately stop this function and will
203  *              never come back.
204  * 2. preempt attempt (IPI to package state and maybe run something else):
205  *              - if a preempt attempt comes in while we're in the kernel, it'll
206  *              just set a flag.  we could attempt to bundle the kernel state
207  *              and rerun it later, but it's really messy (and possibly given
208  *              back to userspace).  we'll disable ints, check this flag, and if
209  *              so, handle the preemption using the same funcs as the normal
210  *              preemption handler.  nonblocking kernel calls will just slow
211  *              down the preemption while they work.  blocking kernel calls will
212  *              need to package their state properly anyway.
213  *
214  * TODO: in general, think about when we no longer need the stack, in case we
215  * are preempted and expected to run again from somewhere else.  we can't
216  * expect to have the kernel stack around anymore.  the nice thing about being
217  * at this point is that we are just about ready to give up the stack anyways.
218  *
219  * I think we need to make it such that the kernel in "process context" never
220  * gets removed from the core (displaced from its stack) without going through
221  * some "bundling" code.
222  */
223 void proc_startcore(struct proc *p, trapframe_t *tf) {
224         // it's possible to be DYING, but it's a rare race.
225         //if (p->state & (PROC_RUNNING_S | PROC_RUNNING_M))
226         //      printk("dying before (re)startcore on core %d\n", core_id());
227
228         // sucks to have ints disabled when doing env_decref and possibly freeing
229         disable_irq();
230         if (per_cpu_info[core_id()].preempt_pending) {
231                 // TODO: handle preemption
232                 // the functions will need to consider deal with current like down below
233                 panic("Preemption not supported!");
234         }
235         /* If the process wasn't here, then we need to load its address space. */
236         if (p != current) {
237                 if (proc_incref(p)) {
238                         // getting here would mean someone tried killing this while we tried
239                         // to start one of it's contexts (from scratch, o/w we had it's CR3
240                         // loaded already)
241                         // if this happens, a no-op death-IPI ought to be on its way...  we can
242                         // just smp_idle()
243                         smp_idle();
244                 }
245                 lcr3(p->env_cr3);
246                 // we unloaded the old cr3, so decref it (if it exists)
247                 // TODO: Consider moving this to wherever we really "mean to leave the
248                 // process's context".
249                 if (current)
250                         proc_decref(current);
251                 set_cpu_curenv(p);
252         }
253         /* need to load our silly state, preferably somewhere other than here so we
254          * can avoid the case where the context was just running here.  it's not
255          * sufficient to do it in the "new process" if-block above (could be things
256          * like page faults that cause us to keep the same process, but want a
257          * different context.
258          * for now, we load this silly state here. (TODO) (HSS)
259          * We also need this to be per trapframe, and not per process...
260          */
261         env_pop_ancillary_state(p);
262         env_pop_tf(tf);
263 }
264
265 /*
266  * Destroys the given process.  This may be called from another process, a light
267  * kernel thread (no real process context), asynchronously/cross-core, or from
268  * the process on its own core.
269  *
270  * Here's the way process death works:
271  * 0. grab the lock (protects state transition and core map)
272  * 1. set state to dying.  that keeps the kernel from doing anything for the
273  * process (like proc_running it).
274  * 2. figure out where the process is running (cross-core/async or RUNNING_M)
275  * 3. IPI to clean up those cores (decref, etc).
276  * 4. Unlock
277  * 5. Clean up your core, if applicable
278  * (Last core/kernel thread to decref cleans up and deallocates resources.)
279  *
280  * Note that some cores can be processing async calls, but will eventually
281  * decref.  Should think about this more.
282  */
283 void proc_destroy(struct proc *p)
284 {
285         // Note this code relies on this lock disabling interrupts, similar to
286         // proc_run.
287         spin_lock_irqsave(&p->proc_lock);
288         switch (p->state) {
289                 case PROC_DYING:
290                         return; // someone else killed this already.
291                 case PROC_RUNNABLE_S:
292                 case PROC_RUNNABLE_M:
293                         // Think about other lists, like WAITING, or better ways to do this
294                         deschedule_proc(p);
295                         break;
296                 case PROC_RUNNING_S:
297                         #if 0
298                         // here's how to do it manually
299                         if (current == p) {
300                                 lcr3(boot_cr3);
301                                 proc_decref(p); // this decref is for the cr3
302                                 current = NULL;
303                         }
304                         #endif
305                         send_active_msg_sync(p->vcoremap[0], __death, (void *SNT)0,
306                                              (void *SNT)0, (void *SNT)0);
307                         #if 0
308                         /* right now, RUNNING_S only runs on a mgmt core (0), not cores
309                          * managed by the idlecoremap.  so don't do this yet. */
310                         spin_lock(&idle_lock);
311                         idlecoremap[num_idlecores++] = p->vcoremap[0];
312                         spin_unlock(&idle_lock);
313                         #endif
314                         break;
315                 case PROC_RUNNING_M:
316                         /* Send the DEATH message to every core running this process, and
317                          * deallocate the cores.
318                          * The rule is that the vcoremap is set before proc_run, and reset
319                          * within proc_destroy */
320                         spin_lock(&idle_lock);
321                         for (int i = 0; i < p->num_vcores; i++) {
322                                 send_active_msg_sync(p->vcoremap[i], __death, (void *SNT)0,
323                                                      (void *SNT)0, (void *SNT)0);
324                                 // give the pcore back to the idlecoremap
325                                 assert(num_idlecores < num_cpus); // sanity
326                                 idlecoremap[num_idlecores++] = p->vcoremap[i];
327                                 p->vcoremap[i] = 0; // TODO: might need a better signal
328                         }
329                         spin_unlock(&idle_lock);
330                         break;
331                 default:
332                         // TODO: getting here if it's already dead and free (ENV_FREE).
333                         // Need to sort reusing process structures and having pointers to
334                         // them floating around the system.
335                         panic("Weird state(0x%08x) in proc_destroy", p->state);
336         }
337         proc_set_state(p, PROC_DYING);
338
339         atomic_dec(&num_envs);
340         /* TODO: (REF) dirty hack.  decref currently uses a lock, but needs to use
341          * CAS instead (another lock would be slightly less ghetto).  but we need to
342          * decref before releasing the lock, since that could enable interrupts,
343          * which would have us receive the DEATH IPI if this was called locally by
344          * the target process. */
345         //proc_decref(p); // this decref is for the process in general
346         p->env_refcnt--;
347         size_t refcnt = p->env_refcnt; // need to copy this in so it's not reloaded
348
349         /* After unlocking, we can receive a DEATH IPI and clean up */
350         spin_unlock_irqsave(&p->proc_lock);
351
352         // coupled with the refcnt-- above, from decref.  if this happened,
353         // proc_destroy was called "remotely", and with no one else refcnting
354         if (!refcnt)
355                 env_free(p);
356
357         /* If we were running the process, we should have received an IPI by now.
358          * If not, odds are interrupts are disabled, which shouldn't happen while
359          * servicing syscalls. */
360         assert(current != p);
361         return;
362 }
363
364 /*
365  * The process refcnt is the number of places the process 'exists' in the
366  * system.  Creation counts as 1.  Having your page tables loaded somewhere
367  * (lcr3) counts as another 1.  A non-RUNNING_* process should have refcnt at
368  * least 1.  If the kernel is on another core and in a processes address space
369  * (like processing its backring), that counts as another 1.
370  *
371  * Note that the actual loading and unloading of cr3 is up to the caller, since
372  * that's not the only use for this (and decoupling is more flexible).
373  *
374  * The refcnt should always be greater than 0 for processes that aren't dying.
375  * When refcnt is 0, the process is dying and should not allow any more increfs.
376  * A process can be dying with a refcnt greater than 0, since it could be
377  * waiting for other cores to "get the message" to die, or a kernel core can be
378  * finishing work in the processes's address space.
379  *
380  * Implementation aside, the important thing is that we atomically increment
381  * only if it wasn't already 0.  If it was 0, then we shouldn't be attaching to
382  * the process, so we return an error, which should be handled however is
383  * appropriate.  We currently use spinlocks, but some sort of clever atomics
384  * would work too.
385  *
386  * Also, no one should ever update the refcnt outside of these functions.
387  * Eventually, we'll have Ivy support for this. (TODO)
388  *
389  * TODO: (REF) change to use CAS.
390  */
391 error_t proc_incref(struct proc *p)
392 {
393         error_t retval = 0;
394         spin_lock_irqsave(&p->proc_lock);
395         if (p->env_refcnt)
396                 p->env_refcnt++;
397         else
398                 retval = -EBADENV;
399         spin_unlock_irqsave(&p->proc_lock);
400         return retval;
401 }
402
403 /*
404  * When the kernel is done with a process, it decrements its reference count.
405  * When the count hits 0, no one is using it and it should be freed.
406  * "Last one out" actually finalizes the death of the process.  This is tightly
407  * coupled with the previous function (incref)
408  * Be sure to load a different cr3 before calling this!
409  *
410  * TODO: (REF) change to use CAS.  Note that when we do so, we may be holding
411  * the process lock when calling env_free().
412  */
413 void proc_decref(struct proc *p)
414 {
415         spin_lock_irqsave(&p->proc_lock);
416         p->env_refcnt--;
417         size_t refcnt = p->env_refcnt; // need to copy this in so it's not reloaded
418         spin_unlock_irqsave(&p->proc_lock);
419         // if we hit 0, no one else will increment and we can check outside the lock
420         if (!refcnt)
421                 env_free(p);
422 }
423
424 /* Active message handler to start a process's context on this core.  Tightly
425  * coupled with proc_run() */
426 #ifdef __IVY__
427 void __startcore(trapframe_t *tf, uint32_t srcid, struct proc *CT(1) a0,
428                  trapframe_t *CT(1) a1, void *SNT a2)
429 #else
430 void __startcore(trapframe_t *tf, uint32_t srcid, void * a0, void * a1,
431                  void * a2)
432 #endif
433 {
434         uint32_t coreid = core_id();
435         struct proc *p_to_run = (struct proc *CT(1))a0;
436         trapframe_t local_tf;
437         trapframe_t *tf_to_pop = (trapframe_t *CT(1))a1;
438
439         printk("Startcore on core %d\n", coreid);
440         assert(p_to_run);
441         // TODO: handle silly state (HSS)
442         if (!tf_to_pop) {
443                 tf_to_pop = &local_tf;
444                 memset(tf_to_pop, 0, sizeof(*tf_to_pop));
445                 proc_init_trapframe(tf_to_pop);
446                 // Note the init_tf sets tf_to_pop->tf_esp = USTACKTOP;
447                 proc_set_tfcoreid(tf_to_pop, (uint32_t)a2);
448                 proc_set_program_counter(tf_to_pop, p_to_run->env_entry);
449         }
450         proc_startcore(p_to_run, tf_to_pop);
451 }
452
453 /* Active message handler to stop running whatever context is on this core and
454  * to idle.  Note this leaves no trace of what was running.
455  * It's okay if death comes to a core that's already idling and has no current.
456  * It could happen if a process decref'd before proc_startcore could incref. */
457 void __death(trapframe_t *tf, uint32_t srcid, void *SNT a0, void *SNT a1,
458              void *SNT a2)
459 {
460         /* If we are currently running an address space on our core, we need a known
461          * good pgdir before releasing the old one.  This is currently the major
462          * practical implication of the kernel caring about a processes existence
463          * (the inc and decref).  This decref corresponds to the incref in
464          * proc_startcore (though it's not the only one). */
465         if (current) {
466                 lcr3(boot_cr3);
467                 proc_decref(current);
468                 set_cpu_curenv(NULL);
469         }
470         smp_idle();
471 }
472
473 void print_idlecoremap(void)
474 {
475         spin_lock(&idle_lock);
476         for (int i = 0; i < num_idlecores; i++)
477                 printk("idlecoremap[%d] = %d\n", i, idlecoremap[i]);
478         spin_unlock(&idle_lock);
479 }