typedef struct _virNodeInfo virNodeInfo;
struct _virNodeInfo {
- char model[32]; /* string indicating the CPU model */
- 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 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 */
+ char model[32]; /* string indicating the CPU model */
+ 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 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,
+ 1 in case of unusual NUMA topology */
+ unsigned int cores; /* number of cores per socket, total number of
+ processors in case of unusual NUMA topology*/
+ unsigned int threads; /* number of threads per core, 1 in case of
+ unusual numa topology */
};
/**
static int
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2)
ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4)
-virNodeParseNode(const char *node, int *sockets, int *cores, int *threads)
+ATTRIBUTE_NONNULL(5)
+virNodeParseNode(const char *node,
+ int *sockets,
+ int *cores,
+ int *threads,
+ int *offline)
{
int ret = -1;
int processors = 0;
if ((online = virNodeGetCpuValue(node, cpu, "online", true)) < 0)
goto cleanup;
- if (!online)
+ if (!online) {
+ (*offline)++;
continue;
+ }
processors++;
char line[1024];
DIR *nodedir = NULL;
struct dirent *nodedirent = NULL;
- int cpus, cores, socks, threads;
+ int cpus, cores, socks, threads, offline = 0;
unsigned int node;
int ret = -1;
char *sysfs_nodedir = NULL;
goto cleanup;
}
- if ((cpus = virNodeParseNode(sysfs_cpudir, &socks,
- &cores, &threads)) < 0)
+ if ((cpus = virNodeParseNode(sysfs_cpudir, &socks, &cores,
+ &threads, &offline)) < 0)
goto cleanup;
VIR_FREE(sysfs_cpudir);
goto cleanup;
}
- if ((cpus = virNodeParseNode(sysfs_cpudir, &socks, &cores, &threads)) < 0)
+ if ((cpus = virNodeParseNode(sysfs_cpudir, &socks, &cores,
+ &threads, &offline)) < 0)
goto cleanup;
nodeinfo->nodes = 1;
goto cleanup;
}
+ /* Now check if the topology makes sense. There are machines that don't
+ * expose their real number of nodes or for example the AMD Bulldozer
+ * architecture that exposes their Clustered integer core modules as both
+ * threads and cores. This approach throws off our detection. Unfortunately
+ * the nodeinfo structure isn't designed to carry the full topology so
+ * we're going to lie about the detected topology to notify the user
+ * to check the host capabilities for the actual topology. */
+ if ((nodeinfo->nodes *
+ nodeinfo->sockets *
+ nodeinfo->cores *
+ nodeinfo->threads) != (nodeinfo->cpus + offline)) {
+ nodeinfo->nodes = 1;
+ nodeinfo->sockets = 1;
+ nodeinfo->cores = nodeinfo->cpus + offline;
+ nodeinfo->threads = 1;
+ }
+
ret = 0;
cleanup: