https://bugzilla.redhat.com/show_bug.cgi?id=1176020 We had a check for the vcpu count total number in <numa> before, however this check is not good enough. There are some examples: 1. one of cpu id is out of maxvcpus, can set success(cpu count = 5 < 10): <vcpu placement='static'>10</vcpu> <cell id='0' cpus='0-3,100' memory='512000' unit='KiB'/> 2. use the same cpu in 2 cell, can set success(cpu count = 8 < 10): <vcpu placement='static'>10</vcpu> <cell id='0' cpus='0-3' memory='512000' unit='KiB'/> <cell id='1' cpus='0-3' memory='512000' unit='KiB'/> 3. use the same cpu in 2 cell, cannot set success(cpu count = 11 > 10): <vcpu placement='static'>10</vcpu> <cell id='0' cpus='0-6' memory='512000' unit='KiB'/> <cell id='1' cpus='0-3' memory='512000' unit='KiB'/> Use a new check for numa cpus, check if use a cpu exceeds maxvcpus and if duplicate use one cpu in more than one cell. Signed-off-by: Luyao Huang <lhuang@xxxxxxxxxx> --- src/conf/domain_conf.c | 12 ++++-------- src/conf/numa_conf.c | 37 ++++++++++++++++++++++++++++++------- src/conf/numa_conf.h | 2 +- 3 files changed, 35 insertions(+), 16 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 831f033..3a5eb1f 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -13510,7 +13510,10 @@ virDomainThreadSchedParse(xmlNodePtr node, static int virDomainDefNewCheck(virDomainDefPtr def) { - /*TO DO*/ + if (def->numa && + (virDomainNumaCheckCPU(def->numa, def->maxvcpus) < 0)) + return -1; + return 0; } @@ -14141,13 +14144,6 @@ virDomainDefParseXML(xmlDocPtr xml, if (virDomainNumaDefCPUParseXML(def->numa, ctxt) < 0) goto error; - if (virDomainNumaGetCPUCountTotal(def->numa) > def->maxvcpus) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Number of CPUs in <numa> exceeds the" - " <vcpu> count")); - goto error; - } - if (virDomainNumatuneParseXML(def->numa, def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_STATIC, diff --git a/src/conf/numa_conf.c b/src/conf/numa_conf.c index 8a0f686..0191a22 100644 --- a/src/conf/numa_conf.c +++ b/src/conf/numa_conf.c @@ -790,16 +790,39 @@ virDomainNumaDefCPUFormat(virBufferPtr buf, } -unsigned int -virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa) +int +virDomainNumaCheckCPU(virDomainNumaPtr numa, + unsigned short maxvcpus) { - size_t i; - unsigned int ret = 0; + size_t i,j; - for (i = 0; i < numa->nmem_nodes; i++) - ret += virBitmapCountBits(virDomainNumaGetNodeCpumask(numa, i)); + for (i = 0; i < numa->nmem_nodes; i++) { + virBitmapPtr nodeset = NULL; + ssize_t bit = -1; + + nodeset = virDomainNumaGetNodeCpumask(numa, i); + for (j = 0; j < i; j++) { + if (virBitmapOverlaps(virDomainNumaGetNodeCpumask(numa, j), + nodeset)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot binding one vCPU in 2 NUMA cell" + " %d and %d"), (int) i, (int) j); + return -1; + } + } - return ret; + while ((bit = virBitmapNextSetBit(nodeset, bit)) >= 0) { + if (bit <= maxvcpus-1) + continue; + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("vcpu '%d' in <numa> cell '%d' exceeds the maxvcpus"), + (int) bit, (int) i); + return -1; + } + } + + return 0; } diff --git a/src/conf/numa_conf.h b/src/conf/numa_conf.h index ded6e01..d7713c8 100644 --- a/src/conf/numa_conf.h +++ b/src/conf/numa_conf.h @@ -149,7 +149,7 @@ bool virDomainNumatuneNodeSpecified(virDomainNumaPtr numatune, int virDomainNumaDefCPUParseXML(virDomainNumaPtr def, xmlXPathContextPtr ctxt); int virDomainNumaDefCPUFormat(virBufferPtr buf, virDomainNumaPtr def); -unsigned int virDomainNumaGetCPUCountTotal(virDomainNumaPtr numa); +int virDomainNumaCheckCPU(virDomainNumaPtr numa, unsigned short maxvcpus); #endif /* __NUMA_CONF_H__ */ -- 1.8.3.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list