diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index 716f7af99b..3c6a54ac36 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -219,9 +219,12 @@ struct _virNodeInfo { unsigned long memory;/* memory size in kilobytes */ unsigned int cpus; /* the number of active CPUs */ unsigned int mhz; /* expected CPU frequency */ - unsigned int nodes; /* the number of NUMA cell, 1 for uniform mem access */ - unsigned int sockets;/* number of CPU socket per node */ - unsigned int cores; /* number of core per socket */ + unsigned int nodes; /* the number of NUMA cell, 1 for unusual NUMA + topologies or uniform memory access; check + capabilities XML for the actual NUMA topology */ + unsigned int sockets;/* number of CPU sockets per node if nodes > 1, + total number of CPU sockets otherwise */ + unsigned int cores; /* number of cores per socket */ unsigned int threads;/* number of threads per core */ }; diff --git a/src/nodeinfo.c b/src/nodeinfo.c index 9be2a02f55..acd3188472 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -305,6 +305,16 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, return -1; } + /* nodeinfo->sockets is supposed to be a number of sockets per NUMA node, + * however if NUMA nodes are not composed of whole sockets, we just lie + * about the number of NUMA nodes and force apps to check capabilities XML + * for the actual NUMA topology. + */ + if (nodeinfo->sockets % nodeinfo->nodes == 0) + nodeinfo->sockets /= nodeinfo->nodes; + else + nodeinfo->nodes = 1; + return 0; } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 44501950ac..6ce0c3fe7d 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2497,12 +2497,21 @@ sexpr_to_xend_node_info(const struct sexpr *root, virNodeInfoPtr info) if (procs == 0) /* Sanity check in case of Xen bugs in futures..*/ return (-1); info->sockets = nr_cpus / procs; - /* Should already be fine, but for further sanity make - * sure we have at least one socket - */ - if (info->sockets == 0) - info->sockets = 1; } + + /* On systems where NUMA nodes are not composed of whole sockets either Xen + * provided us wrong number of sockets per node or we computed the wrong + * number in the compatibility code above. In such case, we compute the + * correct number of sockets on the host, lie about the number of NUMA + * nodes, and force apps to check capabilities XML for the actual NUMA + * topology. + */ + if (info->nodes * info->sockets * info->cores * info->threads + != info->cpus) { + info->nodes = 1; + info->sockets = info->cpus / (info->cores * info->threads); + } + return (0); }