5 #include <parlib/parlib.h>
6 #include <parlib/vcore.h>
8 const char *argp_program_version = "prov v0.1475263";
9 const char *argp_program_bug_address = "<akaros@lists.eecs.berkeley.edu>";
11 static char doc[] = "prov -- control for provisioning resources";
12 static char args_doc[] = "-p PID\n-c PROGRAM [ARGS]\nPROGRAM [ARGS]\n"
13 "-- PROGRAM [ARGS]\n-s";
15 static struct argp_option options[] = {
16 {"type", 't', "TYPE",0, "Type of resource to provision"},
17 {"Possible types:", 0, 0, OPTION_DOC | OPTION_NO_USAGE, "c = cores\n"
19 {0, 0, 0, 0, "Call with exactly one of these, or with a program and args:"},
20 {"pid", 'p', "PID", OPTION_NO_USAGE, "Pid of process to provision "
23 {"command", 'c', "PROG",OPTION_NO_USAGE, "Launch a program and "
24 "provision (alternate)"},
26 {"show", 's', 0, OPTION_NO_USAGE, "Show current resource "
28 {0, 0, 0, OPTION_DOC, "If your command has arguments that conflict with "
29 "prov, then put them after -- to keep prov from "
30 "interpretting them."},
31 {0, 0, 0, 0, "Call with exactly one of these when changing a provision:"},
32 {"value", 'v', "VAL", 0, "Type-specific value, passed to the kernel"},
33 {"max", 'm', 0, 0, "Provision all resources of the given type"},
34 {0, 0, 0, OPTION_DOC, "Cores are provisioned to processes, so the value is "
35 "a specific pcore id. To undo a core's "
36 "provisioning, pass in pid=0."},
40 #define PROV_MODE_PID 1
41 #define PROV_MODE_CMD 2
42 #define PROV_MODE_SHOW 3
47 int mode; /* PROV_MODE_ETC */
49 char res_type; /* cores (c), ram (m), etc */
50 long res_val; /* type-specific value */
55 static error_t parse_opt (int key, char *arg, struct argp_state *state)
57 struct prog_args *pargs = state->input;
60 pargs->res_type = arg[0];
62 printf("Warning, extra letters detected for -t's argument\n");
66 printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
69 pargs->mode = PROV_MODE_PID;
70 pargs->pid = atoi(arg);
74 printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
77 pargs->mode = PROV_MODE_SHOW;
82 printf("Too many modes given (-p, -s, COMMAND, etc)\n\n");
85 pargs->mode = PROV_MODE_CMD;
87 /* Point to the next arg. We can also check state->arg_num, which
88 * is how many non-arpg arguments there are */
89 pargs->cmd_args = &state->argv[state->next];
90 /* Consume all args (it's done when next == argc) */
91 state->next = state->argc;
94 /* could also check to make sure we're not -s (and vice versa) */
95 if (pargs->dummy_val_flag) {
96 printf("Provide only -v or -m, not both\n\n");
99 pargs->dummy_val_flag = 1;
100 pargs->res_val = atol(arg);
103 if (pargs->dummy_val_flag) {
104 printf("Provide only -v or -m, not both\n\n");
107 pargs->dummy_val_flag = 1;
111 /* Make sure we selected a mode */
113 printf("No mode selected (-p, -s, etc).\n\n");
118 return ARGP_ERR_UNKNOWN;
123 static struct argp argp = {options, parse_opt, args_doc, doc};
125 /* Used by both -p and -c modes (-c will use it after creating pid) */
126 static int prov_pid(pid_t pid, struct prog_args *pargs)
128 unsigned int kernel_res_type;
130 switch (pargs->res_type) {
133 /* TODO: don't guess the LL/CG layout and num pcores */
135 for (int i = 1; i < max_vcores() + 1; i++) {
136 if ((retval = sys_provision(pid, RES_CORES, i))) {
137 perror("Failed max provisioning");
142 /* To force a vcore shuffle / least optimal ordering, change
143 * the if 1 to 0. Normally, we provision out in a predictable,
144 * VCn->PCn+1 ordering. This splits the odd and even VCs
145 * across sockets on a 32 PC machine (c89). This is only for
146 * perf debugging, when using the lockprov.sh script. */
148 retval |= sys_provision(pid, RES_CORES, 1);
149 retval |= sys_provision(pid, RES_CORES, 16);
150 retval |= sys_provision(pid, RES_CORES, 2);
151 retval |= sys_provision(pid, RES_CORES, 17);
152 retval |= sys_provision(pid, RES_CORES, 3);
153 retval |= sys_provision(pid, RES_CORES, 18);
154 retval |= sys_provision(pid, RES_CORES, 4);
155 retval |= sys_provision(pid, RES_CORES, 19);
156 retval |= sys_provision(pid, RES_CORES, 5);
157 retval |= sys_provision(pid, RES_CORES, 20);
158 retval |= sys_provision(pid, RES_CORES, 6);
159 retval |= sys_provision(pid, RES_CORES, 21);
160 retval |= sys_provision(pid, RES_CORES, 7);
161 retval |= sys_provision(pid, RES_CORES, 22);
162 retval |= sys_provision(pid, RES_CORES, 8);
163 retval |= sys_provision(pid, RES_CORES, 23);
164 retval |= sys_provision(pid, RES_CORES, 9);
165 retval |= sys_provision(pid, RES_CORES, 24);
166 retval |= sys_provision(pid, RES_CORES, 10);
167 retval |= sys_provision(pid, RES_CORES, 25);
168 retval |= sys_provision(pid, RES_CORES, 11);
169 retval |= sys_provision(pid, RES_CORES, 26);
170 retval |= sys_provision(pid, RES_CORES, 12);
171 retval |= sys_provision(pid, RES_CORES, 27);
172 retval |= sys_provision(pid, RES_CORES, 13);
173 retval |= sys_provision(pid, RES_CORES, 28);
174 retval |= sys_provision(pid, RES_CORES, 14);
175 retval |= sys_provision(pid, RES_CORES, 29);
176 retval |= sys_provision(pid, RES_CORES, 15);
177 retval |= sys_provision(pid, RES_CORES, 31);
178 retval |= sys_provision(pid, RES_CORES, 30);
182 if ((retval = sys_provision(pid, RES_CORES, pargs->res_val))) {
183 perror("Failed single provision");
187 kernel_res_type = RES_CORES;
190 printf("Provisioning memory is not supported yet\n");
194 if (!pargs->res_type)
195 printf("No resource type selected. Use -t\n");
197 printf("Unsupported resource type %c\n", pargs->res_type);
200 sys_poke_ksched(pid, kernel_res_type);
204 int main(int argc, char **argv)
207 struct prog_args pargs = {0};
209 argp_parse(&argp, argc, argv, 0, 0, &pargs);
211 switch (pargs.mode) {
212 case (PROV_MODE_PID):
213 return prov_pid(pargs.pid, &pargs);
215 case (PROV_MODE_CMD):
216 printf("Launching programs not supported yet\n");
217 printf("Would have launched %s with args:", pargs.cmd);
219 for (int i = 0; pargs.cmd_args[i]; i++)
220 printf(" %s", pargs.cmd_args[i]);
224 case (PROV_MODE_SHOW):
225 printf("Show mode not supported yet, using ghetto interface\n\n");
226 sys_provision(-1, 0, 0);