]> xenbits.xensource.com Git - xen.git/commitdiff
xl: vcpu-pin command
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Apr 2010 05:54:51 +0000 (06:54 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 6 Apr 2010 05:54:51 +0000 (06:54 +0100)
Signed-off-by: Eric Chanudet <eric.chanudet@citrix.com>
Acked-by: Vincent Hanquez <vincent.hanquez@eu.citrix.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
tools/libxl/libxl.c
tools/libxl/libxl.h
tools/libxl/xl.c

index 4aa9b9bde4be8422156f534832871b4e6539ae46..80d4c68e35bc060330841f2d2c115520b8cebe63 100644 (file)
@@ -2233,6 +2233,7 @@ int libxl_get_physinfo(struct libxl_ctx *ctx, struct libxl_physinfo *physinfo)
     }
     physinfo->threads_per_core = xcphysinfo.threads_per_core;
     physinfo->cores_per_socket = xcphysinfo.cores_per_socket;
+    physinfo->max_cpu_id = xcphysinfo.max_cpu_id;
     physinfo->nr_cpus = xcphysinfo.nr_cpus;
     physinfo->cpu_khz = xcphysinfo.cpu_khz;
     physinfo->total_pages = xcphysinfo.total_pages;
@@ -2282,3 +2283,9 @@ struct libxl_vcpuinfo *libxl_list_vcpu(struct libxl_ctx *ctx, uint32_t domid,
     }
     return ret;
 }
+
+int libxl_set_vcpuaffinity(struct libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid,
+                           uint64_t *cpumap, int cpusize)
+{
+    return (xc_vcpu_setaffinity(ctx->xch, domid, vcpuid, cpumap, cpusize));
+}
index 64a4fbfd8ec1f913bf715c5ed17423fd44bec7e6..68da2c45864ff944ac734add3340a4c456f3a951 100644 (file)
@@ -374,6 +374,7 @@ struct libxl_physinfo {
     uint32_t threads_per_core;
     uint32_t cores_per_socket;
 
+    uint32_t max_cpu_id;
     uint32_t nr_cpus;
     uint32_t cpu_khz;
 
@@ -385,6 +386,7 @@ struct libxl_physinfo {
 int libxl_get_physinfo(struct libxl_ctx *ctx, struct libxl_physinfo *physinfo);
 struct libxl_vcpuinfo *libxl_list_vcpu(struct libxl_ctx *ctx, uint32_t domid,
                                        int *nb_vcpu, int *cpusize);
-
+int libxl_set_vcpuaffinity(struct libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid,
+                           uint64_t *cpumap, int cpusize);
 #endif /* LIBXL_H */
 
index da758fe2b03015657d7ee74c102e21b35d9a28d2..e57613ac7de299aca1e07ee3fdd2e5f8aab4cf6d 100644 (file)
@@ -877,6 +877,7 @@ static void help(char *command)
         printf(" mem-set                       set the current memory usage for a domain\n\n");
         printf(" button-press                  indicate an ACPI button press to the domain\n\n");
         printf(" vcpu-list                     list the VCPUs for all/some domains.\n\n");
+        printf(" vcpu-pin                      Set which CPUs a VCPU can use.\n\n");
     } else if(!strcmp(command, "create")) {
         printf("Usage: xl create <ConfigFile> [options] [vars]\n\n");
         printf("Create a domain based on <ConfigFile>.\n\n");
@@ -937,6 +938,9 @@ static void help(char *command)
     } else if (!strcmp(command, "vcpu-list")) {
         printf("Usage: xl vcpu-list [Domain, ...]\n\n");
         printf("List the VCPUs for all/some domains.\n\n");
+    } else if (!strcmp(command, "vcpu-pin")) {
+        printf("Usage: xl vcpu-pin <Domain> <VCPU|all> <CPUs|all>\n\n");
+        printf("Set which CPUs a VCPU can use.\n\n");
     }
 }
 
@@ -1863,6 +1867,119 @@ void main_vcpulist(int argc, char **argv)
     exit(0);
 }
 
