[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH] xl: vcpu-pin command
This patch add vcpu-pin command to xl. Requires vcpu-list command patch for xl. Acked-by: Vincent Hanquez <vincent.hanquez@xxxxxxxxxxxxx> diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -2233,6 +2233,7 @@ int libxl_get_physinfo(struct libxl_ctx } 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(s } 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)); +} diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -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 */ diff --git a/tools/libxl/xl.c b/tools/libxl/xl.c --- a/tools/libxl/xl.c +++ b/tools/libxl/xl.c @@ -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: xm vcpu-list [Domain, ...]\n\n"); printf("List the VCPUs for all/some domains.\n\n"); + } else if (!strcmp(command, "vcpu-pin")) { + printf("Usage: xm 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]); -- Eric CHANUDET XenClient Team _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |