printk: check for user pointers in format string parameters
[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 /* Provision a core to proc p. This code assumes that the scheduler that uses
12  * it holds a lock for the duration of the call. */
13 void __provision_core(struct proc *p, uint32_t pcoreid)
14 {
15         struct sched_pcore *spc = pcoreid2spc(pcoreid);
16         struct sched_pcore_tailq *prov_list;
17
18         /* If the core is already prov to someone else, take it away.  (last
19          * write wins, some other layer or new func can handle permissions). */
20         if (spc->prov_proc) {
21                 /* the list the spc is on depends on whether it is alloced to
22                  * the prov_proc or not */
23                 prov_list = spc->alloc_proc == spc->prov_proc ?
24                             &spc->prov_proc->ksched_data.crd.prov_alloc_me :
25                             &spc->prov_proc->ksched_data.crd.prov_not_alloc_me;
26                 TAILQ_REMOVE(prov_list, spc, prov_next);
27         }
28         /* Now prov it to p.  Again, the list it goes on depends on whether it
29          * is alloced to p or not.  Callers can also send in 0 to de-provision.
30          * */
31         if (p) {
32                 if (spc->alloc_proc == p) {
33                         TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
34                                           prov_next);
35                 } else {
36                         /* this is be the victim list, which can be sorted so
37                          * that we pick the right victim (sort by alloc_proc
38                          * reverse priority, etc). */
39                         TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_not_alloc_me,
40                                           spc, prov_next);
41                 }
42         }
43         spc->prov_proc = p;
44 }
45
46 /* Unprovisions any pcores for the given list */
47 static void __unprov_pcore_list(struct sched_pcore_tailq *list_head)
48 {
49         struct sched_pcore *spc_i;
50
51         /* We can leave them connected within the tailq, since the scps don't
52          * have a default list (if they aren't on a proc's list, then we don't
53          * care about them), and since the INSERTs don't care what list you were
54          * on before (chummy with the implementation).  Pretty sure this is
55          * right.  If there's suspected list corruption, be safer here. */
56         TAILQ_FOREACH(spc_i, list_head, prov_next)
57                 spc_i->prov_proc = 0;
58         TAILQ_INIT(list_head);
59 }
60
61 /* Unprovision all cores from proc p. This code assumes that the scheduler
62  * that uses * it holds a lock for the duration of the call. */
63 void __unprovision_all_cores(struct proc *p)
64 {
65         __unprov_pcore_list(&p->ksched_data.crd.prov_alloc_me);
66         __unprov_pcore_list(&p->ksched_data.crd.prov_not_alloc_me);
67 }
68
69 /* Print a list of the cores currently provisioned to p. */
70 void print_proc_coreprov(struct proc *p)
71 {
72         struct sched_pcore *spc_i;
73
74         if (!p)
75                 return;
76         print_lock();
77         printk("Prov cores alloced to proc %d (%p)\n----------\n", p->pid, p);
78         TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_alloc_me, prov_next)
79                 printk("Pcore %d\n", spc2pcoreid(spc_i));
80         printk("Prov cores not alloced to proc %d (%p)\n----------\n", p->pid,
81                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         print_unlock();
87 }
88
89 /* Print the processes attached to each provisioned core. */
90 void print_coreprov_map(void)
91 {
92         struct sched_pcore *spc_i;
93
94         /* Doing this without a scheduler lock, which is dangerous, but won't
95          * deadlock */
96         print_lock();
97         printk("Which cores are provisioned to which procs:\n--------------\n");
98         for (int i = 0; i < num_cores; i++) {
99                 spc_i = pcoreid2spc(i);
100                 printk("Core %02d, prov: %d(%p) alloc: %d(%p)\n", i,
101                        spc_i->prov_proc ? spc_i->prov_proc->pid : 0,
102                        spc_i->prov_proc,
103                        spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
104                        spc_i->alloc_proc);
105         }
106         print_unlock();
107 }