# HG changeset patch # User Juergen Gross # Date 1290685192 -3600 # Node ID d3880bd8b4674e0ec88dfa380347de9045a4b533 # Parent 37dc5cb8c5857d7ffa3e3572d6d4090478b8cebc Extend cpupools to support numa The user interfaces for cpupools are extended to support numa machines: - xl cpupool-create supports now specifying a node list instead of a cpu list. The new cpupool will be created with all free cpus of the specified numa nodes. - xl cpupool-cpu-remove and xl cpupool-cpu-add can take a node number instead of a cpu number. Using 'node:1' for the cpu parameter will, depending on the operation, either remove all cpus of node 1 in the specified cpupool, or add all free cpus of node 1 to the cpupool. Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 37dc5cb8c585 -r d3880bd8b467 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Nov 25 09:32:49 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Thu Nov 25 12:39:52 2010 +0100 @@ -5402,10 +5402,12 @@ uint32_t poolid; int schedid = -1; XLU_ConfigList *cpus; - int n_cpus, i, n; + XLU_ConfigList *nodes; + int n_cpus, n_nodes, i, n; libxl_cpumap freemap; libxl_cpumap cpumap; libxl_uuid uuid; + libxl_topologyinfo *topology; while (1) { opt = getopt_long(argc, argv, "hnf:", long_options, &option_index); @@ -5514,7 +5516,31 @@ fprintf(stderr, "Failed to allocate cpumap\n"); return -ERROR_FAIL; } - if (!xlu_cfg_get_list(config, "cpus", &cpus, 0, 0)) { + if (!xlu_cfg_get_list(config, "nodes", &nodes, 0, 0)) { + n_cpus = 0; + n_nodes = 0; + topology = libxl_get_topologyinfo(&ctx); + if (topology == NULL) { + fprintf(stderr, "libxl_get_topologyinfo failed\n"); + return -ERROR_FAIL; + } + while ((buf = xlu_cfg_get_listitem(nodes, n_nodes)) != NULL) { + n = atoi(buf); + for (i = 0; i < topology->nodemap.entries; i++) { + if ((topology->nodemap.array[i] == n) && + libxl_cpumap_test(&freemap, i)) { + libxl_cpumap_set(&cpumap, i); + n_cpus++; + } + } + n_nodes++; + } + libxl_topologyinfo_destroy(topology); + if (n_cpus == 0) { + fprintf(stderr, "no free cpu found\n"); + return -ERROR_FAIL; + } + } else if (!xlu_cfg_get_list(config, "cpus", &cpus, 0, 0)) { n_cpus = 0; while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) { i = atoi(buf); @@ -5698,6 +5724,10 @@ const char *pool; uint32_t poolid; int cpu; + int node; + int n; + libxl_cpumap freemap; + libxl_topologyinfo *topology; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { @@ -5722,7 +5752,13 @@ help("cpupool-cpu-add"); return -ERROR_FAIL; } - cpu = atoi(argv[optind]); + node = -1; + cpu = -1; + if (strncmp(argv[optind], "node:", 5) == 0) { + node = atoi(argv[optind] + 5); + } else { + cpu = atoi(argv[optind]); + } if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || !libxl_cpupoolid_to_name(&ctx, poolid)) { @@ -5730,7 +5766,38 @@ return -ERROR_FAIL; } - return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); + if (cpu >= 0) { + return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); + } + + if (libxl_get_freecpus(&ctx, &freemap)) { + fprintf(stderr, "libxl_get_freecpus failed\n"); + return -ERROR_FAIL; + } + + topology = libxl_get_topologyinfo(&ctx); + if (topology == NULL) { + fprintf(stderr, "libxl_get_topologyinfo failed\n"); + return -ERROR_FAIL; + } + + n = 0; + for (cpu = 0; cpu < topology->nodemap.entries; cpu++) { + if (libxl_cpumap_test(&freemap, cpu) && + (topology->nodemap.array[cpu] == node) && + !libxl_cpupool_cpuadd(&ctx, poolid, cpu)) { + n++; + } + } + + libxl_topologyinfo_destroy(topology); + + if (n > 0) { + return 0; + } + + fprintf(stderr, "no free cpu found\n"); + return -ERROR_FAIL; } int main_cpupoolcpuremove(int argc, char **argv) @@ -5739,6 +5806,13 @@ const char *pool; uint32_t poolid; int cpu; + int node; + int n; + int ret; + int p; + int n_pools; + libxl_topologyinfo *topology; + libxl_cpupoolinfo *poolinfo; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { @@ -5763,7 +5837,13 @@ help("cpupool-cpu-remove"); return -ERROR_FAIL; } - cpu = atoi(argv[optind]); + node = -1; + cpu = -1; + if (strncmp(argv[optind], "node:", 5) == 0) { + node = atoi(argv[optind] + 5); + } else { + cpu = atoi(argv[optind]); + } if (cpupool_qualifier_to_cpupoolid(pool, &poolid, NULL) || !libxl_cpupoolid_to_name(&ctx, poolid)) { @@ -5771,7 +5851,51 @@ return -ERROR_FAIL; } - return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); + if (cpu >= 0) { + return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); + } + + ret = 0; + + poolinfo = libxl_list_cpupool(&ctx, &n_pools); + if (!poolinfo) { + fprintf(stderr, "error getting cpupool info\n"); + return -ERROR_NOMEM; + } + + topology = libxl_get_topologyinfo(&ctx); + if (topology == NULL) { + fprintf(stderr, "libxl_get_topologyinfo failed\n"); + ret = -ERROR_FAIL; + goto out; + } + + n = 0; + for (p = 0; p < n_pools; p++) { + if (poolinfo[p].poolid == poolid) { + for (cpu = 0; cpu < topology->nodemap.entries; cpu++) { + if ((topology->nodemap.array[cpu] == node) && + libxl_cpumap_test(&poolinfo[p].cpumap, cpu) && + !libxl_cpupool_cpuremove(&ctx, poolid, cpu)) { + n++; + } + } + } + } + + libxl_topologyinfo_destroy(topology); + + if (n == 0) { + fprintf(stderr, "no cpu of node found in cpupool\n"); + ret = -ERROR_FAIL; + } + +out: + for (p = 0; p < n_pools; p++) { + libxl_cpupoolinfo_destroy(poolinfo + p); + } + + return ret; } int main_cpupoolmigrate(int argc, char **argv) diff -r 37dc5cb8c585 -r d3880bd8b467 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Thu Nov 25 09:32:49 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Thu Nov 25 12:39:52 2010 +0100 @@ -361,12 +361,12 @@ { "cpupool-cpu-add", &main_cpupoolcpuadd, "Adds a CPU to a CPU pool", - " ", + " |node:", }, { "cpupool-cpu-remove", &main_cpupoolcpuremove, "Removes a CPU from a CPU pool", - " ", + " |node:", }, { "cpupool-migrate", &main_cpupoolmigrate,