+void vcpupin(char *d, const char *vcpu, char *cpu)
+{
+    struct libxl_ctx ctx;
+    struct libxl_vcpuinfo *vcpuinfo;
+    struct libxl_physinfo physinfo;
+    uint64_t *cpumap = NULL;
+
+    uint32_t domid, vcpuid, cpuida, cpuidb;
+    char *endptr, *toka, *tokb;
+    int i, nb_vcpu, cpusize;
+
+    vcpuid = strtoul(vcpu, &endptr, 10);
+    if (vcpu == endptr) {
+        if (strcmp(vcpu, "all")) {
+            fprintf(stderr, "Error: Invalid argument.\n");
+            return;
+        }
+        vcpuid = -1;
+    }
+
+    if (libxl_ctx_init(&ctx, LIBXL_VERSION)) {
+        fprintf(stderr, "cannot init xl context\n");
+        return;
+    }
+    libxl_ctx_set_log(&ctx, log_callback, NULL);
+
+    if (domain_qualifier_to_domid(&ctx, d, &domid) < 0) {
+        fprintf(stderr, "%s is an invalid domain identifier\n", d);
+        goto vcpupin_out1;
+    }
+    if (libxl_get_physinfo(&ctx, &physinfo) != 0) {
+        fprintf(stderr, "libxl_get_physinfo failed.\n");
+        goto vcpupin_out1;
+    }
+
+    cpumap = calloc(physinfo.max_cpu_id + 1, sizeof (uint64_t));
+    if (!cpumap) {
+        goto vcpupin_out1;
+    }
+    if (strcmp(cpu, "all")) {
+        for (toka = strtok(cpu, ","), i = 0; toka; toka = strtok(NULL, ","), ++i) {
+            cpuida = strtoul(toka, &endptr, 10);
+            if (toka == endptr) {
+                fprintf(stderr, "Error: Invalid argument.\n");
+                goto vcpupin_out;
+            }
+            if (*endptr == '-') {
+                tokb = endptr + 1;
+                cpuidb = strtoul(tokb, &endptr, 10);
+                if ((tokb == endptr) || (cpuida > cpuidb)) {
+                    fprintf(stderr, "Error: Invalid argument.\n");
+                    goto vcpupin_out;
+                }
+                while (cpuida <= cpuidb) {
+                    cpumap[cpuida / 64] |= (1 << (cpuida % 64));
+                    ++cpuida;
+                }
+            } else {
+                cpumap[cpuida / 64] |= (1 << (cpuida % 64));
+            }
+        }
+    }
+    else {
+        memset(cpumap, -1, sizeof (uint64_t) * (physinfo.max_cpu_id + 1));
+    }
+
+    if (vcpuid != -1) {
+        if (libxl_set_vcpuaffinity(&ctx, domid, vcpuid,
+                                   cpumap, physinfo.max_cpu_id + 1) == -1) {
+            fprintf(stderr, "Could not set affinity for vcpu `%u'.\n", vcpuid);
+        }
+    }
+    else {
+        if (!(vcpuinfo = libxl_list_vcpu(&ctx, domid, &nb_vcpu, &cpusize))) {
+            fprintf(stderr, "libxl_list_vcpu failed.\n");
+            goto vcpupin_out;
+        }
+        for (; nb_vcpu > 0; --nb_vcpu, ++vcpuinfo) {
+            if (libxl_set_vcpuaffinity(&ctx, domid, vcpuinfo->vcpuid,
+                                       cpumap, physinfo.max_cpu_id + 1) == -1) {
+                fprintf(stderr, "libxl_list_vcpu failed on vcpu `%u'.\n", vcpuinfo->vcpuid);
+            }
+        }
+    }
+  vcpupin_out1:
+    free(cpumap);
+  vcpupin_out:
+    libxl_ctx_free(&ctx);
+}
+
+int main_vcpupin(int argc, char **argv)
+{
+    int opt;
+
+    if (argc != 4) {
+        help("vcpu-pin");
+        exit(0);
+    }
+    while ((opt = getopt(argc, argv, "h")) != -1) {
+        switch (opt) {
+        case 'h':
+            help("vcpu-pin");
+            exit(0);
+        default:
+            fprintf(stderr, "option `%c' not supported.\n", opt);
+            break;
+        }
+    }
+
+    vcpupin(argv[1], argv[2] , argv[3]);
+    exit(0);
+}
+
 int main(int argc, char **argv)
 {
     if (argc < 2) {
@@ -1906,6 +2023,8 @@ int main(int argc, char **argv)
         main_button_press(argc - 1, argv + 1);
     } else if (!strcmp(argv[1], "vcpu-list")) {
         main_vcpulist(argc - 1, argv + 1);
+    } else if (!strcmp(argv[1], "vcpu-pin")) {
+        main_vcpupin(argc - 1, argv + 1);
     } else if (!strcmp(argv[1], "help")) {
         if (argc > 2)
             help(argv[2]);