[PATCH v2 1/2] Handle non-sequential NUMA node numbers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On some platforms like IBM PowerNV the NUMA node numbers can be
non-sequential. For eg. numactl --hardware o/p from such a machine looks
as given below

node distances:
   node   0   1  16  17
     0:  10  40  40  40
     1:  40  10  40  40
    16:  40  40  10  40
    17:  40  40  40  10

The NUMA nodes are 0,1,16,17

Libvirt uses sequential index as NUMA node numbers and this can
result in crash or incorrect results.

Signed-off-by: Shivaprasad G Bhat <sbhat@xxxxxxxxxxxxxxxxxx>
Signed-off-by: Pradipta Kr. Banerjee <bpradip@xxxxxxxxxx>
---
 src/conf/capabilities.c | 12 ++++++++++--
 src/qemu/qemu_driver.c  |  5 +++--
 src/qemu/qemu_process.c |  2 +-
 3 files changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
index 726ec3f..78f65cb 100644
--- a/src/conf/capabilities.c
+++ b/src/conf/capabilities.c
@@ -1000,10 +1000,18 @@ virCapabilitiesGetCpusForNode(virCapsPtr caps,
                               size_t node,
                               virBitmapPtr cpumask)
 {
-    virCapsHostNUMACellPtr cell = caps->host.numaCell[node];
+    virCapsHostNUMACellPtr cell = NULL;
     size_t cpu;
+    size_t index;
+    /* The numa node numbers can be non-contiguous. Ex: 0,1,16,17. */
+    for (index = 0; index < caps->host.nnumaCell; index++) {
+        if (caps->host.numaCell[index]->num == node) {
+            cell = caps->host.numaCell[index];
+            break;
+        }
+    }
 
-    for (cpu = 0; cpu < cell->ncpus; cpu++) {
+    for (cpu = 0; cell && cpu < cell->ncpus; cpu++) {
         if (virBitmapSetBit(cpumask, cell->cpus[cpu].id) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("Cpu '%u' in node '%zu' is out of range "
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 944facb..cb63b60 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8566,12 +8566,13 @@ qemuDomainSetNumaParamsLive(virDomainObjPtr vm,
 
     for (i = 0; i < caps->host.nnumaCell; i++) {
         bool result;
-        if (virBitmapGetBit(nodeset, i, &result) < 0) {
+        virCapsHostNUMACellPtr cell = caps->host.numaCell[i];
+        if (virBitmapGetBit(nodeset, cell->num, &result) < 0) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Failed to get cpuset bit values"));
             goto cleanup;
         }
-        if (result && (virBitmapSetBit(temp_nodeset, i) < 0)) {
+        if (result && (virBitmapSetBit(temp_nodeset, cell->num) < 0)) {
             virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                            _("Failed to set temporary cpuset bit values"));
             goto cleanup;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8bcd98e..c28f84d 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -2002,7 +2002,7 @@ qemuPrepareCpumap(virQEMUDriverPtr driver,
             size_t j;
             int cur_ncpus = caps->host.numaCell[i]->ncpus;
             bool result;
-            if (virBitmapGetBit(nodemask, i, &result) < 0) {
+            if (virBitmapGetBit(nodemask, caps->host.numaCell[i]->num, &result) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                _("Failed to convert nodeset to cpuset"));
                 virBitmapFree(cpumap);
-- 
1.8.5.3

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list




[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]