Refactor to move prov stuff to coreprov.c (4/4)
[akaros.git] / kern / src / coreprov.c
1 /* Copyright (c) 2009, 2012, 2015 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * Valmon Leymarie <leymariv@berkeley.edu>
4  * Kevin Klues <klueska@cs.berkeley.edu>
5  * See LICENSE for details.
6  */
7
8 #include <env.h>
9 #include <schedule.h>
10
11 /* Initialize any data associated with provisiong cores to a process. */
12 void coreprov_proc_init(struct proc *p)
13 {
14         TAILQ_INIT(&p->ksched_data.crd.prov_alloc_me);
15         TAILQ_INIT(&p->ksched_data.crd.prov_not_alloc_me);
16 }
17
18 /* Provision a core to proc p. This code assumes that the scheduler that uses
19  * it holds a lock for the duration of the call. */
20 void __provision_core(struct proc *p, struct sched_pcore *spc)
21 {
22         struct sched_pcore_tailq *prov_list;
23         /* If the core is already prov to someone else, take it away.  (last write
24          * wins, some other layer or new func can handle permissions). */
25         if (spc->prov_proc) {
26                 /* the list the spc is on depends on whether it is alloced to the
27                  * prov_proc or not */
28                 prov_list = (spc->alloc_proc == spc->prov_proc ?
29                              &spc->prov_proc->ksched_data.crd.prov_alloc_me :
30                              &spc->prov_proc->ksched_data.crd.prov_not_alloc_me);
31                 TAILQ_REMOVE(prov_list, spc, prov_next);
32         }
33         /* Now prov it to p.  Again, the list it goes on depends on whether it is
34          * alloced to p or not.  Callers can also send in 0 to de-provision. */
35         if (p) {
36                 if (spc->alloc_proc == p) {
37                         TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
38                                           prov_next);
39                 } else {
40                         /* this is be the victim list, which can be sorted so that we pick
41                          * the right victim (sort by alloc_proc reverse priority, etc). */
42                         TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_not_alloc_me, spc,
43                                           prov_next);
44                 }
45         }
46         spc->prov_proc = p;
47 }
48
49 /* Unprovisions any pcores for the given list */
50 static void __unprov_pcore_list(struct sched_pcore_tailq *list_head)
51 {
52         struct sched_pcore *spc_i;
53         /* We can leave them connected within the tailq, since the scps don't have a
54          * default list (if they aren't on a proc's list, then we don't care about
55          * them), and since the INSERTs don't care what list you were on before
56          * (chummy with the implementation).  Pretty sure this is right.  If there's
57          * suspected list corruption, be safer here. */
58         TAILQ_FOREACH(spc_i, list_head, prov_next)
59                 spc_i->prov_proc = 0;
60         TAILQ_INIT(list_head);
61 }
62
63 /* Unprovision all cores from proc p. This code assumes that the scheduler
64  * that uses * it holds a lock for the duration of the call. */
65 void __unprovision_all_cores(struct proc *p)
66 {
67         __unprov_pcore_list(&p->ksched_data.crd.prov_alloc_me);
68         __unprov_pcore_list(&p->ksched_data.crd.prov_not_alloc_me);
69 }
70
71 /* Print a list of the cores currently provisioned to p. */
72 void print_proc_coreprov(struct proc *p)
73 {
74         struct sched_pcore *spc_i;
75
76         if (!p)
77                 return;
78         printk("Prov cores alloced to proc %d (%p)\n----------\n", p->pid, p);
79         TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_alloc_me, prov_next)
80                 printk("Pcore %d\n", spc2pcoreid(spc_i));
81         printk("Prov cores not alloced to proc %d (%p)\n----------\n", p->pid, p);
82         TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_not_alloc_me, prov_next)
83                 printk("Pcore %d (alloced to %d (%p))\n", spc2pcoreid(spc_i),
84                        spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
85                        spc_i->alloc_proc);
86 }
87
88 /* Print the processes attached to each provisioned core. */
89 void print_coreprov_map(void)
90 {
91         struct sched_pcore *spc_i;
92         /* Doing this unlocked, which is dangerous, but won't deadlock */
93         printk("Which cores are provisioned to which procs:\n------------------\n");
94         for (int i = 0; i < num_cores; i++) {
95                 spc_i = pcoreid2spc(i);
96                 printk("Core %02d, prov: %d(%p) alloc: %d(%p)\n", i,
97                        spc_i->prov_proc ? spc_i->prov_proc->pid : 0, spc_i->prov_proc,
98                        spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
99                        spc_i->alloc_proc);
100         }
101 }