diff options
-rw-r--r-- | tools/libxc/xc_misc.c | 14 | ||||
-rw-r--r-- | tools/libxc/xenctrl.h | 6 | ||||
-rw-r--r-- | tools/libxl/libxl.c | 69 | ||||
-rw-r--r-- | tools/libxl/libxl.h | 7 | ||||
-rw-r--r-- | tools/libxl/libxl_types.idl | 9 | ||||
-rw-r--r-- | tools/libxl/libxl_utils.c | 13 | ||||
-rw-r--r-- | xen/include/public/sysctl.h | 1 |
7 files changed, 119 insertions, 0 deletions
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 812b127ff3..3c5d64a4d1 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -35,6 +35,20 @@ int xc_get_max_cpus(xc_interface *xch) return max_cpus; } +int xc_get_max_nodes(xc_interface *xch) +{ + static int max_nodes = 0; + xc_physinfo_t physinfo; + + if ( max_nodes ) + return max_nodes; + + if ( !xc_physinfo(xch, &physinfo) ) + max_nodes = physinfo.max_node_id + 1; + + return max_nodes; +} + int xc_get_cpumap_size(xc_interface *xch) { return (xc_get_max_cpus(xch) + 7) / 8; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 15bf8d28cb..91fbb02979 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -329,6 +329,12 @@ int xc_get_cpumap_size(xc_interface *xch); /* allocate a cpumap */ xc_cpumap_t xc_cpumap_alloc(xc_interface *xch); + /* + * NODEMAP handling + */ +/* return maximum number of NUMA nodes the hypervisor supports */ +int xc_get_max_nodes(xc_interface *xch); + /* * DOMAIN DEBUGGING FUNCTIONS */ diff --git a/tools/libxl/libxl.c b/tools/libxl/libxl.c index 9f301a9098..2ecdce3efd 100644 --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -3298,6 +3298,75 @@ fail: return ret; } +libxl_numainfo *libxl_get_numainfo(libxl_ctx *ctx, int *nr) +{ + GC_INIT(ctx); + xc_numainfo_t ninfo; + DECLARE_HYPERCALL_BUFFER(xc_node_to_memsize_t, memsize); + DECLARE_HYPERCALL_BUFFER(xc_node_to_memfree_t, memfree); + DECLARE_HYPERCALL_BUFFER(uint32_t, node_dists); + libxl_numainfo *ret = NULL; + int i, j, max_nodes; + + max_nodes = libxl_get_max_nodes(ctx); + if (max_nodes == 0) + { + LIBXL__LOG(ctx, XTL_ERROR, "Unable to determine number of NODES"); + ret = NULL; + goto out; + } + + memsize = xc_hypercall_buffer_alloc + (ctx->xch, memsize, sizeof(*memsize) * max_nodes); + memfree = xc_hypercall_buffer_alloc + (ctx->xch, memfree, sizeof(*memfree) * max_nodes); + node_dists = xc_hypercall_buffer_alloc + (ctx->xch, node_dists, sizeof(*node_dists) * max_nodes * max_nodes); + if ((memsize == NULL) || (memfree == NULL) || (node_dists == NULL)) { + LIBXL__LOG_ERRNOVAL(ctx, XTL_ERROR, ENOMEM, + "Unable to allocate hypercall arguments"); + goto fail; + } + + set_xen_guest_handle(ninfo.node_to_memsize, memsize); + set_xen_guest_handle(ninfo.node_to_memfree, memfree); + set_xen_guest_handle(ninfo.node_to_node_distance, node_dists); + ninfo.max_node_index = max_nodes - 1; + if (xc_numainfo(ctx->xch, &ninfo) != 0) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "getting numainfo"); + goto fail; + } + + if (ninfo.max_node_index < max_nodes - 1) + max_nodes = ninfo.max_node_index + 1; + + *nr = max_nodes; + + ret = libxl__zalloc(NOGC, sizeof(libxl_numainfo) * max_nodes); + for (i = 0; i < max_nodes; i++) + ret[i].dists = libxl__calloc(NOGC, max_nodes, sizeof(*node_dists)); + + for (i = 0; i < max_nodes; i++) { +#define V(mem, i) (mem[i] == INVALID_NUMAINFO_ID) ? \ + LIBXL_NUMAINFO_INVALID_ENTRY : mem[i] + ret[i].size = V(memsize, i); + ret[i].free = V(memfree, i); + ret[i].num_dists = max_nodes; + for (j = 0; j < ret[i].num_dists; j++) + ret[i].dists[j] = V(node_dists, i * max_nodes + j); +#undef V + } + + fail: + xc_hypercall_buffer_free(ctx->xch, memsize); + xc_hypercall_buffer_free(ctx->xch, memfree); + xc_hypercall_buffer_free(ctx->xch, node_dists); + + out: + GC_FREE; + return ret; +} + const libxl_version_info* libxl_get_version_info(libxl_ctx *ctx) { union { diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index 371b659434..cb18eda9d5 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -532,6 +532,9 @@ int libxl_domain_preserve(libxl_ctx *ctx, uint32_t domid, libxl_domain_create_in /* get max. number of cpus supported by hypervisor */ int libxl_get_max_cpus(libxl_ctx *ctx); +/* get max. number of NUMA nodes supported by hypervisor */ +int libxl_get_max_nodes(libxl_ctx *ctx); + int libxl_domain_rename(libxl_ctx *ctx, uint32_t domid, const char *old_name, const char *new_name); @@ -604,6 +607,10 @@ void libxl_vminfo_list_free(libxl_vminfo *list, int nb_vm); libxl_cputopology *libxl_get_cpu_topology(libxl_ctx *ctx, int *nb_cpu_out); void libxl_cputopology_list_free(libxl_cputopology *, int nb_cpu); +#define LIBXL_NUMAINFO_INVALID_ENTRY (~(uint32_t)0) +libxl_numainfo *libxl_get_numainfo(libxl_ctx *ctx, int *nr); +void libxl_numainfo_list_free(libxl_numainfo *, int nr); + libxl_vcpuinfo *libxl_list_vcpu(libxl_ctx *ctx, uint32_t domid, int *nb_vcpu, int *nr_vcpus_out); void libxl_vcpuinfo_list_free(libxl_vcpuinfo *, int nr_vcpus); diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 00947e1875..2735ebd82a 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -433,6 +433,15 @@ libxl_physinfo = Struct("physinfo", [ ("cap_hvm_directio", bool), ], dir=DIR_OUT) +# NUMA node characteristics: size and free are how much memory it has, and how +# much of it is free, respectively. dists is an array of distances from this +# node to each other node. +libxl_numainfo = Struct("numainfo", [ + ("size", uint64), + ("free", uint64), + ("dists", Array(uint32, "num_dists")), + ], dir=DIR_OUT) + libxl_cputopology = Struct("cputopology", [ ("core", uint32), ("socket", uint32), diff --git a/tools/libxl/libxl_utils.c b/tools/libxl/libxl_utils.c index f69a24c267..29f430d977 100644 --- a/tools/libxl/libxl_utils.c +++ b/tools/libxl/libxl_utils.c @@ -572,6 +572,11 @@ int libxl_get_max_cpus(libxl_ctx *ctx) return xc_get_max_cpus(ctx->xch); } +int libxl_get_max_nodes(libxl_ctx *ctx) +{ + return xc_get_max_nodes(ctx->xch); +} + int libxl__enum_from_string(const libxl_enum_string_table *t, const char *s, int *e) { @@ -594,6 +599,14 @@ void libxl_cputopology_list_free(libxl_cputopology *list, int nr) free(list); } +void libxl_numainfo_list_free(libxl_numainfo *list, int nr) +{ + int i; + for (i = 0; i < nr; i++) + libxl_numainfo_dispose(&list[i]); + free(list); +} + void libxl_vcpuinfo_list_free(libxl_vcpuinfo *list, int nr) { int i; diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h index 88ec803cfd..3225b2ae42 100644 --- a/xen/include/public/sysctl.h +++ b/xen/include/public/sysctl.h @@ -484,6 +484,7 @@ typedef struct xen_sysctl_topologyinfo xen_sysctl_topologyinfo_t; DEFINE_XEN_GUEST_HANDLE(xen_sysctl_topologyinfo_t); /* XEN_SYSCTL_numainfo */ +#define INVALID_NUMAINFO_ID (~0U) struct xen_sysctl_numainfo { /* * IN: maximum addressable entry in the caller-provided arrays. |