# HG changeset patch # Parent d76603510485bbd69b30905599f2883bc0fb9b67 libxl: allow for specifying the CPU affinity in the config file. Enable CPU affinity specification in a VM's config file with the exact syntax `xl vcpu-pin' provides. Signed-off-by: Dario Faggioli diff -r d76603510485 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl.c Mon Jan 23 18:02:47 2012 +0000 @@ -2663,6 +2663,20 @@ int libxl_set_vcpuaffinity(libxl_ctx *ct return 0; } +int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, + unsigned int max_vcpus, libxl_cpumap *cpumap) +{ + int i, rc = 0; + + for (i = 0; i < max_vcpus; i++) { + if (libxl_set_vcpuaffinity(ctx, domid, i, cpumap)) { + LIBXL__LOG(ctx, LIBXL__LOG_WARNING, "no affinity for cpu %d", i); + rc = ERROR_FAIL; + } + } + return rc; +} + int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_cpumap *cpumap) { GC_INIT(ctx); diff -r d76603510485 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl.h Mon Jan 23 18:02:47 2012 +0000 @@ -560,6 +560,8 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct int *nb_vcpu, int *nrcpus); int libxl_set_vcpuaffinity(libxl_ctx *ctx, uint32_t domid, uint32_t vcpuid, libxl_cpumap *cpumap); +int libxl_set_vcpuaffinity_all(libxl_ctx *ctx, uint32_t domid, + unsigned int max_vcpus, libxl_cpumap *cpumap); int libxl_set_vcpuonline(libxl_ctx *ctx, uint32_t domid, libxl_cpumap *cpumap); int libxl_get_sched_id(libxl_ctx *ctx); diff -r d76603510485 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl_create.c Mon Jan 23 18:02:47 2012 +0000 @@ -71,6 +71,9 @@ int libxl_init_build_info(libxl_ctx *ctx memset(b_info, '\0', sizeof(*b_info)); b_info->max_vcpus = 1; b_info->cur_vcpus = 1; + if (libxl_cpumap_alloc(ctx, &b_info->cpumap)) + return ERROR_NOMEM; + libxl_cpumap_set_any(&b_info->cpumap); b_info->max_memkb = 32 * 1024; b_info->target_memkb = b_info->max_memkb; b_info->disable_migrate = 0; diff -r d76603510485 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl_dom.c Mon Jan 23 18:02:47 2012 +0000 @@ -65,6 +65,7 @@ int libxl__build_pre(libxl__gc *gc, uint libxl_ctx *ctx = libxl__gc_owner(gc); int tsc_mode; xc_domain_max_vcpus(ctx->xch, domid, info->max_vcpus); + libxl_set_vcpuaffinity_all(ctx, domid, info->max_vcpus, &info->cpumap); xc_domain_setmaxmem(ctx->xch, domid, info->target_memkb + LIBXL_MAXMEM_CONSTANT); if (info->type == LIBXL_DOMAIN_TYPE_PV) xc_domain_set_memmap_limit(ctx->xch, domid, diff -r d76603510485 tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl_types.idl Mon Jan 23 18:02:47 2012 +0000 @@ -162,6 +162,7 @@ libxl_domain_create_info = Struct("domai libxl_domain_build_info = Struct("domain_build_info",[ ("max_vcpus", integer), ("cur_vcpus", integer), + ("cpumap", libxl_cpumap), ("tsc_mode", libxl_tsc_mode), ("max_memkb", uint32), ("target_memkb", uint32), diff -r d76603510485 tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/libxl_utils.h Mon Jan 23 18:02:47 2012 +0000 @@ -70,6 +70,18 @@ int libxl_cpumap_alloc(libxl_ctx *ctx, l int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu); void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu); void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu); +static inline void libxl_cpumap_set_any(libxl_cpumap *cpumap) +{ + memset(cpumap->map, -1, cpumap->size); +} +static inline void libxl_cpumap_set_none(libxl_cpumap *cpumap) +{ + memset(cpumap->map, 0, cpumap->size); +} +static inline int libxl_cpumap_cpu_valid(libxl_cpumap *cpumap, int cpu) +{ + return cpu >= 0 && cpu < (cpumap->size * 8); +} #define libxl_for_each_cpu(var, map) for (var = 0; var < (map).size * 8; var++) #define libxl_for_each_set_cpu(v, m) for (v = 0; v < (m).size * 8; v++) \ if (libxl_cpumap_test(&(m), v)) diff -r d76603510485 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Mon Jan 23 18:02:42 2012 +0000 +++ b/tools/libxl/xl_cmdimpl.c Mon Jan 23 18:02:47 2012 +0000 @@ -288,16 +288,72 @@ static void dolog(const char *file, int libxl_write_exactly(NULL, logfile, s, rc, NULL, NULL); } +static void print_bitmap(uint8_t *map, int maplen, FILE *stream) +{ + int i; + uint8_t pmap = 0, bitmask = 0; + int firstset = 0, state = 0; + + for (i = 0; i < maplen; i++) { + if (i % 8 == 0) { + pmap = *map++; + bitmask = 1; + } else bitmask <<= 1; + + switch (state) { + case 0: + case 2: + if ((pmap & bitmask) != 0) { + firstset = i; + state++; + } + continue; + case 1: + case 3: + if ((pmap & bitmask) == 0) { + fprintf(stream, "%s%d", state > 1 ? "," : "", firstset); + if (i - 1 > firstset) + fprintf(stream, "-%d", i - 1); + state = 2; + } + continue; + } + } + switch (state) { + case 0: + fprintf(stream, "none"); + break; + case 2: + break; + case 1: + if (firstset == 0) { + fprintf(stream, "any cpu"); + break; + } + case 3: + fprintf(stream, "%s%d", state > 1 ? "," : "", firstset); + if (i - 1 > firstset) + fprintf(stream, "-%d", i - 1); + break; + } +} + static void printf_info(int domid, libxl_domain_config *d_config, libxl_device_model_info *dm_info) { - int i; + int i, nr_cpus = -1; libxl_dominfo info; + libxl_physinfo physinfo; libxl_domain_create_info *c_info = &d_config->c_info; libxl_domain_build_info *b_info = &d_config->b_info; + if (libxl_get_physinfo(ctx, &physinfo) == 0) + nr_cpus = physinfo.nr_cpus; + else + fprintf(stderr, "libxl_physinfo failed.\n"); + printf("(domain\n\t(domid %d)\n", domid); printf("\t(create_info)\n"); printf("\t(hvm %d)\n", c_info->type == LIBXL_DOMAIN_TYPE_HVM); @@ -328,6 +384,9 @@ static void printf_info(int domid, printf("\t(build_info)\n"); printf("\t(max_vcpus %d)\n", b_info->max_vcpus); + printf("\t(CPU affinity "); + print_bitmap(b_info->cpumap.map, nr_cpus, stdout); + printf(")\n"); printf("\t(tsc_mode %s)\n", libxl_tsc_mode_to_string(b_info->tsc_mode)); printf("\t(max_memkb %d)\n", b_info->max_memkb); printf("\t(target_memkb %d)\n", b_info->target_memkb); @@ -569,6 +628,8 @@ static void split_string_into_string_lis free(s); } +static int vcpupin_parse(char *cpu, libxl_cpumap *cpumap); + static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len, @@ -578,7 +639,7 @@ static void parse_config_data(const char const char *buf; long l; XLU_Config *config; - XLU_ConfigList *vbds, *nics, *pcis, *cvfbs, *cpuids; + XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids; int pci_power_mgmt = 0; int pci_msitranslate = 1; int e; @@ -661,6 +722,29 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "maxvcpus", &l, 0)) b_info->max_vcpus = l; + if (!xlu_cfg_get_list (config, "cpus", &cpus, 0, 1)) { + int i, n_cpus = 0; + + libxl_cpumap_set_none(&b_info->cpumap); + while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) { + i = atoi(buf); + if (!libxl_cpumap_cpu_valid(&b_info->cpumap, i)) { + fprintf(stderr, "cpu %d illegal\n", i); + exit(1); + } + libxl_cpumap_set(&b_info->cpumap, i); + n_cpus++; + } + } + else if (!xlu_cfg_get_string (config, "cpus", &buf, 0)) { + char *buf2 = strdup(buf); + + libxl_cpumap_set_none(&b_info->cpumap); + if (vcpupin_parse(buf2, &b_info->cpumap)) + exit(1); + free(buf2); + } + if (!xlu_cfg_get_long (config, "memory", &l, 0)) { b_info->max_memkb = l * 1024; b_info->target_memkb = b_info->max_memkb; @@ -3357,56 +3441,6 @@ int main_button_press(int argc, char **a return 0; } -static void print_bitmap(uint8_t *map, int maplen, FILE *stream) -{ - int i; - uint8_t pmap = 0, bitmask = 0; - int firstset = 0, state = 0; - - for (i = 0; i < maplen; i++) { - if (i % 8 == 0) { - pmap = *map++; - bitmask = 1; - } else bitmask <<= 1; - - switch (state) { - case 0: - case 2: - if ((pmap & bitmask) != 0) { - firstset = i; - state++; - } - continue; - case 1: - case 3: - if ((pmap & bitmask) == 0) { - fprintf(stream, "%s%d", state > 1 ? "," : "", firstset); - if (i - 1 > firstset) - fprintf(stream, "-%d", i - 1); - state = 2; - } - continue; - } - } - switch (state) { - case 0: - fprintf(stream, "none"); - break; - case 2: - break; - case 1: - if (firstset == 0) { - fprintf(stream, "any cpu"); - break; - } - case 3: - fprintf(stream, "%s%d", state > 1 ? "," : "", firstset); - if (i - 1 > firstset) - fprintf(stream, "-%d", i - 1); - break; - } -} - static void print_vcpuinfo(uint32_t tdomid, const libxl_vcpuinfo *vcpuinfo, uint32_t nr_cpus) @@ -3511,7 +3545,7 @@ static int vcpupin_parse(char *cpu, libx int i, ret = 0; if (!strcmp(cpu, "all")) { - memset(cpumap->map, -1, cpumap->size); + libxl_cpumap_set_any(cpumap); return 0; }