# HG changeset patch # User Juergen Gross # Date 1291890397 -3600 # Node ID 34367a3d42f7f8145bdc74c464f6822144aeab70 # Parent 823571e65b696b6fb3a00fa2b205ea8248f6d0df 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. libxl is extended with the following functions to support this feature: int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) Signed-off-by: juergen.gross@xxxxxxxxxxxxxx diff -r 823571e65b69 -r 34367a3d42f7 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Thu Dec 09 11:23:20 2010 +0100 +++ b/tools/libxl/libxl.c Thu Dec 09 11:26:37 2010 +0100 @@ -3822,6 +3822,38 @@ int libxl_cpupool_cpuadd(libxl_ctx *ctx, return 0; } +int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) +{ + int rc = 0; + int cpu; + libxl_cpumap freemap; + libxl_topologyinfo topology; + + if (libxl_get_freecpus(ctx, &freemap)) { + return ERROR_FAIL; + } + + if (libxl_get_topologyinfo(ctx, &topology)) { + rc = ERROR_FAIL; + goto out; + } + + *cpus = 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)) { + (*cpus)++; + } + } + + libxl_topologyinfo_destroy(&topology); + +out: + libxl_cpumap_destroy(&freemap); + return rc; +} + int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu) { int rc; @@ -3833,6 +3865,48 @@ int libxl_cpupool_cpuremove(libxl_ctx *c return ERROR_FAIL; } return 0; +} + +int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus) +{ + int ret = 0; + int n_pools; + int p; + int cpu; + libxl_topologyinfo topology; + libxl_cpupoolinfo *poolinfo; + + poolinfo = libxl_list_cpupool(ctx, &n_pools); + if (!poolinfo) { + return ERROR_NOMEM; + } + + if (libxl_get_topologyinfo(ctx, &topology)) { + ret = ERROR_FAIL; + goto out; + } + + *cpus = 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)) { + (*cpus)++; + } + } + } + } + + libxl_topologyinfo_destroy(&topology); + +out: + for (p = 0; p < n_pools; p++) { + libxl_cpupoolinfo_destroy(poolinfo + p); + } + + return ret; } int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid) diff -r 823571e65b69 -r 34367a3d42f7 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Thu Dec 09 11:23:20 2010 +0100 +++ b/tools/libxl/libxl.h Thu Dec 09 11:26:37 2010 +0100 @@ -525,7 +525,9 @@ int libxl_create_cpupool(libxl_ctx *ctx, uint32_t *poolid); int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid); int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu); +int libxl_cpupool_cpuadd_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus); int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu); +int libxl_cpupool_cpuremove_node(libxl_ctx *ctx, uint32_t poolid, int node, int *cpus); int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid); /* common paths */ diff -r 823571e65b69 -r 34367a3d42f7 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Dec 09 11:23:20 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Thu Dec 09 11:26:37 2010 +0100 @@ -5402,10 +5402,12 @@ int main_cpupoolcreate(int argc, char ** 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,32 @@ int main_cpupoolcreate(int argc, char ** 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; + if (libxl_get_topologyinfo(&ctx, &topology)) { + 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 +5725,8 @@ int main_cpupoolcpuadd(int argc, char ** const char *pool; uint32_t poolid; int cpu; + int node; + int n; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { @@ -5722,7 +5751,13 @@ int main_cpupoolcpuadd(int argc, char ** 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 +5765,21 @@ int main_cpupoolcpuadd(int argc, char ** return -ERROR_FAIL; } - return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); + if (cpu >= 0) { + return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); + } + + if (libxl_cpupool_cpuadd_node(&ctx, poolid, node, &n)) { + fprintf(stderr, "libxl_cpupool_cpuadd_node failed\n"); + return -ERROR_FAIL; + } + + if (n > 0) { + return 0; + } + + fprintf(stderr, "no free cpu found\n"); + return -ERROR_FAIL; } int main_cpupoolcpuremove(int argc, char **argv) @@ -5739,6 +5788,8 @@ int main_cpupoolcpuremove(int argc, char const char *pool; uint32_t poolid; int cpu; + int node; + int n; while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { @@ -5763,7 +5814,13 @@ int main_cpupoolcpuremove(int argc, char 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 +5828,21 @@ int main_cpupoolcpuremove(int argc, char return -ERROR_FAIL; } - return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); + if (cpu >= 0) { + return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); + } + + if (libxl_cpupool_cpuremove_node(&ctx, poolid, node, &n)) { + fprintf(stderr, "libxl_cpupool_cpuremove_node failed\n"); + return -ERROR_FAIL; + } + + if (n == 0) { + fprintf(stderr, "no cpu of node found in cpupool\n"); + return -ERROR_FAIL; + } + + return 0; } int main_cpupoolmigrate(int argc, char **argv) diff -r 823571e65b69 -r 34367a3d42f7 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Thu Dec 09 11:23:20 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Thu Dec 09 11:26:37 2010 +0100 @@ -361,12 +361,12 @@ struct cmd_spec cmd_table[] = { { "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,