* [Patch] support of cpu pools in xl
@ 2010-09-17 6:10 Juergen Gross
2010-09-17 9:46 ` Ian Campbell
0 siblings, 1 reply; 11+ messages in thread
From: Juergen Gross @ 2010-09-17 6:10 UTC (permalink / raw)
To: xen-devel@lists.xensource.com, Ian Campbell
[-- Attachment #1: Type: text/plain, Size: 693 bytes --]
Hi,
attached patch adds support of cpu pools in xl/libxl.
Ian, I didn't split up this patch, because the updated libxl_cpumask structure
requires changes to xl in any case.
BTW: I realized that libxlu_cfg_l.c seems to be in the repository. Isn't this
file generated by make? I think it should be removed there.
Juergen
--
Juergen Gross Principal Developer Operating Systems
TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967
Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com
Domagkstr. 28 Internet: ts.fujitsu.com
D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html
[-- Attachment #2: cpupools-xl.patch --]
[-- Type: text/x-patch, Size: 32574 bytes --]
Signed-off-by: juergen.gross@ts.fujitsu.com
Support of cpu pools in xl:
library functions
xl pool-create
xl pool-list
xl pool-destroy
xl pool-cpu-add
xl pool-cpu-remove
xl pool-migrate
diff -r d978675f3d53 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.c Fri Sep 17 07:42:30 2010 +0200
@@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c
libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool)
{
libxl_poolinfo *ptr;
- int i, ret;
- xc_cpupoolinfo_t info[256];
- int size = 256;
+ int i, m;
+ xc_cpupoolinfo_t *info;
+ int size;
+ uint32_t poolid;
+ libxl_physinfo physinfo;
+
+ if (libxl_get_physinfo(ctx, &physinfo) != 0) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info");
+ return NULL;
+ }
+ size = physinfo.max_cpu_id + 32;
ptr = calloc(size, sizeof(libxl_poolinfo));
if (!ptr) {
@@ -619,16 +627,23 @@ libxl_poolinfo * libxl_list_pool(libxl_c
return NULL;
}
- ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info);
- if (ret<0) {
- LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info");
- return NULL;
+ poolid = 0;
+ for (i = 0; i < size; i++) {
+ info = xc_cpupool_getinfo(ctx->xch, poolid);
+ if (info == NULL)
+ break;
+ ptr[i].poolid = info->cpupool_id;
+ ptr[i].sched_id = info->sched_id;
+ ptr[i].n_dom = info->n_dom;
+ if (libxl_cpumap_alloc(&ptr[i].cpumap, physinfo.max_cpu_id + 1))
+ break;
+ for (m = 0; m < ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++)
+ ptr[i].cpumap.map[m] = info->cpumap[m];
+ poolid = info->cpupool_id + 1;
+ free(info);
}
- for (i = 0; i < ret; i++) {
- ptr[i].poolid = info[i].cpupool_id;
- }
- *nb_pool = ret;
+ *nb_pool = i;
return ptr;
}
@@ -2928,7 +2943,6 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
xc_domaininfo_t domaininfo;
xc_vcpuinfo_t vcpuinfo;
xc_physinfo_t physinfo = { 0 };
- unsigned num_cpuwords;
if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist");
@@ -2944,10 +2958,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
return NULL;
}
- num_cpuwords = ((physinfo.max_cpu_id + 64) / 64);
for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) {
- ptr->cpumap = malloc(num_cpuwords * sizeof(*ptr->cpumap));
- if (!ptr->cpumap) {
+ if (libxl_cpumap_alloc(&ptr->cpumap, *nrcpus)) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpumap");
return NULL;
}
if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) {
@@ -2955,7 +2968,7 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct
return NULL;
}
if (xc_vcpu_getaffinity(ctx->xch, domid, *nb_vcpu,
- ptr->cpumap, ((*nrcpus) + 7) / 8) == -1) {
+ ptr->cpumap.map, ((*nrcpus) + 7) / 8) == -1) {
LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting vcpu affinity");
return NULL;
}
@@ -3359,3 +3372,180 @@ void libxl_file_reference_destroy(libxl_
libxl__file_reference_unmap(f);
free(f->path);
}
+
+int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap)
+{
+ libxl_physinfo info;
+ int ret;
+
+ if (libxl_get_physinfo(ctx, &info) != 0)
+ return ERROR_FAIL;
+
+ ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1);
+ if (ret)
+ return ret;
+
+ if (xc_cpupool_freeinfo(ctx->xch, cpumap->map, cpumap->size)) {
+ free(cpumap->map);
+ cpumap->map = NULL;
+ return ERROR_FAIL;
+ }
+
+ return 0;
+}
+
+int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid,
+ libxl_cpumap cpumap, libxl_uuid *uuid,
+ uint32_t *poolid)
+{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
+ int rc;
+ int i;
+ xs_transaction_t t;
+ char *uuid_string;
+
+ uuid_string = libxl__uuid2string(&gc, *uuid);
+ if (!uuid_string)
+ return ERROR_NOMEM;
+
+ rc = xc_cpupool_create(ctx->xch, poolid, schedid);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Could not create cpupool");
+ return ERROR_FAIL;
+ }
+
+ for (i = 0; i < cpumap.size * 8; i++)
+ if (cpumap.map[i / 64] & (1L << (i % 64))) {
+ rc = xc_cpupool_addcpu(ctx->xch, *poolid, i);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Error moving cpu to cpupool");
+ return ERROR_FAIL;
+ }
+ }
+
+ for (;;) {
+ t = xs_transaction_start(ctx->xsh);
+
+ xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/pool/%d", *poolid));
+ libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/uuid", *poolid),
+ uuid_string);
+ libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/name", *poolid),
+ name);
+
+ if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
+ return 0;
+ }
+}
+
+int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid)
+{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
+ int rc, i;
+ xc_cpupoolinfo_t *info;
+ xs_transaction_t t;
+
+ info = xc_cpupool_getinfo(ctx->xch, poolid);
+ if (info == NULL)
+ return ERROR_NOMEM;
+
+ rc = ERROR_INVAL;
+ if ((info->cpupool_id != poolid) || (info->n_dom))
+ goto out;
+
+ for (i = 0; i < info->cpumap_size; i++)
+ if (info->cpumap[i / 64] & (1L << (i % 64))) {
+ rc = xc_cpupool_removecpu(ctx->xch, poolid, i);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Error removing cpu from cpupool");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ }
+
+ rc = xc_cpupool_destroy(ctx->xch, poolid);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "Could not destroy cpupool");
+ rc = ERROR_FAIL;
+ goto out;
+ }
+
+ for (;;) {
+ t = xs_transaction_start(ctx->xsh);
+
+ xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/pool/%d", poolid));
+
+ if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
+ break;
+ }
+
+ rc = 0;
+
+out:
+ free(info);
+
+ return rc;
+}
+
+int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu)
+{
+ int rc;
+
+ rc = xc_cpupool_addcpu(ctx->xch, poolid, cpu);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Error moving cpu to cpupool");
+ return ERROR_FAIL;
+ }
+ return 0;
+}
+
+int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu)
+{
+ int rc;
+
+ rc = xc_cpupool_removecpu(ctx->xch, poolid, cpu);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Error removing cpu from cpupool");
+ return ERROR_FAIL;
+ }
+ return 0;
+}
+
+int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid)
+{
+ libxl__gc gc = LIBXL_INIT_GC(ctx);
+ int rc;
+ char *dom_path;
+ char *vm_path;
+ char *poolname;
+ xs_transaction_t t;
+
+ dom_path = libxl__xs_get_dompath(&gc, domid);
+ if (!dom_path) {
+ return ERROR_FAIL;
+ }
+
+ rc = xc_cpupool_movedomain(ctx->xch, poolid, domid);
+ if (rc) {
+ LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc,
+ "Error moving domain to cpupool");
+ return ERROR_FAIL;
+ }
+
+ poolname = libxl__poolid_to_name(&gc, poolid);
+ vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path));
+ for (; vm_path;) {
+ t = xs_transaction_start(ctx->xsh);
+
+ libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), poolname);
+
+ if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN))
+ break;
+ }
+
+ return 0;
+}
diff -r d978675f3d53 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.h Fri Sep 17 07:42:30 2010 +0200
@@ -140,8 +140,6 @@ void libxl_string_list_destroy(libxl_str
typedef char **libxl_key_value_list;
void libxl_key_value_list_destroy(libxl_key_value_list *kvl);
-
-typedef uint64_t *libxl_cpumap;
typedef uint32_t libxl_hwcap[8];
@@ -488,6 +486,15 @@ int libxl_device_net2_del(libxl_ctx *ctx
int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2,
int wait);
+int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap);
+int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid,
+ libxl_cpumap cpumap, libxl_uuid *uuid,
+ 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_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu);
+int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid);
+
/* common paths */
const char *libxl_sbindir_path(void);
const char *libxl_bindir_path(void);
diff -r d978675f3d53 tools/libxl/libxl.idl
--- a/tools/libxl/libxl.idl Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl.idl Fri Sep 17 07:42:30 2010 +0200
@@ -16,8 +16,6 @@ libxl_string_list = Builtin("string_list
libxl_string_list = Builtin("string_list", destructor_fn="libxl_string_list_destroy", passby=PASS_BY_REFERENCE)
libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE)
libxl_file_reference = Builtin("file_reference", destructor_fn="libxl_file_reference_destroy", passby=PASS_BY_REFERENCE)
-
-libxl_cpumap = Builtin("cpumap", destructor_fn="free")
libxl_hwcap = Builtin("hwcap")
@@ -44,9 +42,17 @@ SHUTDOWN_* constant."""),
("vcpu_online", uint32),
], destructor_fn=None)
+libxl_cpumap = Struct("cpumap", [
+ ("size", uint32, False, "number of bytes in map"),
+ ("map", Reference(uint64)),
+ ])
+
libxl_poolinfo = Struct("poolinfo", [
- ("poolid", uint32)
- ], destructor_fn=None)
+ ("poolid", uint32),
+ ("sched_id", uint32),
+ ("n_dom", uint32),
+ ("cpumap", libxl_cpumap)
+ ], destructor_fn="libxl_poolinfo_destroy")
libxl_vminfo = Struct("vminfo", [
("uuid", libxl_uuid),
diff -r d978675f3d53 tools/libxl/libxl_utils.c
--- a/tools/libxl/libxl_utils.c Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl_utils.c Fri Sep 17 07:42:30 2010 +0200
@@ -31,6 +31,17 @@
#include "libxl_utils.h"
#include "libxl_internal.h"
+struct schedid_name {
+ char *name;
+ int id;
+};
+
+static struct schedid_name schedid_name[] = {
+ { "credit", XEN_SCHEDULER_CREDIT },
+ { "sedf", XEN_SCHEDULER_SEDF },
+ { "credit2", XEN_SCHEDULER_CREDIT2 },
+ { NULL, -1 }
+};
unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus)
{
@@ -124,19 +135,41 @@ int libxl_name_to_poolid(libxl_ctx *ctx,
return ERROR_NOMEM;
for (i = 0; i < nb_pools; i++) {
- poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid);
- if (!poolname)
- continue;
- if (strcmp(poolname, name) == 0) {
- *poolid = poolinfo[i].poolid;
- ret = 0;
+ if (ret && ((poolname = libxl_poolid_to_name(ctx,
+ poolinfo[i].poolid)) != NULL)) {
+ if (strcmp(poolname, name) == 0) {
+ *poolid = poolinfo[i].poolid;
+ ret = 0;
+ free(poolname);
+ }
free(poolname);
- break;
}
- free(poolname);
+ libxl_poolinfo_destroy(poolinfo + i);
}
free(poolinfo);
return ret;
+}
+
+int libxl_name_to_schedid(libxl_ctx *ctx, const char *name)
+{
+ int i;
+
+ for (i = 0; schedid_name[i].name != NULL; i++)
+ if (strcmp(name, schedid_name[i].name) == 0)
+ return schedid_name[i].id;
+
+ return -1;
+}
+
+char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid)
+{
+ int i;
+
+ for (i = 0; schedid_name[i].name != NULL; i++)
+ if (schedid_name[i].id == schedid)
+ return schedid_name[i].name;
+
+ return "unknown";
}
int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid)
@@ -675,3 +708,36 @@ out:
libxl__free_all(&gc);
return rc;
}
+
+int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus)
+{
+ int elems;
+
+ elems = (max_cpus + 63) / 64;
+ cpumap->map = calloc(elems, sizeof(*cpumap->map));
+ if (!cpumap->map)
+ return ERROR_NOMEM;
+ cpumap->size = elems * 8; /* size in bytes */
+ return 0;
+}
+
+int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu)
+{
+ if (cpu >= cpumap->size * 8)
+ return 0;
+ return (cpumap->map[cpu / 64] & (1L << (cpu & 63))) ? 1 : 0;
+}
+
+void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu)
+{
+ if (cpu >= cpumap->size * 8)
+ return;
+ cpumap->map[cpu / 64] |= 1L << (cpu & 63);
+}
+
+void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu)
+{
+ if (cpu >= cpumap->size * 8)
+ return;
+ cpumap->map[cpu / 64] &= ~(1L << (cpu & 63));
+}
diff -r d978675f3d53 tools/libxl/libxl_utils.h
--- a/tools/libxl/libxl_utils.h Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxl_utils.h Fri Sep 17 07:42:30 2010 +0200
@@ -23,6 +23,8 @@ char *libxl_domid_to_name(libxl_ctx *ctx
char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid);
int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid);
char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid);
+int libxl_name_to_schedid(libxl_ctx *ctx, const char *name);
+char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid);
int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid);
int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid);
int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name);
@@ -74,5 +76,9 @@ int libxl_devid_to_device_net2(libxl_ctx
* return -1 if there are an error */
int libxl_check_device_model_version(libxl_ctx *ctx, char *path);
+int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus);
+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);
#endif
diff -r d978675f3d53 tools/libxl/libxltypes.py
--- a/tools/libxl/libxltypes.py Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/libxltypes.py Fri Sep 17 07:42:30 2010 +0200
@@ -131,7 +131,10 @@ class Reference(Type):
kwargs.setdefault('passby', PASS_BY_VALUE)
kwargs.setdefault('namespace', ty.namespace)
- typename = ty.typename[len(kwargs['namespace']):]
+
+ typename = ty.typename
+ if ty.namespace:
+ typename = typename[len(kwargs['namespace']):]
Type.__init__(self, typename + " *", **kwargs)
#
diff -r d978675f3d53 tools/libxl/xl.h
--- a/tools/libxl/xl.h Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl.h Fri Sep 17 07:42:30 2010 +0200
@@ -79,6 +79,12 @@ int main_network2attach(int argc, char *
int main_network2attach(int argc, char **argv);
int main_network2list(int argc, char **argv);
int main_network2detach(int argc, char **argv);
+int main_poolcreate(int argc, char **argv);
+int main_poollist(int argc, char **argv);
+int main_pooldestroy(int argc, char **argv);
+int main_poolcpuadd(int argc, char **argv);
+int main_poolcpuremove(int argc, char **argv);
+int main_poolmigrate(int argc, char **argv);
void help(char *command);
diff -r d978675f3d53 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c Fri Sep 17 07:42:30 2010 +0200
@@ -421,7 +421,7 @@ static void printf_info(int domid,
printf("\t(ssidref %d)\n", c_info->ssidref);
printf("\t(name %s)\n", c_info->name);
printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(c_info->uuid));
- printf("\t(cpupool %s (%d))\n", c_info->poolname, c_info->poolid);
+ printf("\t(cpupool %s)\n", c_info->poolname);
if (c_info->xsdata)
printf("\t(xsdata contains data)\n");
else
@@ -3287,7 +3287,7 @@ static void print_vcpuinfo(uint32_t tdom
printf("%9.1f ", ((float)vcpuinfo->vcpu_time / 1e9));
/* CPU AFFINITY */
pcpumap = nr_cpus > 64 ? (uint64_t)-1 : ((1ULL << nr_cpus) - 1);
- for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
+ for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) {
if (*cpumap < pcpumap) {
break;
}
@@ -3302,7 +3302,7 @@ static void print_vcpuinfo(uint32_t tdom
if (!nr_cpus) {
printf("any cpu\n");
} else {
- for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) {
+ for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) {
pcpumap = *cpumap;
for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1)
;
@@ -3574,10 +3574,7 @@ static void output_xeninfo(void)
printf("xen_minor : %d\n", info->xen_version_minor);
printf("xen_extra : %s\n", info->xen_version_extra);
printf("xen_caps : %s\n", info->capabilities);
- printf("xen_scheduler : %s\n",
- sched_id == XEN_SCHEDULER_SEDF ? "sedf" :
- sched_id == XEN_SCHEDULER_CREDIT ? "credit" :
- sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown");
+ printf("xen_scheduler : %s\n", libxl_schedid_to_name(&ctx, sched_id));
printf("xen_pagesize : %lu\n", info->pagesize);
printf("platform_params : virt_start=0x%lx\n", info->virt_start);
printf("xen_changeset : %s\n", info->changeset);
@@ -3608,6 +3605,8 @@ static void output_physinfo(void)
libxl_physinfo info;
const libxl_version_info *vinfo;
unsigned int i;
+ libxl_cpumap cpumap;
+ int n = 0;
if (libxl_get_physinfo(&ctx, &info) != 0) {
fprintf(stderr, "libxl_physinfo failed.\n");
@@ -3634,6 +3633,13 @@ static void output_physinfo(void)
printf("total_memory : %"PRIu64"\n", info.total_pages / i);
printf("free_memory : %"PRIu64"\n", info.free_pages / i);
}
+ if (!libxl_get_freecpus(&ctx, &cpumap)) {
+ for (i = 0; i < cpumap.size * 8; i++)
+ if (libxl_cpumap_test(&cpumap, i))
+ n++;
+ printf("free_cpus : %d\n", n);
+ free(cpumap.map);
+ }
return;
}
@@ -5049,3 +5055,444 @@ int main_tmem_freeable(int argc, char **
printf("%d\n", mb);
return 0;
}
+
+int main_poolcreate(int argc, char **argv)
+{
+ char *filename = NULL;
+ char *p, extra_config[1024];
+ int dryrun = 0;
+ int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"defconfig", 1, 0, 'f'},
+ {"dryrun", 0, 0, 'n'},
+ {0, 0, 0, 0}
+ };
+ int ret;
+ void *config_data = 0;
+ int config_len = 0;
+ XLU_Config *config;
+ const char *buf;
+ char *name, *sched;
+ uint32_t poolid;
+ int schedid = -1;
+ XLU_ConfigList *cpus;
+ int n_cpus, i, n;
+ libxl_cpumap freemap;
+ libxl_cpumap cpumap;
+ libxl_uuid uuid;
+
+ while (1) {
+ opt = getopt_long(argc, argv, "hnf:", long_options, &option_index);
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'f':
+ filename = optarg;
+ break;
+ case 'h':
+ help("pool-create");
+ return 0;
+ case 'n':
+ dryrun = 1;
+ break;
+ default:
+ fprintf(stderr, "option not supported\n");
+ break;
+ }
+ }
+
+ memset(extra_config, 0, sizeof(extra_config));
+ while (optind < argc) {
+ if ((p = strchr(argv[optind], '='))) {
+ if (strlen(extra_config) + 1 < sizeof(extra_config)) {
+ if (strlen(extra_config))
+ strcat(extra_config, "\n");
+ strcat(extra_config, argv[optind]);
+ }
+ } else if (!filename) {
+ filename = argv[optind];
+ } else {
+ help("pool-create");
+ return -ERROR_FAIL;
+ }
+ optind++;
+ }
+
+ if (!filename) {
+ help("pool-create");
+ return -ERROR_FAIL;
+ }
+
+ if (libxl_read_file_contents(&ctx, filename, &config_data, &config_len)) {
+ fprintf(stderr, "Failed to read config file: %s: %s\n",
+ filename, strerror(errno));
+ return -ERROR_FAIL;
+ }
+ if (strlen(extra_config)) {
+ if (config_len > INT_MAX - (strlen(extra_config) + 2)) {
+ fprintf(stderr, "Failed to attach extra configration\n");
+ return -ERROR_FAIL;
+ }
+ config_data = realloc(config_data,
+ config_len + strlen(extra_config) + 2);
+ if (!config_data) {
+ fprintf(stderr, "Failed to realloc config_data\n");
+ return -ERROR_FAIL;
+ }
+ strcat(config_data, "\n");
+ strcat(config_data, extra_config);
+ strcat(config_data, "\n");
+ config_len += (strlen(extra_config) + 2);
+ }
+
+ config = xlu_cfg_init(stderr, filename);
+ if (!config) {
+ fprintf(stderr, "Failed to allocate for configuration\n");
+ return -ERROR_FAIL;
+ }
+
+ ret = xlu_cfg_readdata(config, config_data, config_len);
+ if (ret) {
+ fprintf(stderr, "Failed to parse config file: %s\n", strerror(ret));
+ return -ERROR_FAIL;
+ }
+
+ if (!xlu_cfg_get_string (config, "name", &buf))
+ name = strdup(buf);
+ else
+ name = basename(filename);
+ if (!libxl_name_to_poolid(&ctx, name, &poolid)) {
+ fprintf(stderr, "Pool name \"%s\" already exists\n", name);
+ return -ERROR_FAIL;
+ }
+
+ if (!xlu_cfg_get_string (config, "sched", &buf)) {
+ if ((schedid = libxl_name_to_schedid(&ctx, buf)) < 0) {
+ fprintf(stderr, "Unknown scheduler\n");
+ return -ERROR_FAIL;
+ }
+ } else {
+ if ((schedid = libxl_get_sched_id(&ctx)) < 0) {
+ fprintf(stderr, "get_sched_id sysctl failed.\n");
+ return -ERROR_FAIL;
+ }
+ }
+ sched = libxl_schedid_to_name(&ctx, schedid);
+
+ if (libxl_get_freecpus(&ctx, &freemap)) {
+ fprintf(stderr, "libxl_get_freecpus failed\n");
+ return -ERROR_FAIL;
+ }
+ if (libxl_cpumap_alloc(&cpumap, freemap.size * 8)) {
+ fprintf(stderr, "Failed to allocate cpumap\n");
+ return -ERROR_FAIL;
+ }
+ if (!xlu_cfg_get_list(config, "cpus", &cpus, 0)) {
+ n_cpus = 0;
+ while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) {
+ i = atoi(buf);
+ if ((i < 0) || (i >= freemap.size * 8) ||
+ !libxl_cpumap_test(&freemap, i)) {
+ fprintf(stderr, "cpu %d illegal or not free\n", i);
+ return -ERROR_FAIL;
+ }
+ libxl_cpumap_set(&cpumap, i);
+ n_cpus++;
+ }
+ } else {
+ n_cpus = 1;
+ n = 0;
+ for (i = 0; i < freemap.size; i++)
+ if (libxl_cpumap_test(&freemap, i)) {
+ n++;
+ libxl_cpumap_set(&cpumap, i);
+ break;
+ }
+ if (n != n_cpus) {
+ fprintf(stderr, "no free cpu found\n");
+ return -ERROR_FAIL;
+ }
+ }
+
+ libxl_uuid_generate(&uuid);
+
+ printf("Using config file \"%s\"\n", filename);
+ printf("pool name: %s\n", name);
+ printf("scheduler: %s\n", sched);
+ printf("number of cpus: %d\n", n_cpus);
+
+ if (dryrun)
+ return 0;
+
+ poolid = 0;
+ if (libxl_create_cpupool(&ctx, name, schedid, cpumap, &uuid, &poolid)) {
+ fprintf(stderr, "error on creating cpupool\n");
+ return -ERROR_FAIL;
+ }
+
+ return 0;
+}
+
+int main_poollist(int argc, char **argv)
+{
+ int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"help", 0, 0, 'h'},
+ {"long", 0, 0, 'l'},
+ {"cpus", 0, 0, 'c'},
+ {0, 0, 0, 0}
+ };
+ int opt_long = 0;
+ int opt_cpus = 0;
+ char *pool = NULL;
+ libxl_poolinfo *poolinfo;
+ int n_pools, p, c, n;
+ uint32_t poolid;
+ char *name;
+ int ret = 0;
+
+ while (1) {
+ opt = getopt_long(argc, argv, "hlc", long_options, &option_index);
+ if (opt == -1)
+ break;
+
+ switch (opt) {
+ case 'h':
+ help("pool-list");
+ return 0;
+ case 'l':
+ opt_long = 1;
+ break;
+ case 'c':
+ opt_cpus = 1;
+ break;
+ default:
+ fprintf(stderr, "option not supported\n");
+ break;
+ }
+ }
+
+ if ((optind + 1) < argc) {
+ help("pool-list");
+ return -ERROR_FAIL;
+ }
+ if (optind < argc) {
+ pool = argv[optind];
+ if (libxl_name_to_poolid(&ctx, pool, &poolid)) {
+ fprintf(stderr, "Pool \'%s\' does not exist\n", pool);
+ return -ERROR_FAIL;
+ }
+ }
+
+ poolinfo = libxl_list_pool(&ctx, &n_pools);
+ if (!poolinfo) {
+ fprintf(stderr, "error getting cpupool info\n");
+ return -ERROR_NOMEM;
+ }
+
+ if (!opt_long) {
+ printf("%-19s", "Name");
+ if (opt_cpus)
+ printf("CPU list\n");
+ else
+ printf("CPUs Sched Active Domain count\n");
+ }
+
+ for (p = 0; p < n_pools; p++) {
+ if (!ret && (!pool || (poolinfo[p].poolid != poolid))) {
+ name = libxl_poolid_to_name(&ctx, poolinfo[p].poolid);
+ if (!name) {
+ fprintf(stderr, "error getting cpupool info\n");
+ ret = -ERROR_NOMEM;
+ }
+ else if (opt_long) {
+ ret = -ERROR_NI;
+ } else {
+ printf("%-19s", name);
+ n = 0;
+ for (c = 0; c < poolinfo[p].cpumap.size * 8; c++)
+ if (poolinfo[p].cpumap.map[c / 64] & (1L << (c % 64))) {
+ if (n && opt_cpus) printf(",");
+ if (opt_cpus) printf("%d", c);
+ n++;
+ }
+ if (!opt_cpus) {
+ printf("%3d %9s y %4d", n,
+ libxl_schedid_to_name(&ctx, poolinfo[p].sched_id),
+ poolinfo[p].n_dom);
+ }
+ printf("\n");
+ }
+ }
+ libxl_poolinfo_destroy(poolinfo + p);
+ }
+
+ return ret;
+}
+
+int main_pooldestroy(int argc, char **argv)
+{
+ int opt;
+ char *pool;
+ uint32_t poolid;
+
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ help("pool-destroy");
+ return 0;
+ default:
+ fprintf(stderr, "option `%c' not supported.\n", opt);
+ break;
+ }
+ }
+
+ pool = argv[optind];
+ if (!pool) {
+ fprintf(stderr, "no cpupool specified\n");
+ help("pool-destroy");
+ return -ERROR_FAIL;
+ }
+
+ if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+ !libxl_poolid_to_name(&ctx, poolid)) {
+ fprintf(stderr, "unknown pool \'%s\'\n", pool);
+ return -ERROR_FAIL;
+ }
+
+ return -libxl_destroy_cpupool(&ctx, poolid);
+}
+
+int main_poolcpuadd(int argc, char **argv)
+{
+ int opt;
+ char *pool;
+ uint32_t poolid;
+ int cpu;
+
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ help("pool-cpu-add");
+ return 0;
+ default:
+ fprintf(stderr, "option `%c' not supported.\n", opt);
+ break;
+ }
+ }
+
+ pool = argv[optind++];
+ if (!pool) {
+ fprintf(stderr, "no cpupool specified\n");
+ help("pool-cpu-add");
+ return -ERROR_FAIL;
+ }
+
+ if (!argv[optind]) {
+ fprintf(stderr, "no cpu specified\n");
+ help("pool-cpu-add");
+ return -ERROR_FAIL;
+ }
+ cpu = atoi(argv[optind]);
+
+ if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+ !libxl_poolid_to_name(&ctx, poolid)) {
+ fprintf(stderr, "unknown pool \'%s\'\n", pool);
+ return -ERROR_FAIL;
+ }
+
+ return -libxl_cpupool_cpuadd(&ctx, poolid, cpu);
+}
+
+int main_poolcpuremove(int argc, char **argv)
+{
+ int opt;
+ char *pool;
+ uint32_t poolid;
+ int cpu;
+
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ help("pool-cpu-remove");
+ return 0;
+ default:
+ fprintf(stderr, "option `%c' not supported.\n", opt);
+ break;
+ }
+ }
+
+ pool = argv[optind++];
+ if (!pool) {
+ fprintf(stderr, "no cpupool specified\n");
+ help("pool-cpu-remove");
+ return -ERROR_FAIL;
+ }
+
+ if (!argv[optind]) {
+ fprintf(stderr, "no cpu specified\n");
+ help("pool-cpu-remove");
+ return -ERROR_FAIL;
+ }
+ cpu = atoi(argv[optind]);
+
+ if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+ !libxl_poolid_to_name(&ctx, poolid)) {
+ fprintf(stderr, "unknown pool \'%s\'\n", pool);
+ return -ERROR_FAIL;
+ }
+
+ return -libxl_cpupool_cpuremove(&ctx, poolid, cpu);
+}
+
+int main_poolmigrate(int argc, char **argv)
+{
+ int opt;
+ char *pool;
+ uint32_t poolid;
+ char *dom;
+ uint32_t domid;
+
+ while ((opt = getopt(argc, argv, "h")) != -1) {
+ switch (opt) {
+ case 'h':
+ help("pool-migrate");
+ return 0;
+ default:
+ fprintf(stderr, "option `%c' not supported.\n", opt);
+ break;
+ }
+ }
+
+ dom = argv[optind++];
+ if (!dom) {
+ fprintf(stderr, "no domain specified\n");
+ help("pool-migrate");
+ return -ERROR_FAIL;
+ }
+
+ pool = argv[optind++];
+ if (!pool) {
+ fprintf(stderr, "no cpupool specified\n");
+ help("pool-migrate");
+ return -ERROR_FAIL;
+ }
+
+ if (domain_qualifier_to_domid(dom, &domid, NULL) ||
+ !libxl_domid_to_name(&ctx, domid)) {
+ fprintf(stderr, "unknown domain \'%s\'\n", dom);
+ return -ERROR_FAIL;
+ }
+
+ if (pool_qualifier_to_poolid(pool, &poolid, NULL) ||
+ !libxl_poolid_to_name(&ctx, poolid)) {
+ fprintf(stderr, "unknown pool \'%s\'\n", pool);
+ return -ERROR_FAIL;
+ }
+
+ return -libxl_cpupool_movedomain(&ctx, poolid, domid);
+}
diff -r d978675f3d53 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c Thu Sep 16 18:29:26 2010 +0100
+++ b/tools/libxl/xl_cmdtable.c Fri Sep 17 07:42:30 2010 +0200
@@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = {
"destroy a domain's version 2 virtual network device",
"<Domain> <DevId>",
},
+ { "pool-create",
+ &main_poolcreate,
+ "Create a CPU pool based an ConfigFile",
+ "[options] <ConfigFile> [vars]",
+ "-h, --help Print this help.\n"
+ "-f=FILE, --defconfig=FILE Use the given configuration file.\n"
+ "-n, --dryrun Dry run - prints the resulting configuration."
+ },
+ { "pool-list",
+ &main_poollist,
+ "List CPU pools on host",
+ "[-l|--long] [-c|--cpus] [<CPU Pool>]",
+ "-l, --long Output all CPU pool details.\n"
+ "-c, --cpus Output list of CPUs used by a pool"
+ },
+ { "pool-destroy",
+ &main_pooldestroy,
+ "Deactivates a CPU pool",
+ "<CPU Pool>",
+ },
+ { "pool-cpu-add",
+ &main_poolcpuadd,
+ "Adds a CPU to a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-cpu-remove",
+ &main_poolcpuremove,
+ "Removes a CPU from a CPU pool",
+ "<CPU Pool> <CPU nr>",
+ },
+ { "pool-migrate",
+ &main_poolmigrate,
+ "Moves a domain into a CPU pool",
+ "<Domain> <CPU Pool>",
+ },
};
int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec);
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
^ permalink raw reply [flat|nested] 11+ messages in thread* Re: [Patch] support of cpu pools in xl 2010-09-17 6:10 [Patch] support of cpu pools in xl Juergen Gross @ 2010-09-17 9:46 ` Ian Campbell 2010-09-17 11:41 ` Juergen Gross 0 siblings, 1 reply; 11+ messages in thread From: Ian Campbell @ 2010-09-17 9:46 UTC (permalink / raw) To: Juergen Gross; +Cc: xen-devel@lists.xensource.com > On Fri, 2010-09-17 at 07:10 +0100, Juergen Gross wrote: > > attached patch adds support of cpu pools in xl/libxl. > Ian, I didn't split up this patch, because the updated libxl_cpumask > structure requires changes to xl in any case. That's fine. > BTW: I realized that libxlu_cfg_l.c seems to be in the repository. > Isn't this file generated by make? I think it should be removed there. In an ideal world, yes. I think this was a workaround for buggy versions of flex observed in the field or something. > Signed-off-by: juergen.gross@ts.fujitsu.com > > Support of cpu pools in xl: > library functions > xl pool-create > xl pool-list > xl pool-destroy > xl pool-cpu-add > xl pool-cpu-remove > xl pool-migrate > > diff -r d978675f3d53 tools/libxl/libxl.c > --- a/tools/libxl/libxl.c Thu Sep 16 18:29:26 2010 +0100 > +++ b/tools/libxl/libxl.c Fri Sep 17 07:42:30 2010 +0200 > @@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c > libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) > { > libxl_poolinfo *ptr; > - int i, ret; > - xc_cpupoolinfo_t info[256]; > - int size = 256; > + int i, m; > + xc_cpupoolinfo_t *info; > + int size; > + uint32_t poolid; > + libxl_physinfo physinfo; > + > + if (libxl_get_physinfo(ctx, &physinfo) != 0) { > + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info"); > + return NULL; > + } > + size = physinfo.max_cpu_id + 32; Where does the number 32 come from? > ptr = calloc(size, sizeof(libxl_poolinfo)); > if (!ptr) { > @@ -619,16 +627,23 @@ libxl_poolinfo * libxl_list_pool(libxl_c > return NULL; > } > > - ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info); > - if (ret<0) { > - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info"); > - return NULL; > + poolid = 0; > + for (i = 0; i < size; i++) { > + info = xc_cpupool_getinfo(ctx->xch, poolid); > + if (info == NULL) > + break; > + ptr[i].poolid = info->cpupool_id; > + ptr[i].sched_id = info->sched_id; > + ptr[i].n_dom = info->n_dom; > + if (libxl_cpumap_alloc(&ptr[i].cpumap, physinfo.max_cpu_id + 1)) > + break; > + for (m = 0; m < ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++) > + ptr[i].cpumap.map[m] = info->cpumap[m]; I guess if "physinfo.max_cpu_id + 1" does not correspond to info->cpumap_size then that is a serious error but if it does happen then you may run over the end of either ptr[i].cpumap.map or info->cpumap. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 9:46 ` Ian Campbell @ 2010-09-17 11:41 ` Juergen Gross 2010-09-17 11:55 ` Ian Campbell 2010-09-17 15:55 ` Ian Jackson 0 siblings, 2 replies; 11+ messages in thread From: Juergen Gross @ 2010-09-17 11:41 UTC (permalink / raw) To: Ian Campbell; +Cc: xen-devel@lists.xensource.com [-- Attachment #1: Type: text/plain, Size: 3328 bytes --] On 09/17/10 11:46, Ian Campbell wrote: > >> On Fri, 2010-09-17 at 07:10 +0100, Juergen Gross wrote: >> >> attached patch adds support of cpu pools in xl/libxl. >> Ian, I didn't split up this patch, because the updated libxl_cpumask >> structure requires changes to xl in any case. > > That's fine. > >> BTW: I realized that libxlu_cfg_l.c seems to be in the repository. >> Isn't this file generated by make? I think it should be removed there. > > In an ideal world, yes. I think this was a workaround for buggy versions > of flex observed in the field or something. How nice ;-) > >> Signed-off-by: juergen.gross@ts.fujitsu.com >> >> Support of cpu pools in xl: >> library functions >> xl pool-create >> xl pool-list >> xl pool-destroy >> xl pool-cpu-add >> xl pool-cpu-remove >> xl pool-migrate >> >> diff -r d978675f3d53 tools/libxl/libxl.c >> --- a/tools/libxl/libxl.c Thu Sep 16 18:29:26 2010 +0100 >> +++ b/tools/libxl/libxl.c Fri Sep 17 07:42:30 2010 +0200 >> @@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c >> libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) >> { >> libxl_poolinfo *ptr; >> - int i, ret; >> - xc_cpupoolinfo_t info[256]; >> - int size = 256; >> + int i, m; >> + xc_cpupoolinfo_t *info; >> + int size; >> + uint32_t poolid; >> + libxl_physinfo physinfo; >> + >> + if (libxl_get_physinfo(ctx,&physinfo) != 0) { >> + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info"); >> + return NULL; >> + } >> + size = physinfo.max_cpu_id + 32; > > Where does the number 32 come from? I just wanted to be able to support some (inactive) cpupools without any cpu allocated. It's just a number which should normally be large enough. > >> ptr = calloc(size, sizeof(libxl_poolinfo)); > >> if (!ptr) { >> @@ -619,16 +627,23 @@ libxl_poolinfo * libxl_list_pool(libxl_c >> return NULL; >> } >> >> - ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info); >> - if (ret<0) { >> - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info"); >> - return NULL; >> + poolid = 0; >> + for (i = 0; i< size; i++) { >> + info = xc_cpupool_getinfo(ctx->xch, poolid); >> + if (info == NULL) >> + break; >> + ptr[i].poolid = info->cpupool_id; >> + ptr[i].sched_id = info->sched_id; >> + ptr[i].n_dom = info->n_dom; >> + if (libxl_cpumap_alloc(&ptr[i].cpumap, physinfo.max_cpu_id + 1)) >> + break; >> + for (m = 0; m< ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++) >> + ptr[i].cpumap.map[m] = info->cpumap[m]; > > I guess if "physinfo.max_cpu_id + 1" does not correspond to > info->cpumap_size then that is a serious error but if it does happen > then you may run over the end of either ptr[i].cpumap.map or > info->cpumap. Changed (introducing '0' when info->cpumap_size is too small). Juergen -- Juergen Gross Principal Developer Operating Systems TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967 Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com Domagkstr. 28 Internet: ts.fujitsu.com D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html [-- Attachment #2: cpupools-xl.patch --] [-- Type: text/x-patch, Size: 37539 bytes --] Signed-off-by: juergen.gross@ts.fujitsu.com Support of cpu pools in xl: library functions xl pool-create xl pool-list xl pool-destroy xl pool-cpu-add xl pool-cpu-remove xl pool-migrate diff -r d978675f3d53 tools/libxl/libxl.c --- a/tools/libxl/libxl.c Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxl.c Fri Sep 17 13:26:13 2010 +0200 @@ -609,9 +609,17 @@ libxl_poolinfo * libxl_list_pool(libxl_c libxl_poolinfo * libxl_list_pool(libxl_ctx *ctx, int *nb_pool) { libxl_poolinfo *ptr; - int i, ret; - xc_cpupoolinfo_t info[256]; - int size = 256; + int i, m; + xc_cpupoolinfo_t *info; + int size; + uint32_t poolid; + libxl_physinfo physinfo; + + if (libxl_get_physinfo(ctx, &physinfo) != 0) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting phys info"); + return NULL; + } + size = physinfo.max_cpu_id + 32; /* allow some inactive cpu pools */ ptr = calloc(size, sizeof(libxl_poolinfo)); if (!ptr) { @@ -619,16 +627,24 @@ libxl_poolinfo * libxl_list_pool(libxl_c return NULL; } - ret = xc_cpupool_getinfo(ctx->xch, 0, 256, info); - if (ret<0) { - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting cpupool info"); - return NULL; + poolid = 0; + for (i = 0; i < size; i++) { + info = xc_cpupool_getinfo(ctx->xch, poolid); + if (info == NULL) + break; + ptr[i].poolid = info->cpupool_id; + ptr[i].sched_id = info->sched_id; + ptr[i].n_dom = info->n_dom; + if (libxl_cpumap_alloc(&ptr[i].cpumap, physinfo.max_cpu_id + 1)) + break; + for (m = 0; m < ptr[i].cpumap.size / sizeof(*ptr[i].cpumap.map); m++) + ptr[i].cpumap.map[m] = (info->cpumap_size > (m * sizeof(*ptr[i].cpumap.map))) ? + info->cpumap[m] : 0; + poolid = info->cpupool_id + 1; + free(info); } - for (i = 0; i < ret; i++) { - ptr[i].poolid = info[i].cpupool_id; - } - *nb_pool = ret; + *nb_pool = i; return ptr; } @@ -2928,7 +2944,6 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct xc_domaininfo_t domaininfo; xc_vcpuinfo_t vcpuinfo; xc_physinfo_t physinfo = { 0 }; - unsigned num_cpuwords; if (xc_domain_getinfolist(ctx->xch, domid, 1, &domaininfo) != 1) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting infolist"); @@ -2944,10 +2959,9 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct return NULL; } - num_cpuwords = ((physinfo.max_cpu_id + 64) / 64); for (*nb_vcpu = 0; *nb_vcpu <= domaininfo.max_vcpu_id; ++*nb_vcpu, ++ptr) { - ptr->cpumap = malloc(num_cpuwords * sizeof(*ptr->cpumap)); - if (!ptr->cpumap) { + if (libxl_cpumap_alloc(&ptr->cpumap, *nrcpus)) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "allocating cpumap"); return NULL; } if (xc_vcpu_getinfo(ctx->xch, domid, *nb_vcpu, &vcpuinfo) == -1) { @@ -2955,7 +2969,7 @@ libxl_vcpuinfo *libxl_list_vcpu(libxl_ct return NULL; } if (xc_vcpu_getaffinity(ctx->xch, domid, *nb_vcpu, - ptr->cpumap, ((*nrcpus) + 7) / 8) == -1) { + ptr->cpumap.map, ((*nrcpus) + 7) / 8) == -1) { LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting vcpu affinity"); return NULL; } @@ -3359,3 +3373,180 @@ void libxl_file_reference_destroy(libxl_ libxl__file_reference_unmap(f); free(f->path); } + +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap) +{ + libxl_physinfo info; + int ret; + + if (libxl_get_physinfo(ctx, &info) != 0) + return ERROR_FAIL; + + ret = libxl_cpumap_alloc(cpumap, info.max_cpu_id + 1); + if (ret) + return ret; + + if (xc_cpupool_freeinfo(ctx->xch, cpumap->map, cpumap->size)) { + free(cpumap->map); + cpumap->map = NULL; + return ERROR_FAIL; + } + + return 0; +} + +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid, + libxl_cpumap cpumap, libxl_uuid *uuid, + uint32_t *poolid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc; + int i; + xs_transaction_t t; + char *uuid_string; + + uuid_string = libxl__uuid2string(&gc, *uuid); + if (!uuid_string) + return ERROR_NOMEM; + + rc = xc_cpupool_create(ctx->xch, poolid, schedid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Could not create cpupool"); + return ERROR_FAIL; + } + + for (i = 0; i < cpumap.size * 8; i++) + if (cpumap.map[i / 64] & (1L << (i % 64))) { + rc = xc_cpupool_addcpu(ctx->xch, *poolid, i); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving cpu to cpupool"); + return ERROR_FAIL; + } + } + + for (;;) { + t = xs_transaction_start(ctx->xsh); + + xs_mkdir(ctx->xsh, t, libxl__sprintf(&gc, "/local/pool/%d", *poolid)); + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/uuid", *poolid), + uuid_string); + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "/local/pool/%d/name", *poolid), + name); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + return 0; + } +} + +int libxl_destroy_cpupool(libxl_ctx *ctx, uint32_t poolid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc, i; + xc_cpupoolinfo_t *info; + xs_transaction_t t; + + info = xc_cpupool_getinfo(ctx->xch, poolid); + if (info == NULL) + return ERROR_NOMEM; + + rc = ERROR_INVAL; + if ((info->cpupool_id != poolid) || (info->n_dom)) + goto out; + + for (i = 0; i < info->cpumap_size; i++) + if (info->cpumap[i / 64] & (1L << (i % 64))) { + rc = xc_cpupool_removecpu(ctx->xch, poolid, i); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error removing cpu from cpupool"); + rc = ERROR_FAIL; + goto out; + } + } + + rc = xc_cpupool_destroy(ctx->xch, poolid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, "Could not destroy cpupool"); + rc = ERROR_FAIL; + goto out; + } + + for (;;) { + t = xs_transaction_start(ctx->xsh); + + xs_rm(ctx->xsh, XBT_NULL, libxl__sprintf(&gc, "/local/pool/%d", poolid)); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + break; + } + + rc = 0; + +out: + free(info); + + return rc; +} + +int libxl_cpupool_cpuadd(libxl_ctx *ctx, uint32_t poolid, int cpu) +{ + int rc; + + rc = xc_cpupool_addcpu(ctx->xch, poolid, cpu); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving cpu to cpupool"); + return ERROR_FAIL; + } + return 0; +} + +int libxl_cpupool_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu) +{ + int rc; + + rc = xc_cpupool_removecpu(ctx->xch, poolid, cpu); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error removing cpu from cpupool"); + return ERROR_FAIL; + } + return 0; +} + +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc; + char *dom_path; + char *vm_path; + char *poolname; + xs_transaction_t t; + + dom_path = libxl__xs_get_dompath(&gc, domid); + if (!dom_path) { + return ERROR_FAIL; + } + + rc = xc_cpupool_movedomain(ctx->xch, poolid, domid); + if (rc) { + LIBXL__LOG_ERRNOVAL(ctx, LIBXL__LOG_ERROR, rc, + "Error moving domain to cpupool"); + return ERROR_FAIL; + } + + poolname = libxl__poolid_to_name(&gc, poolid); + vm_path = libxl__xs_read(&gc, XBT_NULL, libxl__sprintf(&gc, "%s/vm", dom_path)); + for (; vm_path;) { + t = xs_transaction_start(ctx->xsh); + + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/pool_name", vm_path), poolname); + + if (xs_transaction_end(ctx->xsh, t, 0) || (errno != EAGAIN)) + break; + } + + return 0; +} diff -r d978675f3d53 tools/libxl/libxl.h --- a/tools/libxl/libxl.h Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxl.h Fri Sep 17 13:26:13 2010 +0200 @@ -140,8 +140,6 @@ void libxl_string_list_destroy(libxl_str typedef char **libxl_key_value_list; void libxl_key_value_list_destroy(libxl_key_value_list *kvl); - -typedef uint64_t *libxl_cpumap; typedef uint32_t libxl_hwcap[8]; @@ -488,6 +486,15 @@ int libxl_device_net2_del(libxl_ctx *ctx int libxl_device_net2_del(libxl_ctx *ctx, libxl_device_net2 *net2, int wait); +int libxl_get_freecpus(libxl_ctx *ctx, libxl_cpumap *cpumap); +int libxl_create_cpupool(libxl_ctx *ctx, char *name, int schedid, + libxl_cpumap cpumap, libxl_uuid *uuid, + 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_cpuremove(libxl_ctx *ctx, uint32_t poolid, int cpu); +int libxl_cpupool_movedomain(libxl_ctx *ctx, uint32_t poolid, uint32_t domid); + /* common paths */ const char *libxl_sbindir_path(void); const char *libxl_bindir_path(void); diff -r d978675f3d53 tools/libxl/libxl.idl --- a/tools/libxl/libxl.idl Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxl.idl Fri Sep 17 13:26:13 2010 +0200 @@ -16,8 +16,6 @@ libxl_string_list = Builtin("string_list libxl_string_list = Builtin("string_list", destructor_fn="libxl_string_list_destroy", passby=PASS_BY_REFERENCE) libxl_key_value_list = Builtin("key_value_list", destructor_fn="libxl_key_value_list_destroy", passby=PASS_BY_REFERENCE) libxl_file_reference = Builtin("file_reference", destructor_fn="libxl_file_reference_destroy", passby=PASS_BY_REFERENCE) - -libxl_cpumap = Builtin("cpumap", destructor_fn="free") libxl_hwcap = Builtin("hwcap") @@ -44,9 +42,17 @@ SHUTDOWN_* constant."""), ("vcpu_online", uint32), ], destructor_fn=None) +libxl_cpumap = Struct("cpumap", [ + ("size", uint32, False, "number of bytes in map"), + ("map", Reference(uint64)), + ]) + libxl_poolinfo = Struct("poolinfo", [ - ("poolid", uint32) - ], destructor_fn=None) + ("poolid", uint32), + ("sched_id", uint32), + ("n_dom", uint32), + ("cpumap", libxl_cpumap) + ], destructor_fn="libxl_poolinfo_destroy") libxl_vminfo = Struct("vminfo", [ ("uuid", libxl_uuid), diff -r d978675f3d53 tools/libxl/libxl_utils.c --- a/tools/libxl/libxl_utils.c Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxl_utils.c Fri Sep 17 13:26:13 2010 +0200 @@ -31,6 +31,17 @@ #include "libxl_utils.h" #include "libxl_internal.h" +struct schedid_name { + char *name; + int id; +}; + +static struct schedid_name schedid_name[] = { + { "credit", XEN_SCHEDULER_CREDIT }, + { "sedf", XEN_SCHEDULER_SEDF }, + { "credit2", XEN_SCHEDULER_CREDIT2 }, + { NULL, -1 } +}; unsigned long libxl_get_required_shadow_memory(unsigned long maxmem_kb, unsigned int smp_cpus) { @@ -124,19 +135,41 @@ int libxl_name_to_poolid(libxl_ctx *ctx, return ERROR_NOMEM; for (i = 0; i < nb_pools; i++) { - poolname = libxl_poolid_to_name(ctx, poolinfo[i].poolid); - if (!poolname) - continue; - if (strcmp(poolname, name) == 0) { - *poolid = poolinfo[i].poolid; - ret = 0; + if (ret && ((poolname = libxl_poolid_to_name(ctx, + poolinfo[i].poolid)) != NULL)) { + if (strcmp(poolname, name) == 0) { + *poolid = poolinfo[i].poolid; + ret = 0; + free(poolname); + } free(poolname); - break; } - free(poolname); + libxl_poolinfo_destroy(poolinfo + i); } free(poolinfo); return ret; +} + +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name) +{ + int i; + + for (i = 0; schedid_name[i].name != NULL; i++) + if (strcmp(name, schedid_name[i].name) == 0) + return schedid_name[i].id; + + return -1; +} + +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid) +{ + int i; + + for (i = 0; schedid_name[i].name != NULL; i++) + if (schedid_name[i].id == schedid) + return schedid_name[i].name; + + return "unknown"; } int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid) @@ -675,3 +708,36 @@ out: libxl__free_all(&gc); return rc; } + +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus) +{ + int elems; + + elems = (max_cpus + 63) / 64; + cpumap->map = calloc(elems, sizeof(*cpumap->map)); + if (!cpumap->map) + return ERROR_NOMEM; + cpumap->size = elems * 8; /* size in bytes */ + return 0; +} + +int libxl_cpumap_test(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return 0; + return (cpumap->map[cpu / 64] & (1L << (cpu & 63))) ? 1 : 0; +} + +void libxl_cpumap_set(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return; + cpumap->map[cpu / 64] |= 1L << (cpu & 63); +} + +void libxl_cpumap_reset(libxl_cpumap *cpumap, int cpu) +{ + if (cpu >= cpumap->size * 8) + return; + cpumap->map[cpu / 64] &= ~(1L << (cpu & 63)); +} diff -r d978675f3d53 tools/libxl/libxl_utils.h --- a/tools/libxl/libxl_utils.h Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxl_utils.h Fri Sep 17 13:26:13 2010 +0200 @@ -23,6 +23,8 @@ char *libxl_domid_to_name(libxl_ctx *ctx char *libxl_domid_to_name(libxl_ctx *ctx, uint32_t domid); int libxl_name_to_poolid(libxl_ctx *ctx, const char *name, uint32_t *poolid); char *libxl_poolid_to_name(libxl_ctx *ctx, uint32_t poolid); +int libxl_name_to_schedid(libxl_ctx *ctx, const char *name); +char *libxl_schedid_to_name(libxl_ctx *ctx, int schedid); int libxl_get_stubdom_id(libxl_ctx *ctx, int guest_domid); int libxl_is_stubdom(libxl_ctx *ctx, uint32_t domid, uint32_t *target_domid); int libxl_create_logfile(libxl_ctx *ctx, char *name, char **full_name); @@ -74,5 +76,9 @@ int libxl_devid_to_device_net2(libxl_ctx * return -1 if there are an error */ int libxl_check_device_model_version(libxl_ctx *ctx, char *path); +int libxl_cpumap_alloc(libxl_cpumap *cpumap, int max_cpus); +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); #endif diff -r d978675f3d53 tools/libxl/libxltypes.py --- a/tools/libxl/libxltypes.py Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxltypes.py Fri Sep 17 13:26:13 2010 +0200 @@ -131,7 +131,10 @@ class Reference(Type): kwargs.setdefault('passby', PASS_BY_VALUE) kwargs.setdefault('namespace', ty.namespace) - typename = ty.typename[len(kwargs['namespace']):] + + typename = ty.typename + if ty.namespace: + typename = typename[len(kwargs['namespace']):] Type.__init__(self, typename + " *", **kwargs) # diff -r d978675f3d53 tools/libxl/libxlu_cfg_l.c --- a/tools/libxl/libxlu_cfg_l.c Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxlu_cfg_l.c Fri Sep 17 13:26:13 2010 +0200 @@ -54,6 +54,7 @@ typedef unsigned char flex_uint8_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -83,8 +84,6 @@ typedef unsigned int flex_uint32_t; #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -159,15 +158,7 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif /* The state buf must be large enough to hold one state per character in the main buffer. @@ -496,7 +487,7 @@ void xlu__cfg_yyset_column(int column_n void xlu__cfg_yyset_column(int column_no, yyscan_t yyscanner); -#line 500 "libxlu_cfg_l.c" +#line 491 "libxlu_cfg_l.c" #define INITIAL 0 #define lexerr 1 @@ -632,12 +623,7 @@ static int input (yyscan_t yyscanner ); /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Copy whatever the last rule matched to the standard output. */ @@ -645,7 +631,7 @@ static int input (yyscan_t yyscanner ); /* This used to be an fputs(), but since the string might contain NUL's, * we now use fwrite(). */ -#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0) +#define ECHO fwrite( yytext, yyleng, 1, yyout ) #endif /* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, @@ -656,7 +642,7 @@ static int input (yyscan_t yyscanner ); if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ { \ int c = '*'; \ - size_t n; \ + int n; \ for ( n = 0; n < max_size && \ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \ buf[n] = (char) c; \ @@ -744,7 +730,7 @@ YY_DECL #line 37 "libxlu_cfg_l.l" -#line 748 "libxlu_cfg_l.c" +#line 734 "libxlu_cfg_l.c" yylval = yylval_param; @@ -944,7 +930,7 @@ YY_RULE_SETUP #line 82 "libxlu_cfg_l.l" YY_FATAL_ERROR( "flex scanner jammed" ); YY_BREAK -#line 948 "libxlu_cfg_l.c" +#line 934 "libxlu_cfg_l.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(lexerr): yyterminate(); @@ -1687,8 +1673,8 @@ YY_BUFFER_STATE xlu__cfg_yy_scan_string /** Setup the input buffer state to scan the given bytes. The next call to xlu__cfg_yylex() will * scan from a @e copy of @a bytes. - * @param yybytes the byte buffer to scan - * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes. + * @param bytes the byte buffer to scan + * @param len the number of bytes in the buffer pointed to by @a bytes. * @param yyscanner The scanner object. * @return the newly allocated buffer state object. */ diff -r d978675f3d53 tools/libxl/libxlu_cfg_l.h --- a/tools/libxl/libxlu_cfg_l.h Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/libxlu_cfg_l.h Fri Sep 17 13:26:13 2010 +0200 @@ -58,6 +58,7 @@ typedef unsigned char flex_uint8_t; typedef unsigned char flex_uint8_t; typedef unsigned short int flex_uint16_t; typedef unsigned int flex_uint32_t; +#endif /* ! C99 */ /* Limits of integral types. */ #ifndef INT8_MIN @@ -87,8 +88,6 @@ typedef unsigned int flex_uint32_t; #ifndef UINT32_MAX #define UINT32_MAX (4294967295U) #endif - -#endif /* ! C99 */ #endif /* ! FLEXINT_H */ @@ -132,15 +131,7 @@ typedef void* yyscan_t; /* Size of default input buffer. */ #ifndef YY_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k. - * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case. - * Ditto for the __ia64__ case accordingly. - */ -#define YY_BUF_SIZE 32768 -#else #define YY_BUF_SIZE 16384 -#endif /* __ia64__ */ #endif #ifndef YY_TYPEDEF_YY_BUFFER_STATE @@ -310,12 +301,7 @@ static int yy_flex_strlen (yyconst char /* Amount of stuff to slurp up with each read. */ #ifndef YY_READ_BUF_SIZE -#ifdef __ia64__ -/* On IA-64, the buffer size is 16k, not 8k */ -#define YY_READ_BUF_SIZE 16384 -#else #define YY_READ_BUF_SIZE 8192 -#endif /* __ia64__ */ #endif /* Number of entries by which start-condition stack grows. */ @@ -352,6 +338,6 @@ extern int xlu__cfg_yylex \ #line 82 "libxlu_cfg_l.l" -#line 356 "libxlu_cfg_l.h" +#line 342 "libxlu_cfg_l.h" #undef xlu__cfg_yyIN_HEADER #endif /* xlu__cfg_yyHEADER_H */ diff -r d978675f3d53 tools/libxl/xl.h --- a/tools/libxl/xl.h Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/xl.h Fri Sep 17 13:26:13 2010 +0200 @@ -79,6 +79,12 @@ int main_network2attach(int argc, char * int main_network2attach(int argc, char **argv); int main_network2list(int argc, char **argv); int main_network2detach(int argc, char **argv); +int main_poolcreate(int argc, char **argv); +int main_poollist(int argc, char **argv); +int main_pooldestroy(int argc, char **argv); +int main_poolcpuadd(int argc, char **argv); +int main_poolcpuremove(int argc, char **argv); +int main_poolmigrate(int argc, char **argv); void help(char *command); diff -r d978675f3d53 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/xl_cmdimpl.c Fri Sep 17 13:26:13 2010 +0200 @@ -421,7 +421,7 @@ static void printf_info(int domid, printf("\t(ssidref %d)\n", c_info->ssidref); printf("\t(name %s)\n", c_info->name); printf("\t(uuid " LIBXL_UUID_FMT ")\n", LIBXL_UUID_BYTES(c_info->uuid)); - printf("\t(cpupool %s (%d))\n", c_info->poolname, c_info->poolid); + printf("\t(cpupool %s)\n", c_info->poolname); if (c_info->xsdata) printf("\t(xsdata contains data)\n"); else @@ -3287,7 +3287,7 @@ static void print_vcpuinfo(uint32_t tdom printf("%9.1f ", ((float)vcpuinfo->vcpu_time / 1e9)); /* CPU AFFINITY */ pcpumap = nr_cpus > 64 ? (uint64_t)-1 : ((1ULL << nr_cpus) - 1); - for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) { + for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) { if (*cpumap < pcpumap) { break; } @@ -3302,7 +3302,7 @@ static void print_vcpuinfo(uint32_t tdom if (!nr_cpus) { printf("any cpu\n"); } else { - for (cpumap = vcpuinfo->cpumap; nr_cpus; ++cpumap) { + for (cpumap = vcpuinfo->cpumap.map; nr_cpus; ++cpumap) { pcpumap = *cpumap; for (i = 0; !(pcpumap & 1); ++i, pcpumap >>= 1) ; @@ -3574,10 +3574,7 @@ static void output_xeninfo(void) printf("xen_minor : %d\n", info->xen_version_minor); printf("xen_extra : %s\n", info->xen_version_extra); printf("xen_caps : %s\n", info->capabilities); - printf("xen_scheduler : %s\n", - sched_id == XEN_SCHEDULER_SEDF ? "sedf" : - sched_id == XEN_SCHEDULER_CREDIT ? "credit" : - sched_id == XEN_SCHEDULER_CREDIT2 ? "credit2" : "unknown"); + printf("xen_scheduler : %s\n", libxl_schedid_to_name(&ctx, sched_id)); printf("xen_pagesize : %lu\n", info->pagesize); printf("platform_params : virt_start=0x%lx\n", info->virt_start); printf("xen_changeset : %s\n", info->changeset); @@ -3608,6 +3605,8 @@ static void output_physinfo(void) libxl_physinfo info; const libxl_version_info *vinfo; unsigned int i; + libxl_cpumap cpumap; + int n = 0; if (libxl_get_physinfo(&ctx, &info) != 0) { fprintf(stderr, "libxl_physinfo failed.\n"); @@ -3634,6 +3633,13 @@ static void output_physinfo(void) printf("total_memory : %"PRIu64"\n", info.total_pages / i); printf("free_memory : %"PRIu64"\n", info.free_pages / i); } + if (!libxl_get_freecpus(&ctx, &cpumap)) { + for (i = 0; i < cpumap.size * 8; i++) + if (libxl_cpumap_test(&cpumap, i)) + n++; + printf("free_cpus : %d\n", n); + free(cpumap.map); + } return; } @@ -5049,3 +5055,444 @@ int main_tmem_freeable(int argc, char ** printf("%d\n", mb); return 0; } + +int main_poolcreate(int argc, char **argv) +{ + char *filename = NULL; + char *p, extra_config[1024]; + int dryrun = 0; + int opt; + int option_index = 0; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"defconfig", 1, 0, 'f'}, + {"dryrun", 0, 0, 'n'}, + {0, 0, 0, 0} + }; + int ret; + void *config_data = 0; + int config_len = 0; + XLU_Config *config; + const char *buf; + char *name, *sched; + uint32_t poolid; + int schedid = -1; + XLU_ConfigList *cpus; + int n_cpus, i, n; + libxl_cpumap freemap; + libxl_cpumap cpumap; + libxl_uuid uuid; + + while (1) { + opt = getopt_long(argc, argv, "hnf:", long_options, &option_index); + if (opt == -1) + break; + + switch (opt) { + case 'f': + filename = optarg; + break; + case 'h': + help("pool-create"); + return 0; + case 'n': + dryrun = 1; + break; + default: + fprintf(stderr, "option not supported\n"); + break; + } + } + + memset(extra_config, 0, sizeof(extra_config)); + while (optind < argc) { + if ((p = strchr(argv[optind], '='))) { + if (strlen(extra_config) + 1 < sizeof(extra_config)) { + if (strlen(extra_config)) + strcat(extra_config, "\n"); + strcat(extra_config, argv[optind]); + } + } else if (!filename) { + filename = argv[optind]; + } else { + help("pool-create"); + return -ERROR_FAIL; + } + optind++; + } + + if (!filename) { + help("pool-create"); + return -ERROR_FAIL; + } + + if (libxl_read_file_contents(&ctx, filename, &config_data, &config_len)) { + fprintf(stderr, "Failed to read config file: %s: %s\n", + filename, strerror(errno)); + return -ERROR_FAIL; + } + if (strlen(extra_config)) { + if (config_len > INT_MAX - (strlen(extra_config) + 2)) { + fprintf(stderr, "Failed to attach extra configration\n"); + return -ERROR_FAIL; + } + config_data = realloc(config_data, + config_len + strlen(extra_config) + 2); + if (!config_data) { + fprintf(stderr, "Failed to realloc config_data\n"); + return -ERROR_FAIL; + } + strcat(config_data, "\n"); + strcat(config_data, extra_config); + strcat(config_data, "\n"); + config_len += (strlen(extra_config) + 2); + } + + config = xlu_cfg_init(stderr, filename); + if (!config) { + fprintf(stderr, "Failed to allocate for configuration\n"); + return -ERROR_FAIL; + } + + ret = xlu_cfg_readdata(config, config_data, config_len); + if (ret) { + fprintf(stderr, "Failed to parse config file: %s\n", strerror(ret)); + return -ERROR_FAIL; + } + + if (!xlu_cfg_get_string (config, "name", &buf)) + name = strdup(buf); + else + name = basename(filename); + if (!libxl_name_to_poolid(&ctx, name, &poolid)) { + fprintf(stderr, "Pool name \"%s\" already exists\n", name); + return -ERROR_FAIL; + } + + if (!xlu_cfg_get_string (config, "sched", &buf)) { + if ((schedid = libxl_name_to_schedid(&ctx, buf)) < 0) { + fprintf(stderr, "Unknown scheduler\n"); + return -ERROR_FAIL; + } + } else { + if ((schedid = libxl_get_sched_id(&ctx)) < 0) { + fprintf(stderr, "get_sched_id sysctl failed.\n"); + return -ERROR_FAIL; + } + } + sched = libxl_schedid_to_name(&ctx, schedid); + + if (libxl_get_freecpus(&ctx, &freemap)) { + fprintf(stderr, "libxl_get_freecpus failed\n"); + return -ERROR_FAIL; + } + if (libxl_cpumap_alloc(&cpumap, freemap.size * 8)) { + fprintf(stderr, "Failed to allocate cpumap\n"); + return -ERROR_FAIL; + } + if (!xlu_cfg_get_list(config, "cpus", &cpus, 0)) { + n_cpus = 0; + while ((buf = xlu_cfg_get_listitem(cpus, n_cpus)) != NULL) { + i = atoi(buf); + if ((i < 0) || (i >= freemap.size * 8) || + !libxl_cpumap_test(&freemap, i)) { + fprintf(stderr, "cpu %d illegal or not free\n", i); + return -ERROR_FAIL; + } + libxl_cpumap_set(&cpumap, i); + n_cpus++; + } + } else { + n_cpus = 1; + n = 0; + for (i = 0; i < freemap.size; i++) + if (libxl_cpumap_test(&freemap, i)) { + n++; + libxl_cpumap_set(&cpumap, i); + break; + } + if (n != n_cpus) { + fprintf(stderr, "no free cpu found\n"); + return -ERROR_FAIL; + } + } + + libxl_uuid_generate(&uuid); + + printf("Using config file \"%s\"\n", filename); + printf("pool name: %s\n", name); + printf("scheduler: %s\n", sched); + printf("number of cpus: %d\n", n_cpus); + + if (dryrun) + return 0; + + poolid = 0; + if (libxl_create_cpupool(&ctx, name, schedid, cpumap, &uuid, &poolid)) { + fprintf(stderr, "error on creating cpupool\n"); + return -ERROR_FAIL; + } + + return 0; +} + +int main_poollist(int argc, char **argv) +{ + int opt; + int option_index = 0; + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"long", 0, 0, 'l'}, + {"cpus", 0, 0, 'c'}, + {0, 0, 0, 0} + }; + int opt_long = 0; + int opt_cpus = 0; + char *pool = NULL; + libxl_poolinfo *poolinfo; + int n_pools, p, c, n; + uint32_t poolid; + char *name; + int ret = 0; + + while (1) { + opt = getopt_long(argc, argv, "hlc", long_options, &option_index); + if (opt == -1) + break; + + switch (opt) { + case 'h': + help("pool-list"); + return 0; + case 'l': + opt_long = 1; + break; + case 'c': + opt_cpus = 1; + break; + default: + fprintf(stderr, "option not supported\n"); + break; + } + } + + if ((optind + 1) < argc) { + help("pool-list"); + return -ERROR_FAIL; + } + if (optind < argc) { + pool = argv[optind]; + if (libxl_name_to_poolid(&ctx, pool, &poolid)) { + fprintf(stderr, "Pool \'%s\' does not exist\n", pool); + return -ERROR_FAIL; + } + } + + poolinfo = libxl_list_pool(&ctx, &n_pools); + if (!poolinfo) { + fprintf(stderr, "error getting cpupool info\n"); + return -ERROR_NOMEM; + } + + if (!opt_long) { + printf("%-19s", "Name"); + if (opt_cpus) + printf("CPU list\n"); + else + printf("CPUs Sched Active Domain count\n"); + } + + for (p = 0; p < n_pools; p++) { + if (!ret && (!pool || (poolinfo[p].poolid != poolid))) { + name = libxl_poolid_to_name(&ctx, poolinfo[p].poolid); + if (!name) { + fprintf(stderr, "error getting cpupool info\n"); + ret = -ERROR_NOMEM; + } + else if (opt_long) { + ret = -ERROR_NI; + } else { + printf("%-19s", name); + n = 0; + for (c = 0; c < poolinfo[p].cpumap.size * 8; c++) + if (poolinfo[p].cpumap.map[c / 64] & (1L << (c % 64))) { + if (n && opt_cpus) printf(","); + if (opt_cpus) printf("%d", c); + n++; + } + if (!opt_cpus) { + printf("%3d %9s y %4d", n, + libxl_schedid_to_name(&ctx, poolinfo[p].sched_id), + poolinfo[p].n_dom); + } + printf("\n"); + } + } + libxl_poolinfo_destroy(poolinfo + p); + } + + return ret; +} + +int main_pooldestroy(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-destroy"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-destroy"); + return -ERROR_FAIL; + } + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_destroy_cpupool(&ctx, poolid); +} + +int main_poolcpuadd(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + int cpu; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-cpu-add"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-cpu-add"); + return -ERROR_FAIL; + } + + if (!argv[optind]) { + fprintf(stderr, "no cpu specified\n"); + help("pool-cpu-add"); + return -ERROR_FAIL; + } + cpu = atoi(argv[optind]); + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_cpuadd(&ctx, poolid, cpu); +} + +int main_poolcpuremove(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + int cpu; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-cpu-remove"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-cpu-remove"); + return -ERROR_FAIL; + } + + if (!argv[optind]) { + fprintf(stderr, "no cpu specified\n"); + help("pool-cpu-remove"); + return -ERROR_FAIL; + } + cpu = atoi(argv[optind]); + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_cpuremove(&ctx, poolid, cpu); +} + +int main_poolmigrate(int argc, char **argv) +{ + int opt; + char *pool; + uint32_t poolid; + char *dom; + uint32_t domid; + + while ((opt = getopt(argc, argv, "h")) != -1) { + switch (opt) { + case 'h': + help("pool-migrate"); + return 0; + default: + fprintf(stderr, "option `%c' not supported.\n", opt); + break; + } + } + + dom = argv[optind++]; + if (!dom) { + fprintf(stderr, "no domain specified\n"); + help("pool-migrate"); + return -ERROR_FAIL; + } + + pool = argv[optind++]; + if (!pool) { + fprintf(stderr, "no cpupool specified\n"); + help("pool-migrate"); + return -ERROR_FAIL; + } + + if (domain_qualifier_to_domid(dom, &domid, NULL) || + !libxl_domid_to_name(&ctx, domid)) { + fprintf(stderr, "unknown domain \'%s\'\n", dom); + return -ERROR_FAIL; + } + + if (pool_qualifier_to_poolid(pool, &poolid, NULL) || + !libxl_poolid_to_name(&ctx, poolid)) { + fprintf(stderr, "unknown pool \'%s\'\n", pool); + return -ERROR_FAIL; + } + + return -libxl_cpupool_movedomain(&ctx, poolid, domid); +} diff -r d978675f3d53 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c Thu Sep 16 18:29:26 2010 +0100 +++ b/tools/libxl/xl_cmdtable.c Fri Sep 17 13:26:13 2010 +0200 @@ -338,6 +338,41 @@ struct cmd_spec cmd_table[] = { "destroy a domain's version 2 virtual network device", "<Domain> <DevId>", }, + { "pool-create", + &main_poolcreate, + "Create a CPU pool based an ConfigFile", + "[options] <ConfigFile> [vars]", + "-h, --help Print this help.\n" + "-f=FILE, --defconfig=FILE Use the given configuration file.\n" + "-n, --dryrun Dry run - prints the resulting configuration." + }, + { "pool-list", + &main_poollist, + "List CPU pools on host", + "[-l|--long] [-c|--cpus] [<CPU Pool>]", + "-l, --long Output all CPU pool details.\n" + "-c, --cpus Output list of CPUs used by a pool" + }, + { "pool-destroy", + &main_pooldestroy, + "Deactivates a CPU pool", + "<CPU Pool>", + }, + { "pool-cpu-add", + &main_poolcpuadd, + "Adds a CPU to a CPU pool", + "<CPU Pool> <CPU nr>", + }, + { "pool-cpu-remove", + &main_poolcpuremove, + "Removes a CPU from a CPU pool", + "<CPU Pool> <CPU nr>", + }, + { "pool-migrate", + &main_poolmigrate, + "Moves a domain into a CPU pool", + "<Domain> <CPU Pool>", + }, }; int cmdtable_len = sizeof(cmd_table)/sizeof(struct cmd_spec); [-- Attachment #3: Type: text/plain, Size: 138 bytes --] _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 11:41 ` Juergen Gross @ 2010-09-17 11:55 ` Ian Campbell 2010-09-17 15:53 ` Ian Jackson 2010-09-17 15:55 ` Ian Jackson 1 sibling, 1 reply; 11+ messages in thread From: Ian Campbell @ 2010-09-17 11:55 UTC (permalink / raw) To: Juergen Gross; +Cc: xen-devel@lists.xensource.com On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: > On 09/17/10 11:46, Ian Campbell wrote: > > > >> On Fri, 2010-09-17 at 07:10 +0100, Juergen Gross wrote: > >> + size = physinfo.max_cpu_id + 32; > > > > Where does the number 32 come from? > > I just wanted to be able to support some (inactive) cpupools without any > cpu allocated. It's just a number which should normally be large enough. What is the purpose of these inactive cpupools? ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 11:55 ` Ian Campbell @ 2010-09-17 15:53 ` Ian Jackson 2010-09-17 18:28 ` Ian Campbell 0 siblings, 1 reply; 11+ messages in thread From: Ian Jackson @ 2010-09-17 15:53 UTC (permalink / raw) To: Ian Campbell; +Cc: Juergen Gross, xen-devel@lists.xensource.com Ian Campbell writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): > On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: > > I just wanted to be able to support some (inactive) cpupools without any > > cpu allocated. It's just a number which should normally be large enough. > > What is the purpose of these inactive cpupools? Amongst other things, I would guess, the creation or removal of cpupools ! I think we should have a #define rather than the magic number 32 though. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 15:53 ` Ian Jackson @ 2010-09-17 18:28 ` Ian Campbell 2010-09-20 4:58 ` Juergen Gross 0 siblings, 1 reply; 11+ messages in thread From: Ian Campbell @ 2010-09-17 18:28 UTC (permalink / raw) To: Ian Jackson; +Cc: Juergen Gross, xen-devel@lists.xensource.com On Fri, 2010-09-17 at 16:53 +0100, Ian Jackson wrote: > Ian Campbell writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): > > On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: > > > I just wanted to be able to support some (inactive) cpupools without any > > > cpu allocated. It's just a number which should normally be large enough. > > > > What is the purpose of these inactive cpupools? > > Amongst other things, I would guess, the creation or removal of > cpupools ! I don't think so, libxl_create_cpupool returns a new poolid for a newly created pool, so they are not needed for that. libxl_destroy_cpupool would only be used to delete a real cpupool, you don't need dummy pools to remove pools. BTW I noticed that we have libxl_list_pool vs libxl_{create,destroy}_cpupool and libxl_cpupool_{cpuadd,cpuremove,movedomain}. I think the interface should use cpupool throughout and not just pool to make it clear what it is a pool of. IOW libxl_list_pool should be libxl_list_cpupool, the type should be called libxl_cpupool and functions such as libxl_name_to_poolid should instead be libxl_name_to_cpupoolid. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 18:28 ` Ian Campbell @ 2010-09-20 4:58 ` Juergen Gross 2010-09-29 8:28 ` Ian Campbell 0 siblings, 1 reply; 11+ messages in thread From: Juergen Gross @ 2010-09-20 4:58 UTC (permalink / raw) To: Ian Campbell; +Cc: xen-devel@lists.xensource.com, Ian Jackson On 09/17/10 20:28, Ian Campbell wrote: > On Fri, 2010-09-17 at 16:53 +0100, Ian Jackson wrote: >> Ian Campbell writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): >>> On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: >>>> I just wanted to be able to support some (inactive) cpupools without any >>>> cpu allocated. It's just a number which should normally be large enough. >>> >>> What is the purpose of these inactive cpupools? >> >> Amongst other things, I would guess, the creation or removal of >> cpupools ! "Inactive cpupools" were meant to be cpupools without any cpus and domains assigned to them. They can exist for a short time during creation and removal, but due to explicitly removing all cpus, too. > I don't think so, libxl_create_cpupool returns a new poolid for a newly > created pool, so they are not needed for that. They have a poolid, but there might be more cpupools than cpus in the system. This was the reason for the "+ 32". But I agree, this should be done via a #define. > BTW I noticed that we have libxl_list_pool vs > libxl_{create,destroy}_cpupool and > libxl_cpupool_{cpuadd,cpuremove,movedomain}. I think the interface > should use cpupool throughout and not just pool to make it clear what it > is a pool of. IOW libxl_list_pool should be libxl_list_cpupool, the type > should be called libxl_cpupool and functions such as > libxl_name_to_poolid should instead be libxl_name_to_cpupoolid. Okay, I'll change it. Juergen -- Juergen Gross Principal Developer Operating Systems TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967 Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com Domagkstr. 28 Internet: ts.fujitsu.com D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-20 4:58 ` Juergen Gross @ 2010-09-29 8:28 ` Ian Campbell 2010-10-01 7:18 ` Juergen Gross 0 siblings, 1 reply; 11+ messages in thread From: Ian Campbell @ 2010-09-29 8:28 UTC (permalink / raw) To: Juergen Gross; +Cc: xen-devel@lists.xensource.com, Ian Jackson (I'm just back from vacation, sorry for the delay replying) On Mon, 2010-09-20 at 05:58 +0100, Juergen Gross wrote: > On 09/17/10 20:28, Ian Campbell wrote: > > On Fri, 2010-09-17 at 16:53 +0100, Ian Jackson wrote: > >> Ian Campbell writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): > >>> On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: > >>>> I just wanted to be able to support some (inactive) cpupools without any > >>>> cpu allocated. It's just a number which should normally be large enough. > >>> > >>> What is the purpose of these inactive cpupools? > >> > >> Amongst other things, I would guess, the creation or removal of > >> cpupools ! > > "Inactive cpupools" were meant to be cpupools without any cpus and domains > assigned to them. > They can exist for a short time during creation and removal, but due to > explicitly removing all cpus, too. That makes sense in itself but then why do you need to add a magic number? I think libxl_list_pool should look more like libxl_list_domain, which implies that the xc_cpupool_getinfo interface should not be changed as in your previous patch since the new interface seems to preclude this usage. You really need retain the first poolid + a max number of entries + return the actual number of entries used interface in order to have a usable interface when there is no way to query the maximum pool id. The problem with the interface you are trying to define is compounded by the fact that the returned array is sparse and so in fact you will run out of space at poolid == nr_cpus+32 rather than at number of pools == nr_cpus+32. (Note that in contrast libxl_list_domain returns a compact array so that you run out of space at 1024 domains total, not domid 1024). IMHO libxl_list_{pool,domain} should also go realloc the buffer and go around again in the case where the underlying xc call returned the maximum number of entries -- since there may be more to come. Perhaps this is less likely in the domain case (1024 domains is quite a lot, at least today) but it seem more plausible in the pool case? I think this is probably a separate issue though and getting the basic semantics of xc_cpupool_getinfo/libxl_list_pool is more important. > > I don't think so, libxl_create_cpupool returns a new poolid for a newly > > created pool, so they are not needed for that. > > They have a poolid, but there might be more cpupools than cpus in the system. > This was the reason for the "+ 32". But I agree, this should be done via a > #define. I think it should be done by defining an interface which doesn't need arbitrary magic numbers in the first place. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-29 8:28 ` Ian Campbell @ 2010-10-01 7:18 ` Juergen Gross 2010-10-01 7:47 ` Ian Campbell 0 siblings, 1 reply; 11+ messages in thread From: Juergen Gross @ 2010-10-01 7:18 UTC (permalink / raw) To: Ian Campbell; +Cc: xen-devel@lists.xensource.com, Ian Jackson On 09/29/10 10:28, Ian Campbell wrote: > (I'm just back from vacation, sorry for the delay replying) > > On Mon, 2010-09-20 at 05:58 +0100, Juergen Gross wrote: >> On 09/17/10 20:28, Ian Campbell wrote: >>> On Fri, 2010-09-17 at 16:53 +0100, Ian Jackson wrote: >>>> Ian Campbell writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): >>>>> On Fri, 2010-09-17 at 12:41 +0100, Juergen Gross wrote: >>>>>> I just wanted to be able to support some (inactive) cpupools without any >>>>>> cpu allocated. It's just a number which should normally be large enough. >>>>> >>>>> What is the purpose of these inactive cpupools? >>>> >>>> Amongst other things, I would guess, the creation or removal of >>>> cpupools ! >> >> "Inactive cpupools" were meant to be cpupools without any cpus and domains >> assigned to them. >> They can exist for a short time during creation and removal, but due to >> explicitly removing all cpus, too. > > That makes sense in itself but then why do you need to add a magic > number? > > I think libxl_list_pool should look more like libxl_list_domain, which > implies that the xc_cpupool_getinfo interface should not be changed as > in your previous patch since the new interface seems to preclude this > usage. You really need retain the first poolid + a max number of entries > + return the actual number of entries used interface in order to have a > usable interface when there is no way to query the maximum pool id. > > The problem with the interface you are trying to define is compounded by > the fact that the returned array is sparse and so in fact you will run > out of space at poolid == nr_cpus+32 rather than at number of pools == > nr_cpus+32. (Note that in contrast libxl_list_domain returns a compact > array so that you run out of space at 1024 domains total, not domid > 1024). I think you misread the code. The returned array is NOT sparse. Please note that the hypervisor will return the info of the next cpu pool with poolid equal or larger as the requested one (that's the reason why poolid is a vital return info). > > IMHO libxl_list_{pool,domain} should also go realloc the buffer and go > around again in the case where the underlying xc call returned the > maximum number of entries -- since there may be more to come. Perhaps > this is less likely in the domain case (1024 domains is quite a lot, at > least today) but it seem more plausible in the pool case? I think this > is probably a separate issue though and getting the basic semantics of > xc_cpupool_getinfo/libxl_list_pool is more important. I agree realloc-ing the buffer for the array in libxl_list_pool is a better solution (now easy to do as the cpumasks are allocated separately). > >>> I don't think so, libxl_create_cpupool returns a new poolid for a newly >>> created pool, so they are not needed for that. >> >> They have a poolid, but there might be more cpupools than cpus in the system. >> This was the reason for the "+ 32". But I agree, this should be done via a >> #define. > > I think it should be done by defining an interface which doesn't need > arbitrary magic numbers in the first place. I'll resend modified patches. Juergen -- Juergen Gross Principal Developer Operating Systems TSP ES&S SWE OS6 Telephone: +49 (0) 89 3222 2967 Fujitsu Technology Solutions e-mail: juergen.gross@ts.fujitsu.com Domagkstr. 28 Internet: ts.fujitsu.com D-80807 Muenchen Company details: ts.fujitsu.com/imprint.html ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-10-01 7:18 ` Juergen Gross @ 2010-10-01 7:47 ` Ian Campbell 0 siblings, 0 replies; 11+ messages in thread From: Ian Campbell @ 2010-10-01 7:47 UTC (permalink / raw) To: Juergen Gross; +Cc: xen-devel@lists.xensource.com, Ian Jackson On Fri, 2010-10-01 at 08:18 +0100, Juergen Gross wrote: > > > The problem with the interface you are trying to define is > compounded by > > the fact that the returned array is sparse and so in fact you will > run > > out of space at poolid == nr_cpus+32 rather than at number of pools > == > > nr_cpus+32. (Note that in contrast libxl_list_domain returns a > compact > > array so that you run out of space at 1024 domains total, not domid > > 1024). > > I think you misread the code. The returned array is NOT sparse. Please > note that the hypervisor will return the info of the next cpu pool > with poolid equal or larger as the requested one (that's the reason > why poolid is a vital return info). Ah, I think that makes sense, thanks for taking the time to explain. I'll take another look at the latest patch set. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: Re: [Patch] support of cpu pools in xl 2010-09-17 11:41 ` Juergen Gross 2010-09-17 11:55 ` Ian Campbell @ 2010-09-17 15:55 ` Ian Jackson 1 sibling, 0 replies; 11+ messages in thread From: Ian Jackson @ 2010-09-17 15:55 UTC (permalink / raw) To: Juergen Gross; +Cc: Ian Campbell, xen-devel@lists.xensource.com Juergen Gross writes ("Re: [Xen-devel] Re: [Patch] support of cpu pools in xl"): > On 09/17/10 11:46, Ian Campbell wrote: > > In an ideal world, yes. I think this was a workaround for buggy versions > > of flex observed in the field or something. > > How nice ;-) I don't think it's really that bad an answer. Doing it this way means you can compile if you don't have flex, and the flex output itself is portable to any compiler/platform and not dependent on any part of the configuration. If you send patches which touch the .l files my build test will rebuild the .c files so I don't mind if you leave out the changes to the .l in your patch. Ian. ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2010-10-01 7:47 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-09-17 6:10 [Patch] support of cpu pools in xl Juergen Gross 2010-09-17 9:46 ` Ian Campbell 2010-09-17 11:41 ` Juergen Gross 2010-09-17 11:55 ` Ian Campbell 2010-09-17 15:53 ` Ian Jackson 2010-09-17 18:28 ` Ian Campbell 2010-09-20 4:58 ` Juergen Gross 2010-09-29 8:28 ` Ian Campbell 2010-10-01 7:18 ` Juergen Gross 2010-10-01 7:47 ` Ian Campbell 2010-09-17 15:55 ` Ian Jackson
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.