return false;
}
+
+int
+virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune)
+{
+ int ret = -1;
+ virBitmapPtr nodemask = NULL;
+ size_t i;
+ int bit;
+
+ if (!numatune)
+ return ret;
+
+ nodemask = virDomainNumatuneGetNodeset(numatune, NULL, -1);
+ if (nodemask)
+ ret = virBitmapLastSetBit(nodemask);
+
+ for (i = 0; i < numatune->nmem_nodes; i++) {
+ nodemask = numatune->mem_nodes[i].nodeset;
+ if (!nodemask)
+ continue;
+
+ bit = virBitmapLastSetBit(nodemask);
+ if (bit > ret)
+ ret = bit;
+ }
+
+ return ret;
+}
bool virDomainNumatuneHasPerNodeBinding(virDomainNumatunePtr numatune);
+int virDomainNumatuneSpecifiedMaxNode(virDomainNumatunePtr numatune);
#endif /* __NUMATUNE_CONF_H__ */
virNumaGetPages;
virNumaIsAvailable;
virNumaNodeIsAvailable;
+virNumaNodesetIsAvailable;
virNumaSetPagePoolSize;
virNumaSetupMemoryPolicy;
#include "virstoragefile.h"
#include "virtpm.h"
#include "virscsi.h"
+#include "virnuma.h"
#if defined(__linux__)
# include <linux/capability.h>
#endif
goto cleanup;
}
+ if (!virNumaNodesetIsAvailable(def->numatune))
+ goto cleanup;
+
for (i = 0; i < def->mem.nhugepages; i++) {
ssize_t next_bit, pos = 0;
return ret;
}
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+ int maxnode;
+ int bit;
+
+ if (!numatune)
+ return true;
+
+ bit = virDomainNumatuneSpecifiedMaxNode(numatune);
+ if (bit < 0)
+ return true;
+
+ if ((maxnode = virNumaGetMaxNode()) < 0)
+ return false;
+
+ maxnode = maxnode < NUMA_NUM_NODES ? maxnode : NUMA_NUM_NODES;
+ if (bit > maxnode)
+ goto error;
+
+ return true;
+
+ error:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("NUMA node %d is out of range"), bit);
+ return false;
+}
bool
virNumaIsAvailable(void)
return 0;
}
+bool
+virNumaNodesetIsAvailable(virDomainNumatunePtr numatune)
+{
+ if (virDomainNumatuneSpecifiedMaxNode(numatune) >= 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("libvirt is compiled without NUMA tuning support"));
+ return false;
+ }
+
+ return true;
+}
bool
virNumaIsAvailable(void)
int virNumaSetupMemoryPolicy(virDomainNumatunePtr numatune,
virBitmapPtr nodemask);
+bool virNumaNodesetIsAvailable(virDomainNumatunePtr numatune);
bool virNumaIsAvailable(void);
int virNumaGetMaxNode(void);
bool virNumaNodeIsAvailable(int node);
--- /dev/null
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>1048576</memory>
+ <currentMemory unit='KiB'>1048576</currentMemory>
+ <vcpu placement='static'>4</vcpu>
+ <numatune>
+ <memnode cellid='0' mode='strict' nodeset='0-8'/>
+ <memnode cellid='1' mode='strict' nodeset='0'/>
+ </numatune>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <cpu>
+ <numa>
+ <cell id='0' cpus='0-1' memory='524288'/>
+ <cell id='1' cpus='2-3' memory='524288'/>
+ </numa>
+ </cpu>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
#include <config.h>
#include "internal.h"
+#include "virnuma.h"
#include <time.h>
time_t time(time_t *t)
*t = ret;
return ret;
}
+
+int
+virNumaGetMaxNode(void)
+{
+ const int maxnodesNum = 7;
+
+ return maxnodesNum;
+}
DO_TEST_FAILURE("numatune-memnode-no-memory", NONE);
DO_TEST("numatune-auto-nodeset-invalid", NONE);
+ DO_TEST_FAILURE("numatune-static-nodeset-exceed-hostnode",
+ QEMU_CAPS_OBJECT_MEMORY_RAM);
DO_TEST_PARSE_ERROR("numatune-memnode-nocpu", NONE);
DO_TEST_PARSE_ERROR("numatune-memnodes-problematic", NONE);
DO_TEST("numad", NONE);