The host needs to set up the virtqueue. This is an interim commit so suleiman can...
[akaros.git] / tests / prov.c
index 8b3ca32..cc2cc4f 100644 (file)
@@ -2,28 +2,38 @@
 #include <stdlib.h>
 #include <argp.h>
 
-#include <parlib.h>
-#include <vcore.h>
+#include <parlib/parlib.h>
+#include <parlib/vcore.h>
 
 const char *argp_program_version = "prov v0.1475263";
-const char *argp_program_bug_address = "<akaros@lists.eecs.berkeley.edu>";
+const char *argp_program_bug_address = "<akaros+subscribe@googlegroups.com>";
 
 static char doc[] = "prov -- control for provisioning resources";
-static char args_doc[] = "-p PID\nPROGRAM [ARGS]\n-- PROGRAM [ARGS]\n-s";
+static char args_doc[] = "-p PID\n-c PROGRAM [ARGS]\nPROGRAM [ARGS]\n"
+                         "-- PROGRAM [ARGS]\n-s";
 
 static struct argp_option options[] = {
        {"type",                't', "TYPE",0, "Type of resource to provision"},
-       {"Possible types:", 0, 0, OPTION_DOC, "c = cores\nm = ram"},
+       {"Possible types:", 0, 0, OPTION_DOC | OPTION_NO_USAGE, "c = cores\n"
+                                                               "m = ram"},
        {0, 0, 0, 0, "Call with exactly one of these, or with a program and args:"},
-       {"pid",                 'p', "PID",     0, "Pid of process to provision resources to"},
-       {"show",                's', 0,         0, "Show current resource provisioning"},
-       {"command",             'c', "PROG",0, "Launch a program and provision (alternate)"},
-       {0, 0, 0, OPTION_DOC, "If your command has arguments that conflict with prov, then put them after -- to keep prov from interpretting them."},
+       {"pid",                 'p', "PID",     OPTION_NO_USAGE, "Pid of process to provision "
+                                                    "resources to"},
+       {0, 0, 0, 0, ""},
+       {"command",             'c', "PROG",OPTION_NO_USAGE, "Launch a program and "
+                                                    "provision (alternate)"},
+       {0, 0, 0, 0, ""},
+       {"show",                's', 0,         OPTION_NO_USAGE, "Show current resource "
+                                                    "provisioning"},
+       {0, 0, 0, OPTION_DOC, "If your command has arguments that conflict with "
+                             "prov, then put them after -- to keep prov from "
+                             "interpretting them."},
        {0, 0, 0, 0, "Call with exactly one of these when changing a provision:"},
        {"value",               'v', "VAL",     0, "Type-specific value, passed to the kernel"},
        {"max",                 'm', 0,         0, "Provision all resources of the given type"},
-       {0, 0, 0, OPTION_DOC, "Cores are provisioned to processes, so the value is a specific pcore id.  To undo a core's provisioning, pass in pid=0."},
-
+       {0, 0, 0, OPTION_DOC, "Cores are provisioned to processes, so the value is "
+                             "a specific pcore id.  To undo a core's "
+                             "provisioning, pass in pid=0."},
        { 0 }
 };
 
@@ -115,26 +125,70 @@ static struct argp argp = {options, parse_opt, args_doc, doc};
 /* Used by both -p and -c modes (-c will use it after creating pid) */
 static int prov_pid(pid_t pid, struct prog_args *pargs)
 {
-       int retval = 0;
+       unsigned int kernel_res_type;
+       int retval;
        switch (pargs->res_type) {
                case ('c'):
                        if (pargs->max) {
                                /* TODO: don't guess the LL/CG layout and num pcores */
+                               #if 1
                                for (int i = 1; i < max_vcores() + 1; i++) {
-                                       if (retval = sys_provision(pid, RES_CORES, i)) {
+                                       if ((retval = sys_provision(pid, RES_CORES, i))) {
                                                perror("Failed max provisioning");
                                                return retval;
                                        }
                                }
+                               #else
+                               /* To force a vcore shuffle / least optimal ordering, change
+                                * the if 1 to 0.  Normally, we provision out in a predictable,
+                                * VCn->PCn+1 ordering.  This splits the odd and even VCs
+                                * across sockets on a 32 PC machine (c89).  This is only for
+                                * perf debugging, when using the lockprov.sh script. */
+                               retval = 0;
+                               retval |= sys_provision(pid, RES_CORES,  1);
+                               retval |= sys_provision(pid, RES_CORES, 16);
+                               retval |= sys_provision(pid, RES_CORES,  2);
+                               retval |= sys_provision(pid, RES_CORES, 17);
+                               retval |= sys_provision(pid, RES_CORES,  3);
+                               retval |= sys_provision(pid, RES_CORES, 18);
+                               retval |= sys_provision(pid, RES_CORES,  4);
+                               retval |= sys_provision(pid, RES_CORES, 19);
+                               retval |= sys_provision(pid, RES_CORES,  5);
+                               retval |= sys_provision(pid, RES_CORES, 20);
+                               retval |= sys_provision(pid, RES_CORES,  6);
+                               retval |= sys_provision(pid, RES_CORES, 21);
+                               retval |= sys_provision(pid, RES_CORES,  7);
+                               retval |= sys_provision(pid, RES_CORES, 22);
+                               retval |= sys_provision(pid, RES_CORES,  8);
+                               retval |= sys_provision(pid, RES_CORES, 23);
+                               retval |= sys_provision(pid, RES_CORES,  9);
+                               retval |= sys_provision(pid, RES_CORES, 24);
+                               retval |= sys_provision(pid, RES_CORES, 10);
+                               retval |= sys_provision(pid, RES_CORES, 25);
+                               retval |= sys_provision(pid, RES_CORES, 11);
+                               retval |= sys_provision(pid, RES_CORES, 26);
+                               retval |= sys_provision(pid, RES_CORES, 12);
+                               retval |= sys_provision(pid, RES_CORES, 27);
+                               retval |= sys_provision(pid, RES_CORES, 13);
+                               retval |= sys_provision(pid, RES_CORES, 28);
+                               retval |= sys_provision(pid, RES_CORES, 14);
+                               retval |= sys_provision(pid, RES_CORES, 29);
+                               retval |= sys_provision(pid, RES_CORES, 15);
+                               retval |= sys_provision(pid, RES_CORES, 31);
+                               retval |= sys_provision(pid, RES_CORES, 30);
+                               return retval;
+                               #endif
                        } else {
-                               if (retval = sys_provision(pid, RES_CORES, pargs->res_val)) {
+                               if ((retval = sys_provision(pid, RES_CORES, pargs->res_val))) {
                                        perror("Failed single provision");
                                        return retval;
                                }
                        }
+                       kernel_res_type = RES_CORES;
                        break;
                case ('m'):
                        printf("Provisioning memory is not supported yet\n");
+                       return -1;
                        break;
                default:
                        if (!pargs->res_type)
@@ -143,7 +197,8 @@ static int prov_pid(pid_t pid, struct prog_args *pargs)
                                printf("Unsupported resource type %c\n", pargs->res_type);
                        return -1;
        }
-       return retval;
+       sys_poke_ksched(pid, kernel_res_type);
+       return 0;
 }
 
 int main(int argc, char **argv)