"Instead of developing one CPU with 12 cores, the Magny Cours is actually two 6 core “Bulldozer” CPUs combined in to one package" I.e, each package has two NUMA nodes, and the two numa nodes share the same core ID set (0-6), which means parsing the cores number from sysfs doesn't work in this case. And the wrong CPU number could cause three problems for libvirt: 1) performance lost A domain without "cpuset" or "placement='auto'" (to drive numad) specified will be only pinned to part of the CPUs. 2) domain can be started If a domain uses numad, and the advisory nodeset returned from numad contains node which exceeds the range of wrong total CPU number. The domain will fail to start, as the bitmask passed to sched_setaffinity could be fully filled with zero. 3) wrong CPU number affects lots of stuffs. E.g. for command "virsh vcpuinfo", "virsh vcpupin", it will always output with the truncated CPU list. For more details: https://www.redhat.com/archives/libvir-list/2012-May/msg00607.html This patch is to fix the problem by parsing /proc/cpuinfo to get the value of field "cpu cores", and use it as nodeinfo->cores if it's greater than the cores number from sysfs. --- src/nodeinfo.c | 27 ++++++++++++++++++++ .../linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt | 2 +- 2 files changed, 28 insertions(+), 1 deletions(-) diff --git a/src/nodeinfo.c b/src/nodeinfo.c index cd8a806..e1d8ae4 100644 --- a/src/nodeinfo.c +++ b/src/nodeinfo.c @@ -237,6 +237,7 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, int online; int ret = -1; char *sysfs_cpudir = NULL; + unsigned int cpu_cores = 0; nodeinfo->cpus = 0; nodeinfo->mhz = 0; @@ -265,6 +266,22 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, && (*p == '\0' || *p == '.' || c_isspace(*p))) nodeinfo->mhz = ui; } + + if (STRPREFIX(buf, "cpu cores")) { + char *p; + unsigned int ui; + buf += 9; + while (*buf && c_isspace(*buf)) + buf++; + if (*buf != ':' || !buf[1]) { + nodeReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("parsing cpuinfo cpu MHz")); + return -1; + } + if (virStrToLong_ui(buf+1, &p, 10, &ui) == 0 + && (*p == '\0' || c_isspace(*p))) + cpu_cores = ui; + } # elif defined(__powerpc__) || \ defined(__powerpc64__) char *buf = line; @@ -377,6 +394,16 @@ int linuxNodeInfoCPUPopulate(FILE *cpuinfo, goto cleanup; } + /* Platform like AMD Magny Cours has two NUMA nodes each package, and + * the two nodes share the same core ID set, it results in the cores + * number calculated from sysfs is not the actual cores number. Use + * "cpu cores" in /proc/cpuinfo as the cores number instead in this case. + * More details about the problem: + * https://www.redhat.com/archives/libvir-list/2012-May/msg00607.html + */ + if (cpu_cores && (cpu_cores > nodeinfo->cores)) + nodeinfo->cores = cpu_cores; + /* 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 diff --git a/tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt b/tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt index e3c046b..7db3864 100644 --- a/tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt +++ b/tests/nodeinfodata/linux-nodeinfo-sysfs-test-3-cpu-x86-output.txt @@ -1 +1 @@ -CPUs: 48, MHz: 2100, Nodes: 1, Cores: 6 +CPUs: 48, MHz: 2100, Nodes: 1, Cores: 12 -- 1.7.7.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list