Move is_ll_core(), max_vcores() to corerequest.h
[akaros.git] / kern / include / corerequest.h
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 #pragma once
9
10 #include <stdbool.h>
11 #include <arch/topology.h>
12
13 /* The core request algorithm maintains an internal array of these: the
14  * global pcore map. Note the prov_proc and alloc_proc are weak (internal)
15  * references, and should only be used as a ref source while the ksched has a
16  * valid kref. */
17 struct sched_pcore {
18         TAILQ_ENTRY(sched_pcore)   prov_next;    /* on a proc's prov list */
19         TAILQ_ENTRY(sched_pcore)   alloc_next;   /* on an alloc list (idle)*/
20         struct proc                *prov_proc;   /* who this is prov to */
21         struct proc                *alloc_proc;  /* who this is alloc to */
22 };
23 TAILQ_HEAD(sched_pcore_tailq, sched_pcore);
24
25 struct core_request_data {
26         struct sched_pcore_tailq  prov_alloc_me;      /* prov cores alloced us */
27         struct sched_pcore_tailq  prov_not_alloc_me;  /* maybe alloc to others */
28 };
29
30 /* Initialize any data assocaited with doing core allocation. */
31 void corealloc_init(void);
32
33 /* Initialize any data associated with provisiong cores to a process. */
34 void coreprov_proc_init(struct proc *p);
35
36 /* Find the best core to allocate to a process as dictated by the core
37  * allocation algorithm. This code assumes that the scheduler that uses it
38  * holds a lock for the duration of the call. */
39 struct sched_pcore *__find_best_core_to_alloc(struct proc *p);
40
41 /* Track the pcore properly when it is allocated to p. This code assumes that
42  * the scheduler that uses it holds a lock for the duration of the call. */
43 void __track_core_alloc(struct proc *p, uint32_t pcoreid);
44
45 /* Track the pcore properly when it is deallocated from p. This code assumes
46  * that the scheduler that uses it holds a lock for the duration of the call.
47  * */
48 void __track_core_dealloc(struct proc *p, uint32_t pcoreid);
49
50 /* Bulk interface for __track_core_dealloc */
51 void __track_core_dealloc_bulk(struct proc *p, uint32_t *pc_arr,
52                                uint32_t nr_cores);
53
54 /* Get/Put an idle core from our pcore list and return its core_id. Don't
55  * consider the chosen core in the future when handing out cores to a
56  * process. This code assumes that the scheduler that uses it holds a lock
57  * for the duration of the call. This will not give out provisioned cores.
58  * The gets return the coreid on success, -1 or -error on failure. */
59 int __get_any_idle_core(void);
60 int __get_specific_idle_core(int coreid);
61 void __put_idle_core(int coreid);
62
63 /* One off functions to make 'pcoreid' the next core chosen by the core
64  * allocation algorithm (so long as no provisioned cores are still idle), and
65  * to sort the idle core list for debugging. This code assumes that the
66  * scheduler that uses it holds a lock for the duration of the call. */
67 void __next_core_to_alloc(uint32_t pcoreid);
68 void __sort_idle_cores(void);
69
70 /* Provision a core to proc p. This code assumes that the scheduler that uses
71  * it holds a lock for the duration of the call. */
72 void __provision_core(struct proc *p, struct sched_pcore *spc);
73
74 /* Unprovision all cores from proc p. This code assumes that the scheduler
75  * that uses * it holds a lock for the duration of the call. */
76 void __unprovision_all_cores(struct proc *p);
77
78 /* Print the map of idle cores that are still allocatable through our core
79  * allocation algorithm. */
80 void print_idle_core_map(void);
81
82 /* Print a list of the cores currently provisioned to p. */
83 void print_proc_coreprov(struct proc *p);
84
85 /* Print the processes attached to each provisioned core. */
86 void print_coreprov_map(void);
87
88 static inline uint32_t spc2pcoreid(struct sched_pcore *spc)
89 {
90         extern struct sched_pcore *all_pcores;
91
92         return spc - all_pcores;
93 }
94
95 static inline struct sched_pcore *pcoreid2spc(uint32_t pcoreid)
96 {
97         extern struct sched_pcore *all_pcores;
98
99         return &all_pcores[pcoreid];
100 }
101
102 static inline struct proc *get_alloc_proc(struct sched_pcore *c)
103 {
104         return c->alloc_proc;
105 }
106
107 static inline struct proc *get_prov_proc(struct sched_pcore *c)
108 {
109         return c->prov_proc;
110 }
111
112 /* TODO: need more thorough CG/LL management.  For now, core0 is the only LL
113  * core.  This won't play well with the ghetto shit in schedule_init() if you do
114  * anything like 'DEDICATED_MONITOR' or the ARSC server.  All that needs an
115  * overhaul. */
116 static inline bool is_ll_core(uint32_t pcoreid)
117 {
118         if (pcoreid == 0)
119                 return TRUE;
120         return FALSE;
121 }
122
123 /* Normally it'll be the max number of CG cores ever */
124 static inline uint32_t max_vcores(struct proc *p)
125 {
126 /* TODO: (CG/LL) */
127 #ifdef CONFIG_DISABLE_SMT
128         return num_cores >> 1;
129 #else
130         return num_cores - 1;   /* reserving core 0 */
131 #endif /* CONFIG_DISABLE_SMT */
132 }