aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/libxc/xc_misc.c14
-rw-r--r--tools/libxc/xenctrl.h6
-rw-r--r--tools/libxl/libxl.c69
-rw-r--r--tools/libxl/libxl.h7
-rw-r--r--tools/libxl/libxl_types.idl9
-rw-r--r--tools/libxl/libxl_utils.c13
-rw-r--r--xen/include/public/sysctl.h1
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.