From e8e641e161b26dd08227d56054946449e9a1a437 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: May 09 2023 10:16:03 +0000 Subject: import libvirt-9.0.0-10.1.el9_2 --- diff --git a/SOURCES/libvirt-conf-Fix-migration-in-some-firmware-autoselection-scenarios.patch b/SOURCES/libvirt-conf-Fix-migration-in-some-firmware-autoselection-scenarios.patch new file mode 100644 index 0000000..a7a7882 --- /dev/null +++ b/SOURCES/libvirt-conf-Fix-migration-in-some-firmware-autoselection-scenarios.patch @@ -0,0 +1,225 @@ +From e4b040f7a05e4b160a62cd0ce1bdffed7efe8dfa Mon Sep 17 00:00:00 2001 +Message-Id: +From: Andrea Bolognani +Date: Tue, 11 Apr 2023 17:56:45 +0200 +Subject: [PATCH] conf: Fix migration in some firmware autoselection scenarios +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Introduce a small kludge in the parser to avoid unnecessarily +blocking incoming migration from a range of recent libvirt +releases. + +https://bugzilla.redhat.com/show_bug.cgi?id=2184966 + +Signed-off-by: Andrea Bolognani +Reviewed-by: Ján Tomko +(cherry picked from commit f9ad3023355bcbfc692bbe4997fdfa774866a980) + +Conflicts: + + * tests/qemuxml2argvtest.c + * tests/qemuxml2xmltest.c + - missing unrelated changes to surrounding code + + * tests/qemuxml2argvdata/firmware-manual-efi-features.x86_64-latest.args + * tests/qemuxml2xmloutdata/firmware-manual-efi-features.x86_64-latest.xml + - had to be regenerated to account for differences in the + input file, as well as the test code and the behavior of + the firmware selection feature. In particular, the + reference to /bad-test-used-env-home/ is caused by the + fact that qemuxml2xmltest, unlike qemuxml2argvtest, + didn't set cfg->nvramDir before e62db9ee5b..e6c1ca3d11 + +https://bugzilla.redhat.com/show_bug.cgi?id=2186383 + +Signed-off-by: Andrea Bolognani +--- + src/conf/domain_conf.c | 39 ++++++++++++++++++- + ...are-manual-efi-features.x86_64-latest.args | 35 +++++++++++++++++ + tests/qemuxml2argvtest.c | 6 ++- + ...ware-manual-efi-features.x86_64-latest.xml | 32 +++++++++++++++ + tests/qemuxml2xmltest.c | 1 + + 5 files changed, 110 insertions(+), 3 deletions(-) + create mode 100644 tests/qemuxml2argvdata/firmware-manual-efi-features.x86_64-latest.args + create mode 100644 tests/qemuxml2xmloutdata/firmware-manual-efi-features.x86_64-latest.xml + +diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c +index 733399e6da..89637bb282 100644 +--- a/src/conf/domain_conf.c ++++ b/src/conf/domain_conf.c +@@ -17021,11 +17021,13 @@ virDomainDefParseBootKernelOptions(virDomainDef *def, + + static int + virDomainDefParseBootFirmwareOptions(virDomainDef *def, +- xmlXPathContextPtr ctxt) ++ xmlXPathContextPtr ctxt, ++ unsigned int flags) + { + g_autofree char *firmware = virXPathString("string(./os/@firmware)", ctxt); + g_autofree xmlNodePtr *nodes = NULL; + g_autofree int *features = NULL; ++ bool abiUpdate = !!(flags & VIR_DOMAIN_DEF_PARSE_ABI_UPDATE); + int fw = 0; + int n = 0; + size_t i; +@@ -17033,6 +17035,39 @@ virDomainDefParseBootFirmwareOptions(virDomainDef *def, + if ((n = virXPathNodeSet("./os/firmware/feature", ctxt, &nodes)) < 0) + return -1; + ++ /* Migration compatibility kludge. ++ * ++ * Between 8.6.0 and 9.1.0 (extremes included), the migratable ++ * XML produced when feature-based firmware autoselection was ++ * enabled looked like ++ * ++ * ++ * ++ * ++ * ++ * Notice how there's no firmware='foo' attribute for the ++ * element, meaning that firmware autoselection is disabled, and ++ * yet some elements, which are used to control the ++ * firmware autoselection process, are present. We don't consider ++ * this to be a valid combination, and want such a configuration ++ * to get rejected when submitted by users. ++ * ++ * In order to achieve that, while at the same time keeping ++ * migration coming from the libvirt versions listed above ++ * working, we can simply stop parsing early and ignore the ++ * tags when firmware autoselection is not enabled, ++ * *except* if we're defining a new domain. ++ * ++ * This is safe to do because the configuration will either come ++ * from another libvirt instance, in which case it will have a ++ * properly filled in element that contains enough ++ * information to successfully define and start the domain, or it ++ * will be a random configuration that lacks such information, in ++ * which case a different failure will be reported anyway. ++ */ ++ if (n > 0 && !firmware && !abiUpdate) ++ return 0; ++ + if (n > 0) + features = g_new0(int, VIR_DOMAIN_OS_DEF_FIRMWARE_FEATURE_LAST); + +@@ -17161,7 +17196,7 @@ virDomainDefParseBootOptions(virDomainDef *def, + case VIR_DOMAIN_OSTYPE_HVM: + virDomainDefParseBootKernelOptions(def, ctxt); + +- if (virDomainDefParseBootFirmwareOptions(def, ctxt) < 0) ++ if (virDomainDefParseBootFirmwareOptions(def, ctxt, flags) < 0) + return -1; + + if (virDomainDefParseBootLoaderOptions(def, ctxt, xmlopt, flags) < 0) +diff --git a/tests/qemuxml2argvdata/firmware-manual-efi-features.x86_64-latest.args b/tests/qemuxml2argvdata/firmware-manual-efi-features.x86_64-latest.args +new file mode 100644 +index 0000000000..db6c6d06bc +--- /dev/null ++++ b/tests/qemuxml2argvdata/firmware-manual-efi-features.x86_64-latest.args +@@ -0,0 +1,35 @@ ++LC_ALL=C \ ++PATH=/bin \ ++HOME=/tmp/lib/domain--1-test \ ++USER=test \ ++LOGNAME=test \ ++XDG_DATA_HOME=/tmp/lib/domain--1-test/.local/share \ ++XDG_CACHE_HOME=/tmp/lib/domain--1-test/.cache \ ++XDG_CONFIG_HOME=/tmp/lib/domain--1-test/.config \ ++/usr/bin/qemu-system-x86_64 \ ++-name guest=test,debug-threads=on \ ++-S \ ++-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-test/master-key.aes"}' \ ++-blockdev '{"driver":"file","filename":"/usr/share/OVMF/OVMF_CODE.fd","node-name":"libvirt-pflash0-storage","auto-read-only":true,"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash0-format","read-only":true,"driver":"raw","file":"libvirt-pflash0-storage"}' \ ++-blockdev '{"driver":"file","filename":"/var/lib/libvirt/qemu/nvram/test_VARS.fd","node-name":"libvirt-pflash1-storage","auto-read-only":true,"discard":"unmap"}' \ ++-blockdev '{"node-name":"libvirt-pflash1-format","read-only":false,"driver":"raw","file":"libvirt-pflash1-storage"}' \ ++-machine pc,usb=off,dump-guest-core=off,memory-backend=pc.ram,pflash0=libvirt-pflash0-format,pflash1=libvirt-pflash1-format \ ++-accel tcg \ ++-cpu qemu64 \ ++-m 1024 \ ++-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":1073741824}' \ ++-overcommit mem-lock=off \ ++-smp 1,sockets=1,cores=1,threads=1 \ ++-uuid 362d1fc1-df7d-193e-5c18-49a71bd1da66 \ ++-display none \ ++-no-user-config \ ++-nodefaults \ ++-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ ++-mon chardev=charmonitor,id=monitor,mode=control \ ++-rtc base=utc \ ++-no-shutdown \ ++-boot strict=on \ ++-audiodev '{"id":"audio1","driver":"none"}' \ ++-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ ++-msg timestamp=on +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index 3fb2d5dc74..99392335b6 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -1130,7 +1130,11 @@ mymain(void) + QEMU_CAPS_DEVICE_ISA_SERIAL); + DO_TEST_NOCAPS("firmware-manual-efi"); + DO_TEST_PARSE_ERROR_NOCAPS("firmware-manual-efi-no-path"); +- DO_TEST_CAPS_LATEST_PARSE_ERROR("firmware-manual-efi-features"); ++ DO_TEST_CAPS_LATEST("firmware-manual-efi-features"); ++ DO_TEST_CAPS_ARCH_LATEST_FULL("firmware-manual-efi-features", "x86_64", ++ ARG_FLAGS, FLAG_EXPECT_PARSE_ERROR, ++ ARG_PARSEFLAGS, VIR_DOMAIN_DEF_PARSE_ABI_UPDATE, ++ ARG_END); + DO_TEST_CAPS_LATEST("firmware-manual-bios-rw"); + DO_TEST_CAPS_LATEST("firmware-manual-bios-rw-implicit"); + DO_TEST("firmware-manual-efi-secure", +diff --git a/tests/qemuxml2xmloutdata/firmware-manual-efi-features.x86_64-latest.xml b/tests/qemuxml2xmloutdata/firmware-manual-efi-features.x86_64-latest.xml +new file mode 100644 +index 0000000000..d142be9899 +--- /dev/null ++++ b/tests/qemuxml2xmloutdata/firmware-manual-efi-features.x86_64-latest.xml +@@ -0,0 +1,32 @@ ++ ++ test ++ 362d1fc1-df7d-193e-5c18-49a71bd1da66 ++ 1048576 ++ 1048576 ++ 1 ++ ++ hvm ++ /usr/share/OVMF/OVMF_CODE.fd ++ /bad-test-used-env-home/.config/libvirt/qemu/nvram/test_VARS.fd ++ ++ ++ ++ ++ ++ ++ qemu64 ++ ++ ++ destroy ++ restart ++ destroy ++ ++ /usr/bin/qemu-system-x86_64 ++ ++ ++ ++ ++ ++ +diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c +index 72f724bfce..66e038558f 100644 +--- a/tests/qemuxml2xmltest.c ++++ b/tests/qemuxml2xmltest.c +@@ -936,6 +936,7 @@ mymain(void) + DO_TEST_NOCAPS("firmware-manual-bios"); + DO_TEST_NOCAPS("firmware-manual-bios-stateless"); + DO_TEST_NOCAPS("firmware-manual-efi"); ++ DO_TEST_CAPS_LATEST("firmware-manual-efi-features"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-iscsi"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-network-nbd"); + DO_TEST_CAPS_LATEST("firmware-manual-efi-nvram-file"); +-- +2.40.0 diff --git a/SOURCES/libvirt-docs-Document-memory-allocation-and-emulator-pinning-limitation.patch b/SOURCES/libvirt-docs-Document-memory-allocation-and-emulator-pinning-limitation.patch new file mode 100644 index 0000000..61fbf4a --- /dev/null +++ b/SOURCES/libvirt-docs-Document-memory-allocation-and-emulator-pinning-limitation.patch @@ -0,0 +1,34 @@ +From 20187d7bb3024537b1cc3cac1b16a835a29b905e Mon Sep 17 00:00:00 2001 +Message-Id: <20187d7bb3024537b1cc3cac1b16a835a29b905e@dist-git> +From: Michal Privoznik +Date: Wed, 8 Mar 2023 11:53:37 +0100 +Subject: [PATCH] docs: Document memory allocation and emulator pinning + limitation + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit c4b176567b5000da1fe22ecaa9afe4b8ad4b6837) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + docs/formatdomain.rst | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst +index 8fc8aeb928..e7bad33cbb 100644 +--- a/docs/formatdomain.rst ++++ b/docs/formatdomain.rst +@@ -1107,7 +1107,9 @@ influence how virtual memory pages are backed by host pages. + Using the optional ``mode`` attribute, specify when to allocate the memory by + supplying either "immediate" or "ondemand". :since:`Since 8.2.0` it is + possible to set the number of threads that hypervisor uses to allocate +- memory via ``threads`` attribute. ++ memory via ``threads`` attribute. To speed allocation process up, when ++ pinning emulator thread it's recommended to include CPUs from desired NUMA ++ nodes so that allocation threads can have their affinity set. + ``discard`` + When set and supported by hypervisor the memory content is discarded just + before guest shuts down (or when DIMM module is unplugged). Please note that +-- +2.40.0 diff --git a/SOURCES/libvirt-qemu-Add-nodemask-argument-to-qemuBuildThreadContextProps.patch b/SOURCES/libvirt-qemu-Add-nodemask-argument-to-qemuBuildThreadContextProps.patch new file mode 100644 index 0000000..f29b3c4 --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-nodemask-argument-to-qemuBuildThreadContextProps.patch @@ -0,0 +1,181 @@ +From 179240a310b8b74075f90c1580b2864aa406bf03 Mon Sep 17 00:00:00 2001 +Message-Id: <179240a310b8b74075f90c1580b2864aa406bf03@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 12:39:47 +0100 +Subject: [PATCH] qemu: Add @nodemask argument to qemuBuildThreadContextProps() + +When building a thread-context object (inside of +qemuBuildThreadContextProps()) we look at given memory-backend-* +object and look for .host-nodes attribute. This works, as long as +we need to just copy the attribute value into another +thread-context attribute. But soon we will need to adjust it. +That's the point where having the value in virBitmap comes handy. +Utilize the previous commit, which made +qemuBuildMemoryBackendProps() set the argument and pass it into +qemuBuildThreadContextProps(). + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 45222a83b76e05a522afc8743a77ca320feb72f2) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_command.c | 38 +++++++++++++++++++++----------------- + src/qemu/qemu_command.h | 3 ++- + 2 files changed, 23 insertions(+), 18 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 938332496f..346967f51c 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3490,7 +3490,8 @@ qemuBuildMemoryCellBackendProps(virDomainDef *def, + virQEMUDriverConfig *cfg, + size_t cell, + qemuDomainObjPrivate *priv, +- virJSONValue **props) ++ virJSONValue **props, ++ virBitmap **nodemask) + { + g_autofree char *alias = NULL; + virDomainMemoryDef mem = { 0 }; +@@ -3503,8 +3504,8 @@ qemuBuildMemoryCellBackendProps(virDomainDef *def, + mem.targetNode = cell; + mem.info.alias = alias; + +- return qemuBuildMemoryBackendProps(props, alias, cfg, priv, +- def, &mem, false, false, NULL); ++ return qemuBuildMemoryBackendProps(props, alias, cfg, priv, def, ++ &mem, false, false, nodemask); + } + + +@@ -3517,6 +3518,7 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd, + { + g_autoptr(virJSONValue) props = NULL; + g_autoptr(virJSONValue) tcProps = NULL; ++ virBitmap *nodemask = NULL; + g_autofree char *alias = NULL; + + if (!mem->info.alias) { +@@ -3527,11 +3529,11 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd, + + alias = g_strdup_printf("mem%s", mem->info.alias); + +- if (qemuBuildMemoryBackendProps(&props, alias, cfg, +- priv, def, mem, true, false, NULL) < 0) ++ if (qemuBuildMemoryBackendProps(&props, alias, cfg, priv, ++ def, mem, true, false, &nodemask) < 0) + return -1; + +- if (qemuBuildThreadContextProps(&tcProps, &props, priv) < 0) ++ if (qemuBuildThreadContextProps(&tcProps, &props, priv, nodemask) < 0) + return -1; + + if (tcProps && +@@ -3628,11 +3630,10 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + int + qemuBuildThreadContextProps(virJSONValue **tcProps, + virJSONValue **memProps, +- qemuDomainObjPrivate *priv) ++ qemuDomainObjPrivate *priv, ++ virBitmap *nodemask) + { + g_autoptr(virJSONValue) props = NULL; +- virJSONValue *nodemask = NULL; +- g_autoptr(virJSONValue) nodemaskCopy = NULL; + g_autofree char *tcAlias = NULL; + const char *memalias = NULL; + bool prealloc = false; +@@ -3642,7 +3643,6 @@ qemuBuildThreadContextProps(virJSONValue **tcProps, + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_THREAD_CONTEXT)) + return 0; + +- nodemask = virJSONValueObjectGetArray(*memProps, "host-nodes"); + if (!nodemask) + return 0; + +@@ -3658,12 +3658,11 @@ qemuBuildThreadContextProps(virJSONValue **tcProps, + } + + tcAlias = g_strdup_printf("tc-%s", memalias); +- nodemaskCopy = virJSONValueCopy(nodemask); + + if (virJSONValueObjectAdd(&props, + "s:qom-type", "thread-context", + "s:id", tcAlias, +- "a:node-affinity", &nodemaskCopy, ++ "m:node-affinity", nodemask, + NULL) < 0) + return -1; + +@@ -7054,17 +7053,18 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommand *cmd, + g_autoptr(virQEMUDriverConfig) cfg = virQEMUDriverGetConfig(priv->driver); + g_autoptr(virJSONValue) props = NULL; + g_autoptr(virJSONValue) tcProps = NULL; ++ virBitmap *nodemask = NULL; + virDomainMemoryDef mem = { 0 }; + + mem.size = virDomainDefGetMemoryInitial(def); + mem.targetNode = -1; + mem.info.alias = (char *) defaultRAMid; + +- if (qemuBuildMemoryBackendProps(&props, defaultRAMid, cfg, +- priv, def, &mem, false, true, NULL) < 0) ++ if (qemuBuildMemoryBackendProps(&props, defaultRAMid, cfg, priv, ++ def, &mem, false, true, &nodemask) < 0) + return -1; + +- if (qemuBuildThreadContextProps(&tcProps, &props, priv) < 0) ++ if (qemuBuildThreadContextProps(&tcProps, &props, priv, nodemask) < 0) + return -1; + + if (tcProps && +@@ -7335,6 +7335,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg, + virQEMUCaps *qemuCaps = priv->qemuCaps; + g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; + virJSONValue **nodeBackends = NULL; ++ g_autofree virBitmap **nodemask = NULL; + bool needBackend = false; + bool hmat = false; + int ret = -1; +@@ -7356,10 +7357,12 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg, + } + + nodeBackends = g_new0(virJSONValue *, ncells); ++ nodemask = g_new0(virBitmap *, ncells); + + for (i = 0; i < ncells; i++) { + if ((rc = qemuBuildMemoryCellBackendProps(def, cfg, i, priv, +- &nodeBackends[i])) < 0) ++ &nodeBackends[i], ++ &nodemask[i])) < 0) + goto cleanup; + + if (rc == 0) +@@ -7389,7 +7392,8 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg, + if (needBackend) { + g_autoptr(virJSONValue) tcProps = NULL; + +- if (qemuBuildThreadContextProps(&tcProps, &nodeBackends[i], priv) < 0) ++ if (qemuBuildThreadContextProps(&tcProps, &nodeBackends[i], ++ priv, nodemask[i]) < 0) + goto cleanup; + + if (tcProps && +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index 9074822bc5..17f326d13b 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -153,7 +153,8 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + int + qemuBuildThreadContextProps(virJSONValue **tcProps, + virJSONValue **memProps, +- qemuDomainObjPrivate *priv); ++ qemuDomainObjPrivate *priv, ++ virBitmap *nodemask); + + /* Current, best practice */ + virJSONValue * +-- +2.40.0 diff --git a/SOURCES/libvirt-qemu-Add-nodemaskRet-argument-to-qemuBuildMemoryBackendProps.patch b/SOURCES/libvirt-qemu-Add-nodemaskRet-argument-to-qemuBuildMemoryBackendProps.patch new file mode 100644 index 0000000..deb935b --- /dev/null +++ b/SOURCES/libvirt-qemu-Add-nodemaskRet-argument-to-qemuBuildMemoryBackendProps.patch @@ -0,0 +1,127 @@ +From b0e9d41346a272bbe33ce1da7f7dd015a58747e1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 7 Mar 2023 12:02:11 +0100 +Subject: [PATCH] qemu: Add @nodemaskRet argument to + qemuBuildMemoryBackendProps() + +While it's true that anybody who's interested in getting +.host-nodes attribute value can just use +virJSONValueObjectGetArray() (and that's exactly what +qemuBuildThreadContextProps() is doing, btw), if somebody is +interested in getting the actual virBitmap, they would have to +parse the JSON array. + +Instead, introduce an argument to qemuBuildMemoryBackendProps() +which is set to corresponding value used when formatting the +attribute. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 9f26f6cc4bd6161a1978b8703005b9916270d382) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_command.c | 14 ++++++++++---- + src/qemu/qemu_command.h | 4 +++- + src/qemu/qemu_hotplug.c | 2 +- + 3 files changed, 14 insertions(+), 6 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 436df47eaa..938332496f 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3234,6 +3234,7 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg, + * @def: domain definition object + * @mem: memory definition object + * @force: forcibly use one of the backends ++ * @nodemaskRet: [out] bitmap used to format .host-nodes attribute + * + * Creates a configuration object that represents memory backend of given guest + * NUMA node (domain @def and @mem). Use @priv->autoNodeset to fine tune the +@@ -3258,7 +3259,8 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, + const virDomainDef *def, + const virDomainMemoryDef *mem, + bool force, +- bool systemMemory) ++ bool systemMemory, ++ virBitmap **nodemaskRet) + { + const char *backendType = "memory-backend-file"; + virDomainNumatuneMemMode mode; +@@ -3445,6 +3447,9 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, + "S:policy", qemuNumaPolicyTypeToString(mode), + NULL) < 0) + return -1; ++ ++ if (nodemaskRet) ++ *nodemaskRet = nodemask; + } + } + +@@ -3498,7 +3503,8 @@ qemuBuildMemoryCellBackendProps(virDomainDef *def, + mem.targetNode = cell; + mem.info.alias = alias; + +- return qemuBuildMemoryBackendProps(props, alias, cfg, priv, def, &mem, false, false); ++ return qemuBuildMemoryBackendProps(props, alias, cfg, priv, ++ def, &mem, false, false, NULL); + } + + +@@ -3522,7 +3528,7 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd, + alias = g_strdup_printf("mem%s", mem->info.alias); + + if (qemuBuildMemoryBackendProps(&props, alias, cfg, +- priv, def, mem, true, false) < 0) ++ priv, def, mem, true, false, NULL) < 0) + return -1; + + if (qemuBuildThreadContextProps(&tcProps, &props, priv) < 0) +@@ -7055,7 +7061,7 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommand *cmd, + mem.info.alias = (char *) defaultRAMid; + + if (qemuBuildMemoryBackendProps(&props, defaultRAMid, cfg, +- priv, def, &mem, false, true) < 0) ++ priv, def, &mem, false, true, NULL) < 0) + return -1; + + if (qemuBuildThreadContextProps(&tcProps, &props, priv) < 0) +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index c49096a057..9074822bc5 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -22,6 +22,7 @@ + #pragma once + + #include "domain_conf.h" ++#include "virbitmap.h" + #include "vircommand.h" + #include "virenum.h" + #include "qemu_block.h" +@@ -140,7 +141,8 @@ int qemuBuildMemoryBackendProps(virJSONValue **backendProps, + const virDomainDef *def, + const virDomainMemoryDef *mem, + bool force, +- bool systemMemory); ++ bool systemMemory, ++ virBitmap **nodemaskRet); + + virJSONValue * + qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, +diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c +index 2df59873db..8e72a2c431 100644 +--- a/src/qemu/qemu_hotplug.c ++++ b/src/qemu/qemu_hotplug.c +@@ -2284,7 +2284,7 @@ qemuDomainAttachMemory(virQEMUDriver *driver, + goto cleanup; + + if (qemuBuildMemoryBackendProps(&props, objalias, cfg, +- priv, vm->def, mem, true, false) < 0) ++ priv, vm->def, mem, true, false, NULL) < 0) + goto cleanup; + + if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0) +-- +2.40.0 diff --git a/SOURCES/libvirt-qemu-Fix-qemuDomainGetEmulatorPinInfo.patch b/SOURCES/libvirt-qemu-Fix-qemuDomainGetEmulatorPinInfo.patch new file mode 100644 index 0000000..8400fee --- /dev/null +++ b/SOURCES/libvirt-qemu-Fix-qemuDomainGetEmulatorPinInfo.patch @@ -0,0 +1,49 @@ +From dc65b0e0895a556252f523b799a7144566ca388f Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 7 Mar 2023 12:31:08 +0100 +Subject: [PATCH] qemu: Fix qemuDomainGetEmulatorPinInfo() + +The order of pinning priority (at least for emulator thread) was +set by v1.2.15-rc1~58 (for cgroup code). But later, when +automatic placement was implemented into +qemuDomainGetEmulatorPinInfo(), the priority was not honored. + +Now that we have this priority code in a separate function, we +can just call that and avoid this type of error. + +Fixes: 776924e37649f2d47acd805746d5fd9325212ea5 +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 7feed1613df72acd6dbcb65513942163b56e6b3a) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_driver.c | 11 +++-------- + 1 file changed, 3 insertions(+), 8 deletions(-) + +diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c +index d00b91fe0b..fffb0a9ac5 100644 +--- a/src/qemu/qemu_driver.c ++++ b/src/qemu/qemu_driver.c +@@ -4574,14 +4574,9 @@ qemuDomainGetEmulatorPinInfo(virDomainPtr dom, + if (live) + autoCpuset = QEMU_DOMAIN_PRIVATE(vm)->autoCpuset; + +- if (def->cputune.emulatorpin) { +- cpumask = def->cputune.emulatorpin; +- } else if (def->cpumask) { +- cpumask = def->cpumask; +- } else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO && +- autoCpuset) { +- cpumask = autoCpuset; +- } else { ++ if (!(cpumask = qemuDomainEvaluateCPUMask(def, ++ def->cputune.emulatorpin, ++ autoCpuset))) { + if (!(bitmap = virHostCPUGetAvailableCPUsBitmap())) + goto cleanup; + cpumask = bitmap; +-- +2.40.0 diff --git a/SOURCES/libvirt-qemu-Move-cpuset-preference-evaluation-into-a-separate-function.patch b/SOURCES/libvirt-qemu-Move-cpuset-preference-evaluation-into-a-separate-function.patch new file mode 100644 index 0000000..b2d2a16 --- /dev/null +++ b/SOURCES/libvirt-qemu-Move-cpuset-preference-evaluation-into-a-separate-function.patch @@ -0,0 +1,88 @@ +From e917c5aa46ccffb608dad2068861e555b60e10fa Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 7 Mar 2023 12:27:05 +0100 +Subject: [PATCH] qemu: Move cpuset preference evaluation into a separate + function + +The set of if()-s that determines the preference in cpumask used +for setting things like emulatorpin, vcpupin, etc. is going to be +re-used. Separate it out into a function. + +You may think that this changes behaviour, but +qemuProcessPrepareDomainNUMAPlacement() ensures that +priv->autoCpuset is set for VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit b4ccb0dc412bcdb09863b2fa1ee65d09808a2c08) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_domain.c | 18 ++++++++++++++++++ + src/qemu/qemu_domain.h | 5 +++++ + src/qemu/qemu_process.c | 9 ++------- + 3 files changed, 25 insertions(+), 7 deletions(-) + +diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c +index 374b881146..443b6442ca 100644 +--- a/src/qemu/qemu_domain.c ++++ b/src/qemu/qemu_domain.c +@@ -12335,3 +12335,21 @@ qemuDomainStartupCleanup(virDomainObj *vm) + for (i = 0; i < vm->def->ndisks; i++) + qemuDomainCleanupStorageSourceFD(vm->def->disks[i]->src); + } ++ ++ ++virBitmap * ++qemuDomainEvaluateCPUMask(const virDomainDef *def, ++ virBitmap *cpumask, ++ virBitmap *autoCpuset) ++{ ++ if (cpumask) { ++ return cpumask; ++ } else if (autoCpuset && ++ def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { ++ return autoCpuset; ++ } else if (def->cpumask) { ++ return def->cpumask; ++ } ++ ++ return NULL; ++} +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index fb9ab4c5ed..b01b394287 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -1139,3 +1139,8 @@ qemuDomainSchedCoreStart(virQEMUDriverConfig *cfg, + + void + qemuDomainSchedCoreStop(qemuDomainObjPrivate *priv); ++ ++virBitmap * ++qemuDomainEvaluateCPUMask(const virDomainDef *def, ++ virBitmap *cpumask, ++ virBitmap *autoCpuset); +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index e5c438aa26..3154fa5b10 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -2575,13 +2575,8 @@ qemuProcessSetupPid(virDomainObj *vm, + } + + /* Infer which cpumask shall be used. */ +- if (cpumask) { +- use_cpumask = cpumask; +- } else if (vm->def->placement_mode == VIR_DOMAIN_CPU_PLACEMENT_MODE_AUTO) { +- use_cpumask = priv->autoCpuset; +- } else if (vm->def->cpumask) { +- use_cpumask = vm->def->cpumask; +- } else { ++ if (!(use_cpumask = qemuDomainEvaluateCPUMask(vm->def, ++ cpumask, priv->autoCpuset))) { + /* You may think this is redundant, but we can't assume libvirtd + * itself is running on all pCPUs, so we need to explicitly set + * the spawned QEMU instance to all pCPUs if no map is given in +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuBuildMemoryBackendProps-Join-two-conditions.patch b/SOURCES/libvirt-qemuBuildMemoryBackendProps-Join-two-conditions.patch new file mode 100644 index 0000000..d6ca00a --- /dev/null +++ b/SOURCES/libvirt-qemuBuildMemoryBackendProps-Join-two-conditions.patch @@ -0,0 +1,60 @@ +From 328cc56c14284fa7c026fd0fc4e4ab5d80bed9dd Mon Sep 17 00:00:00 2001 +Message-Id: <328cc56c14284fa7c026fd0fc4e4ab5d80bed9dd@dist-git> +From: Michal Privoznik +Date: Tue, 14 Mar 2023 17:19:27 +0100 +Subject: [PATCH] qemuBuildMemoryBackendProps: Join two conditions + +There are two compound conditions in +qemuBuildMemoryBackendProps() and each one checks for nodemask +for NULL first. Join them into one bigger block. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 450d932cd9a604d1e7d25c9f239cad08ca5e375c) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_command.c | 26 ++++++++++++++------------ + 1 file changed, 14 insertions(+), 12 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 5edad046d5..436df47eaa 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3431,19 +3431,21 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, + return -1; + } + +- /* Make sure the requested nodeset is sensible */ +- if (nodemask && !virNumaNodesetIsAvailable(nodemask)) +- return -1; +- +- /* If mode is "restrictive", we should only use cgroups setting allowed memory +- * nodes, and skip passing the host-nodes and policy parameters to QEMU command +- * line which means we will use system default memory policy. */ +- if (nodemask && mode != VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) { +- if (virJSONValueObjectAdd(&props, +- "m:host-nodes", nodemask, +- "S:policy", qemuNumaPolicyTypeToString(mode), +- NULL) < 0) ++ if (nodemask) { ++ /* Make sure the requested nodeset is sensible */ ++ if (!virNumaNodesetIsAvailable(nodemask)) + return -1; ++ ++ /* If mode is "restrictive", we should only use cgroups setting allowed memory ++ * nodes, and skip passing the host-nodes and policy parameters to QEMU command ++ * line which means we will use system default memory policy. */ ++ if (mode != VIR_DOMAIN_NUMATUNE_MEM_RESTRICTIVE) { ++ if (virJSONValueObjectAdd(&props, ++ "m:host-nodes", nodemask, ++ "S:policy", qemuNumaPolicyTypeToString(mode), ++ NULL) < 0) ++ return -1; ++ } + } + + /* If none of the following is requested... */ +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuBuildThreadContextProps-Prune-.node-affinity-wrt-emulatorpin.patch b/SOURCES/libvirt-qemuBuildThreadContextProps-Prune-.node-affinity-wrt-emulatorpin.patch new file mode 100644 index 0000000..ae79042 --- /dev/null +++ b/SOURCES/libvirt-qemuBuildThreadContextProps-Prune-.node-affinity-wrt-emulatorpin.patch @@ -0,0 +1,138 @@ +From 45a585374500f4e4f1684c9dafe89269344c79b1 Mon Sep 17 00:00:00 2001 +Message-Id: <45a585374500f4e4f1684c9dafe89269344c79b1@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 14:05:54 +0100 +Subject: [PATCH] qemuBuildThreadContextProps: Prune .node-affinity wrt + + +When a thread-context object is specified on the cmd line, then +QEMU spawns a thread and sets its affinity to the list of NUMA +nodes specified in .node-affinity attribute. And this works just +fine, until the main QEMU thread itself is not restricted. + +Because of v5.3.0-rc1~18 we restrict the main emulator thread +even before QEMU is executed and thus then it tries to set +affinity of a thread-context thread, it inevitably fails with: + + Setting CPU affinity failed: Invalid argument + +Now, we could lift the pinning temporarily, let QEMU spawn all +thread-context threads, and enforce pinning again, but that would +require some form of communication with QEMU (maybe -preconfig?). +But that would still be wrong, because it would circumvent +. + +Technically speaking, thread-context is an internal +implementation detail of QEMU, and if it weren't for it, the main +emulator thread would be doing the allocation. Therefore, we +should honor the pinning and prune the list of node so that +inaccessible ones are dropped. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2154750 +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit df2ef2e706ec5960761bdbf619ea33be99482a15) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/qemu/qemu_command.c | 25 ++++++++++++++++--- + src/qemu/qemu_command.h | 1 + + ...emory-hotplug-dimm-addr.x86_64-latest.args | 2 +- + 3 files changed, 24 insertions(+), 4 deletions(-) + +diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c +index 346967f51c..b36005d248 100644 +--- a/src/qemu/qemu_command.c ++++ b/src/qemu/qemu_command.c +@@ -3533,7 +3533,7 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd, + def, mem, true, false, &nodemask) < 0) + return -1; + +- if (qemuBuildThreadContextProps(&tcProps, &props, priv, nodemask) < 0) ++ if (qemuBuildThreadContextProps(&tcProps, &props, def, priv, nodemask) < 0) + return -1; + + if (tcProps && +@@ -3630,10 +3630,13 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + int + qemuBuildThreadContextProps(virJSONValue **tcProps, + virJSONValue **memProps, ++ const virDomainDef *def, + qemuDomainObjPrivate *priv, + virBitmap *nodemask) + { + g_autoptr(virJSONValue) props = NULL; ++ virBitmap *emulatorpin = NULL; ++ g_autoptr(virBitmap) emulatorNodes = NULL; + g_autofree char *tcAlias = NULL; + const char *memalias = NULL; + bool prealloc = false; +@@ -3650,6 +3653,22 @@ qemuBuildThreadContextProps(virJSONValue **tcProps, + !prealloc) + return 0; + ++ emulatorpin = qemuDomainEvaluateCPUMask(def, ++ def->cputune.emulatorpin, ++ priv->autoNodeset); ++ ++ if (emulatorpin && virNumaIsAvailable()) { ++ if (virNumaCPUSetToNodeset(emulatorpin, &emulatorNodes) < 0) ++ return -1; ++ ++ virBitmapIntersect(emulatorNodes, nodemask); ++ ++ if (virBitmapIsAllClear(emulatorNodes)) ++ return 0; ++ ++ nodemask = emulatorNodes; ++ } ++ + memalias = virJSONValueObjectGetString(*memProps, "id"); + if (!memalias) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +@@ -7064,7 +7083,7 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommand *cmd, + def, &mem, false, true, &nodemask) < 0) + return -1; + +- if (qemuBuildThreadContextProps(&tcProps, &props, priv, nodemask) < 0) ++ if (qemuBuildThreadContextProps(&tcProps, &props, def, priv, nodemask) < 0) + return -1; + + if (tcProps && +@@ -7393,7 +7412,7 @@ qemuBuildNumaCommandLine(virQEMUDriverConfig *cfg, + g_autoptr(virJSONValue) tcProps = NULL; + + if (qemuBuildThreadContextProps(&tcProps, &nodeBackends[i], +- priv, nodemask[i]) < 0) ++ def, priv, nodemask[i]) < 0) + goto cleanup; + + if (tcProps && +diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h +index 17f326d13b..5fdb138030 100644 +--- a/src/qemu/qemu_command.h ++++ b/src/qemu/qemu_command.h +@@ -153,6 +153,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + int + qemuBuildThreadContextProps(virJSONValue **tcProps, + virJSONValue **memProps, ++ const virDomainDef *def, + qemuDomainObjPrivate *priv, + virBitmap *nodemask); + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.x86_64-latest.args +index 4e9bbde448..bbfb0f9a9e 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.x86_64-latest.args ++++ b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.x86_64-latest.args +@@ -29,7 +29,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ + -no-acpi \ + -boot strict=on \ + -device '{"driver":"piix3-usb-uhci","id":"usb","bus":"pci.0","addr":"0x1.0x2"}' \ +--object '{"qom-type":"thread-context","id":"tc-memdimm0","node-affinity":[1,2,3]}' \ ++-object '{"qom-type":"thread-context","id":"tc-memdimm0","node-affinity":[1,2]}' \ + -object '{"qom-type":"memory-backend-file","id":"memdimm0","mem-path":"/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1","prealloc":true,"size":536870912,"host-nodes":[1,2,3],"policy":"bind","prealloc-context":"tc-memdimm0"}' \ + -device '{"driver":"pc-dimm","node":0,"memdev":"memdimm0","id":"dimm0","slot":0,"addr":4294967296}' \ + -object '{"qom-type":"memory-backend-ram","id":"memdimm2","size":536870912}' \ +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuxml2argvdata-Adjust-maximum-NUMA-node-used.patch b/SOURCES/libvirt-qemuxml2argvdata-Adjust-maximum-NUMA-node-used.patch new file mode 100644 index 0000000..bed2858 --- /dev/null +++ b/SOURCES/libvirt-qemuxml2argvdata-Adjust-maximum-NUMA-node-used.patch @@ -0,0 +1,157 @@ +From 340bb04ed8b9a455880b0cbac7228bb17a9679d8 Mon Sep 17 00:00:00 2001 +Message-Id: <340bb04ed8b9a455880b0cbac7228bb17a9679d8@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 16:06:03 +0100 +Subject: [PATCH] qemuxml2argvdata: Adjust maximum NUMA node used + +We have couple of qemuxml2argvtest cases where up to 8 NUMA nodes +are assumed. These are used to check whether disjoint ranges of +host-nodes= is generated properly. Without prejudice to the +generality, we can rewrite corresponding XML files to use up to 4 +NUMA nodes and still have disjoint ranges. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit d91ca262fba8c942449cb5f705f309fcf4baf05a) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + tests/qemuxml2argvdata/migrate-numa-unaligned.args | 4 ++-- + tests/qemuxml2argvdata/migrate-numa-unaligned.xml | 4 ++-- + tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml | 4 ++-- + tests/qemuxml2argvdata/numatune-memnode.args | 4 ++-- + tests/qemuxml2argvdata/numatune-memnode.x86_64-5.2.0.args | 4 ++-- + tests/qemuxml2argvdata/numatune-memnode.x86_64-latest.args | 4 ++-- + tests/qemuxml2argvdata/numatune-memnode.xml | 4 ++-- + tests/qemuxml2xmloutdata/numatune-memnode.xml | 4 ++-- + 8 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/tests/qemuxml2argvdata/migrate-numa-unaligned.args b/tests/qemuxml2argvdata/migrate-numa-unaligned.args +index b50d93a12f..4786045358 100644 +--- a/tests/qemuxml2argvdata/migrate-numa-unaligned.args ++++ b/tests/qemuxml2argvdata/migrate-numa-unaligned.args +@@ -17,9 +17,9 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ + -smp 32,sockets=32,cores=1,threads=1 \ + -object memory-backend-ram,id=ram-node0,size=20482048,host-nodes=3,policy=preferred \ + -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +--object memory-backend-ram,id=ram-node1,size=675907584,host-nodes=0-7,policy=bind \ ++-object memory-backend-ram,id=ram-node1,size=675907584,host-nodes=0-3,policy=bind \ + -numa node,nodeid=1,cpus=1-27,cpus=29,memdev=ram-node1 \ +--object memory-backend-ram,id=ram-node2,size=24578457600,host-nodes=1-2,host-nodes=5,host-nodes=7,policy=bind \ ++-object memory-backend-ram,id=ram-node2,size=24578457600,host-nodes=0,host-nodes=2,policy=bind \ + -numa node,nodeid=2,cpus=28,cpus=30-31,memdev=ram-node2 \ + -uuid 9f4b6512-e73a-4a25-93e8-5307802821ce \ + -display none \ +diff --git a/tests/qemuxml2argvdata/migrate-numa-unaligned.xml b/tests/qemuxml2argvdata/migrate-numa-unaligned.xml +index e46b723acb..c060852297 100644 +--- a/tests/qemuxml2argvdata/migrate-numa-unaligned.xml ++++ b/tests/qemuxml2argvdata/migrate-numa-unaligned.xml +@@ -6,8 +6,8 @@ + 32 + + +- +- ++ ++ + + + hvm +diff --git a/tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml b/tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml +index 012c526460..2a640f5501 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml ++++ b/tests/qemuxml2argvdata/numatune-memnode-restrictive-mode.xml +@@ -5,9 +5,9 @@ + 24682468 + 32 + +- ++ + +- ++ + + + hvm +diff --git a/tests/qemuxml2argvdata/numatune-memnode.args b/tests/qemuxml2argvdata/numatune-memnode.args +index 1564a0ddd6..dd0fea62e6 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode.args ++++ b/tests/qemuxml2argvdata/numatune-memnode.args +@@ -17,9 +17,9 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ + -smp 32,sockets=32,cores=1,threads=1 \ + -object memory-backend-ram,id=ram-node0,size=20971520,host-nodes=3,policy=preferred \ + -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +--object memory-backend-ram,id=ram-node1,size=676331520,host-nodes=0-7,policy=bind \ ++-object memory-backend-ram,id=ram-node1,size=676331520,host-nodes=0-3,policy=bind \ + -numa node,nodeid=1,cpus=1-27,cpus=29,memdev=ram-node1 \ +--object memory-backend-ram,id=ram-node2,size=24578621440,host-nodes=1-2,host-nodes=5,host-nodes=7,policy=bind \ ++-object memory-backend-ram,id=ram-node2,size=24578621440,host-nodes=0,host-nodes=2,policy=bind \ + -numa node,nodeid=2,cpus=28,cpus=30-31,memdev=ram-node2 \ + -uuid 9f4b6512-e73a-4a25-93e8-5307802821ce \ + -display none \ +diff --git a/tests/qemuxml2argvdata/numatune-memnode.x86_64-5.2.0.args b/tests/qemuxml2argvdata/numatune-memnode.x86_64-5.2.0.args +index 81913e0e18..85f083efc9 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode.x86_64-5.2.0.args ++++ b/tests/qemuxml2argvdata/numatune-memnode.x86_64-5.2.0.args +@@ -18,9 +18,9 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ + -smp 32,sockets=32,cores=1,threads=1 \ + -object memory-backend-ram,id=ram-node0,size=20971520,host-nodes=3,policy=preferred \ + -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +--object memory-backend-ram,id=ram-node1,size=676331520,host-nodes=0-7,policy=bind \ ++-object memory-backend-ram,id=ram-node1,size=676331520,host-nodes=0-3,policy=bind \ + -numa node,nodeid=1,cpus=1-27,cpus=29,memdev=ram-node1 \ +--object memory-backend-ram,id=ram-node2,size=24578621440,host-nodes=1-2,host-nodes=5,host-nodes=7,policy=bind \ ++-object memory-backend-ram,id=ram-node2,size=24578621440,host-nodes=0,host-nodes=2,policy=bind \ + -numa node,nodeid=2,cpus=28,cpus=30-31,memdev=ram-node2 \ + -uuid 9f4b6512-e73a-4a25-93e8-5307802821ce \ + -display none \ +diff --git a/tests/qemuxml2argvdata/numatune-memnode.x86_64-latest.args b/tests/qemuxml2argvdata/numatune-memnode.x86_64-latest.args +index 7cb7e659a4..6d4baebc83 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode.x86_64-latest.args ++++ b/tests/qemuxml2argvdata/numatune-memnode.x86_64-latest.args +@@ -18,9 +18,9 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest/.config \ + -smp 32,sockets=32,cores=1,threads=1 \ + -object '{"qom-type":"memory-backend-ram","id":"ram-node0","size":20971520,"host-nodes":[3],"policy":"preferred"}' \ + -numa node,nodeid=0,cpus=0,memdev=ram-node0 \ +--object '{"qom-type":"memory-backend-ram","id":"ram-node1","size":676331520,"host-nodes":[0,1,2,3,4,5,6,7],"policy":"bind"}' \ ++-object '{"qom-type":"memory-backend-ram","id":"ram-node1","size":676331520,"host-nodes":[0,1,2,3],"policy":"bind"}' \ + -numa node,nodeid=1,cpus=1-27,cpus=29,memdev=ram-node1 \ +--object '{"qom-type":"memory-backend-ram","id":"ram-node2","size":24578621440,"host-nodes":[1,2,5,7],"policy":"bind"}' \ ++-object '{"qom-type":"memory-backend-ram","id":"ram-node2","size":24578621440,"host-nodes":[0,2],"policy":"bind"}' \ + -numa node,nodeid=2,cpus=28,cpus=30-31,memdev=ram-node2 \ + -uuid 9f4b6512-e73a-4a25-93e8-5307802821ce \ + -display none \ +diff --git a/tests/qemuxml2argvdata/numatune-memnode.xml b/tests/qemuxml2argvdata/numatune-memnode.xml +index dd653c5d3b..9640eeb945 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode.xml ++++ b/tests/qemuxml2argvdata/numatune-memnode.xml +@@ -6,8 +6,8 @@ + 32 + + +- +- ++ ++ + + + hvm +diff --git a/tests/qemuxml2xmloutdata/numatune-memnode.xml b/tests/qemuxml2xmloutdata/numatune-memnode.xml +index 104d2e6d4c..a117745bfb 100644 +--- a/tests/qemuxml2xmloutdata/numatune-memnode.xml ++++ b/tests/qemuxml2xmloutdata/numatune-memnode.xml +@@ -5,9 +5,9 @@ + 24682468 + 32 + +- ++ + +- ++ + + + hvm +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuxml2argvdata-Extend-vCPUs-placement-in-memory-hotplug-dimm-addr.xml.patch b/SOURCES/libvirt-qemuxml2argvdata-Extend-vCPUs-placement-in-memory-hotplug-dimm-addr.xml.patch new file mode 100644 index 0000000..80ceb22 --- /dev/null +++ b/SOURCES/libvirt-qemuxml2argvdata-Extend-vCPUs-placement-in-memory-hotplug-dimm-addr.xml.patch @@ -0,0 +1,53 @@ +From 04203191c0261c6a12475865c7053e62b79756ee Mon Sep 17 00:00:00 2001 +Message-Id: <04203191c0261c6a12475865c7053e62b79756ee@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 15:36:47 +0100 +Subject: [PATCH] qemuxml2argvdata: Extend vCPUs placement in + memory-hotplug-dimm-addr.xml + +So far, the memory-hotplug-dimm-addr.xml test case pins its vCPUs +onto CPUs 0-1 which correspond to NUMA node #0 (per +tests/vircaps2xmldata/linux-basic/system/node/node0). Place vCPUs +onto nodes #1 and #2 too so that DIMM device can +continue using thread-context after future patches. This +configuration, as-is currently, would make QEMU error out anyway. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit c4c90063a5955bca9f5afb5fe03502d3503241c3) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml | 2 +- + .../memory-hotplug-dimm-addr.x86_64-latest.xml | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml +index 92ea679bbe..47486dda0c 100644 +--- a/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml ++++ b/tests/qemuxml2argvdata/memory-hotplug-dimm-addr.xml +@@ -4,7 +4,7 @@ + 1099511627776 + 7434230 + 7434230 +- 2 ++ 2 + + hvm + +diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-dimm-addr.x86_64-latest.xml b/tests/qemuxml2xmloutdata/memory-hotplug-dimm-addr.x86_64-latest.xml +index ef671fcfa3..0a32d5491a 100644 +--- a/tests/qemuxml2xmloutdata/memory-hotplug-dimm-addr.x86_64-latest.xml ++++ b/tests/qemuxml2xmloutdata/memory-hotplug-dimm-addr.x86_64-latest.xml +@@ -4,7 +4,7 @@ + 1099511627776 + 7434230 + 7434230 +- 2 ++ 2 + + hvm + +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuxml2argvmock-Drop-virNuma-mocks.patch b/SOURCES/libvirt-qemuxml2argvmock-Drop-virNuma-mocks.patch new file mode 100644 index 0000000..685814f --- /dev/null +++ b/SOURCES/libvirt-qemuxml2argvmock-Drop-virNuma-mocks.patch @@ -0,0 +1,122 @@ +From 2ffa5538e4f7507a77fdb7ac23bdc8aa51e54297 Mon Sep 17 00:00:00 2001 +Message-Id: <2ffa5538e4f7507a77fdb7ac23bdc8aa51e54297@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 16:06:14 +0100 +Subject: [PATCH] qemuxml2argvmock: Drop virNuma* mocks + +Since qemuxml2argvtest is now using virnumamock, there's no need +for qemuxml2argvmock to offer reimplementation of virNuma*() +functions. Also, the comment about CLang and FreeBSD (introduced +in v4.3.0-40-g77ac204d14) is no longer true. Looks like noinline +attribute was the missing culprit. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 95ae91fdd4da33323ead8f916824b48f8506383c) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/util/virnuma.h | 2 +- + ...-unavailable-restrictive.x86_64-latest.err | 2 +- + ...mnode-unavailable-strict.x86_64-latest.err | 2 +- + ...umatune-static-nodeset-exceed-hostnode.err | 2 +- + tests/qemuxml2argvmock.c | 42 ------------------- + 5 files changed, 4 insertions(+), 46 deletions(-) + +diff --git a/src/util/virnuma.h b/src/util/virnuma.h +index edd701d5c8..475df96e1d 100644 +--- a/src/util/virnuma.h ++++ b/src/util/virnuma.h +@@ -32,7 +32,7 @@ int virNumaSetupMemoryPolicy(virDomainNumatuneMemMode mode, + virBitmap *nodeset); + + virBitmap *virNumaGetHostMemoryNodeset(void); +-bool virNumaNodesetIsAvailable(virBitmap *nodeset) G_NO_INLINE; ++bool virNumaNodesetIsAvailable(virBitmap *nodeset); + bool virNumaIsAvailable(void) G_NO_INLINE; + int virNumaGetMaxNode(void) G_NO_INLINE; + bool virNumaNodeIsAvailable(int node) G_NO_INLINE; +diff --git a/tests/qemuxml2argvdata/numatune-memnode-unavailable-restrictive.x86_64-latest.err b/tests/qemuxml2argvdata/numatune-memnode-unavailable-restrictive.x86_64-latest.err +index a826c3cdeb..f872dd7e92 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode-unavailable-restrictive.x86_64-latest.err ++++ b/tests/qemuxml2argvdata/numatune-memnode-unavailable-restrictive.x86_64-latest.err +@@ -1 +1 @@ +-internal error: Mock: no numa node set is available at bit 999 ++unsupported configuration: NUMA node 999 is unavailable +diff --git a/tests/qemuxml2argvdata/numatune-memnode-unavailable-strict.x86_64-latest.err b/tests/qemuxml2argvdata/numatune-memnode-unavailable-strict.x86_64-latest.err +index a826c3cdeb..f872dd7e92 100644 +--- a/tests/qemuxml2argvdata/numatune-memnode-unavailable-strict.x86_64-latest.err ++++ b/tests/qemuxml2argvdata/numatune-memnode-unavailable-strict.x86_64-latest.err +@@ -1 +1 @@ +-internal error: Mock: no numa node set is available at bit 999 ++unsupported configuration: NUMA node 999 is unavailable +diff --git a/tests/qemuxml2argvdata/numatune-static-nodeset-exceed-hostnode.err b/tests/qemuxml2argvdata/numatune-static-nodeset-exceed-hostnode.err +index b6b98775ee..2a33ccd791 100644 +--- a/tests/qemuxml2argvdata/numatune-static-nodeset-exceed-hostnode.err ++++ b/tests/qemuxml2argvdata/numatune-static-nodeset-exceed-hostnode.err +@@ -1 +1 @@ +-internal error: Mock: no numa node set is available at bit 8 ++unsupported configuration: NUMA node 4 is unavailable +diff --git a/tests/qemuxml2argvmock.c b/tests/qemuxml2argvmock.c +index 85bd76c315..f566ec539a 100644 +--- a/tests/qemuxml2argvmock.c ++++ b/tests/qemuxml2argvmock.c +@@ -30,7 +30,6 @@ + #include "virnetdevip.h" + #include "virnetdevtap.h" + #include "virnetdevopenvswitch.h" +-#include "virnuma.h" + #include "virscsivhost.h" + #include "virtpm.h" + #include "virutil.h" +@@ -56,47 +55,6 @@ GDateTime *g_date_time_new_now_local(void) + return g_date_time_new_from_unix_local(1234567890); + } + +-bool +-virNumaIsAvailable(void) +-{ +- return true; +-} +- +-int +-virNumaGetMaxNode(void) +-{ +- return 7; +-} +- +-/* We shouldn't need to mock virNumaNodeIsAvailable() and *definitely* not +- * virNumaNodesetIsAvailable(), but it seems to be the only way to get +- * mocking to work with Clang on FreeBSD, so keep these duplicates around +- * until we figure out a cleaner solution */ +-bool +-virNumaNodeIsAvailable(int node) +-{ +- return node >= 0 && node <= virNumaGetMaxNode(); +-} +- +-bool +-virNumaNodesetIsAvailable(virBitmap *nodeset) +-{ +- ssize_t bit = -1; +- +- if (!nodeset) +- return true; +- +- while ((bit = virBitmapNextSetBit(nodeset, bit)) >= 0) { +- if (virNumaNodeIsAvailable(bit)) +- continue; +- +- virReportError(VIR_ERR_INTERNAL_ERROR, +- "Mock: no numa node set is available at bit %zd", bit); +- return false; +- } +- +- return true; +-} + + char * + virTPMCreateCancelPath(const char *devpath) +-- +2.40.0 diff --git a/SOURCES/libvirt-qemuxml2argvtest-Use-virnuma-mock.patch b/SOURCES/libvirt-qemuxml2argvtest-Use-virnuma-mock.patch new file mode 100644 index 0000000..9c6c3c8 --- /dev/null +++ b/SOURCES/libvirt-qemuxml2argvtest-Use-virnuma-mock.patch @@ -0,0 +1,78 @@ +From 2349387743e56e658fb56fcdadd522e6df9f42f2 Mon Sep 17 00:00:00 2001 +Message-Id: <2349387743e56e658fb56fcdadd522e6df9f42f2@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 15:36:35 +0100 +Subject: [PATCH] qemuxml2argvtest: Use virnuma mock + +While no part of cmd line building process currently depends on a +host NUMA configuration, this will change soon. Use freshly +changed virnumamock from qemuxml2argvtest and make the mock read +NUMA data from vircaps2xmldata which seems to have the most rich +NUMA configuration. + +This also means, we have to start building virnumamock +unconditionally. But this is not a problem, since nothing inside +of the mock relies on Linux specificity. The whole mock is merely +just reading files and parsing them. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 28ec9d86b3db4bd9ea29891350366ffa6895d4e9) + +Conflicts: +- tests/qemuxml2argvtest.c: Context, some cleanup patches (e.g. + v9.2.0-rc1~191) are not backported. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + tests/meson.build | 2 +- + tests/qemuxml2argvtest.c | 5 ++++- + 2 files changed, 5 insertions(+), 2 deletions(-) + +diff --git a/tests/meson.build b/tests/meson.build +index 3365dce307..6d0e62c02f 100644 +--- a/tests/meson.build ++++ b/tests/meson.build +@@ -84,6 +84,7 @@ mock_libs = [ + { 'name': 'virnetdaemonmock' }, + { 'name': 'virnetdevmock' }, + { 'name': 'virnetserverclientmock' }, ++ { 'name': 'virnumamock' }, + { 'name': 'virpcimock' }, + { 'name': 'virportallocatormock' }, + { 'name': 'virprocessmock' }, +@@ -94,7 +95,6 @@ if host_machine.system() == 'linux' + mock_libs += [ + { 'name': 'virfilemock' }, + { 'name': 'virnetdevbandwidthmock' }, +- { 'name': 'virnumamock' }, + { 'name': 'virtestmock' }, + { 'name': 'virusbmock' }, + ] +diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c +index e23b32e96a..3fb2d5dc74 100644 +--- a/tests/qemuxml2argvtest.c ++++ b/tests/qemuxml2argvtest.c +@@ -872,6 +872,8 @@ mymain(void) + VIR_FREE(driver.config->nvramDir); + driver.config->nvramDir = g_strdup("/var/lib/libvirt/qemu/nvram"); + ++ virFileWrapperAddPrefix("/sys/devices/system", ++ abs_srcdir "/vircaps2xmldata/linux-basic/system"); + virFileWrapperAddPrefix(SYSCONFDIR "/qemu/firmware", + abs_srcdir "/qemufirmwaredata/etc/qemu/firmware"); + virFileWrapperAddPrefix(PREFIX "/share/qemu/firmware", +@@ -2999,7 +3001,8 @@ VIR_TEST_MAIN_PRELOAD(mymain, + VIR_TEST_MOCK("domaincaps"), + VIR_TEST_MOCK("virrandom"), + VIR_TEST_MOCK("qemucpu"), +- VIR_TEST_MOCK("virpci")) ++ VIR_TEST_MOCK("virpci"), ++ VIR_TEST_MOCK("virnuma")) + + #else + +-- +2.40.0 diff --git a/SOURCES/libvirt-virnuma-Introduce-virNumaCPUSetToNodeset.patch b/SOURCES/libvirt-virnuma-Introduce-virNumaCPUSetToNodeset.patch new file mode 100644 index 0000000..88a10cd --- /dev/null +++ b/SOURCES/libvirt-virnuma-Introduce-virNumaCPUSetToNodeset.patch @@ -0,0 +1,144 @@ +From d8c969c521efbd38df526f085db32c605661e2d1 Mon Sep 17 00:00:00 2001 +Message-Id: +From: Michal Privoznik +Date: Tue, 7 Mar 2023 14:05:27 +0100 +Subject: [PATCH] virnuma: Introduce virNumaCPUSetToNodeset() + +So far, we have a function that expands given list of NUMA nodes +into list of CPUs. But soon, we are going to need the inverse - +expand list of CPUs into list of NUMA nodes. Introduce +virNumaCPUSetToNodeset() for that. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit b6cfd348e9fd1c748481416b1ef42b482db4b4cb) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/libvirt_private.syms | 2 ++ + src/util/virnuma.c | 59 ++++++++++++++++++++++++++++++++++++++++ + src/util/virnuma.h | 3 ++ + 3 files changed, 64 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index e20421e7cd..28a6efda8f 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2961,6 +2961,7 @@ virNodeSuspendGetTargetMask; + + + # util/virnuma.h ++virNumaCPUSetToNodeset; + virNumaGetAutoPlacementAdvice; + virNumaGetDistances; + virNumaGetHostMemoryNodeset; +@@ -2968,6 +2969,7 @@ virNumaGetMaxCPUs; + virNumaGetMaxNode; + virNumaGetNodeCPUs; + virNumaGetNodeMemory; ++virNumaGetNodeOfCPU; + virNumaGetPageInfo; + virNumaGetPages; + virNumaIsAvailable; +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index dae0827c65..4a15bf32c8 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -311,6 +311,22 @@ virNumaGetNodeCPUs(int node, + # undef MASK_CPU_ISSET + # undef n_bits + ++ ++/** ++ * virNumaGetNodeOfCPU: ++ * @cpu: CPU ID ++ * ++ * For given @cpu, return NUMA node which it belongs to. ++ * ++ * Returns: NUMA node # on success, ++ * -1 on failure (with errno set). ++ */ ++int ++virNumaGetNodeOfCPU(int cpu) ++{ ++ return numa_node_of_cpu(cpu); ++} ++ + #else /* !WITH_NUMACTL */ + + int +@@ -366,6 +382,14 @@ virNumaGetNodeCPUs(int node G_GNUC_UNUSED, + return -1; + } + ++int ++virNumaGetNodeOfCPU(int cpu G_GNUC_UNUSED) ++{ ++ errno = ENOSYS; ++ return -1; ++} ++ ++ + #endif /* !WITH_NUMACTL */ + + /** +@@ -990,6 +1014,41 @@ virNumaGetHostMemoryNodeset(void) + } + + ++/** ++ * virNumaCPUSetToNodeset: ++ * @cpuset: bitmap containing a set of CPUs ++ * @nodeset: returned bitmap containing a set of NUMA nodes ++ * ++ * Convert a set of CPUs to set of NUMA nodes that contain the CPUs. ++ * ++ * Returns: 0 on success, ++ * -1 on failure (with error reported) ++ */ ++int ++virNumaCPUSetToNodeset(virBitmap *cpuset, ++ virBitmap **nodeset) ++{ ++ g_autoptr(virBitmap) nodes = virBitmapNew(0); ++ ssize_t pos = -1; ++ ++ while ((pos = virBitmapNextSetBit(cpuset, pos)) >= 0) { ++ int node = virNumaGetNodeOfCPU(pos); ++ ++ if (node < 0) { ++ virReportSystemError(errno, ++ _("Unable to get NUMA node of cpu %zd"), ++ pos); ++ return -1; ++ } ++ ++ virBitmapSetBitExpand(nodes, node); ++ } ++ ++ *nodeset = g_steal_pointer(&nodes); ++ return 0; ++} ++ ++ + /** + * virNumaNodesetToCPUset: + * @nodeset: bitmap containing a set of NUMA nodes +diff --git a/src/util/virnuma.h b/src/util/virnuma.h +index c35acd47cb..2c30ef4e31 100644 +--- a/src/util/virnuma.h ++++ b/src/util/virnuma.h +@@ -45,7 +45,10 @@ int virNumaGetNodeMemory(int node, + + unsigned int virNumaGetMaxCPUs(void) G_NO_INLINE; + ++int virNumaGetNodeOfCPU(int cpu); + int virNumaGetNodeCPUs(int node, virBitmap **cpus) G_NO_INLINE; ++int virNumaCPUSetToNodeset(virBitmap *cpuset, ++ virBitmap **nodeset); + int virNumaNodesetToCPUset(virBitmap *nodeset, + virBitmap **cpuset); + +-- +2.40.0 diff --git a/SOURCES/libvirt-virnuma-Move-virNumaNodesetToCPUset-out-of-WITH_NUMACTL.patch b/SOURCES/libvirt-virnuma-Move-virNumaNodesetToCPUset-out-of-WITH_NUMACTL.patch new file mode 100644 index 0000000..11b07f3 --- /dev/null +++ b/SOURCES/libvirt-virnuma-Move-virNumaNodesetToCPUset-out-of-WITH_NUMACTL.patch @@ -0,0 +1,166 @@ +From 93f8e4f797fe8480148328a3cc1dfcb40f16a49e Mon Sep 17 00:00:00 2001 +Message-Id: <93f8e4f797fe8480148328a3cc1dfcb40f16a49e@dist-git> +From: Michal Privoznik +Date: Wed, 8 Mar 2023 10:10:00 +0100 +Subject: [PATCH] virnuma: Move virNumaNodesetToCPUset() out of WITH_NUMACTL + +Technically, there's nothing libnuma specific about +virNumaNodesetToCPUset(). It just implements a generic algorithm +over virNumaGetNodeCPUs() (which is then libnuma dependant). +Nevertheless, there's no need to have this function living inside +WITH_NUMACTL block. Any error returned from virNumaGetNodeCPUs() +(including the one that !WITH_NUMACTL stub returns) is propagated +properly. + +Move the function out of the block into a generic one and drop +the !WITH_NUMACTL stub. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 01e5111c3cfee2358961c47f9edaa1eb421d2e03) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/util/virnuma.c | 115 +++++++++++++++++++++------------------------ + 1 file changed, 53 insertions(+), 62 deletions(-) + +diff --git a/src/util/virnuma.c b/src/util/virnuma.c +index 43e299f4bb..dae0827c65 100644 +--- a/src/util/virnuma.c ++++ b/src/util/virnuma.c +@@ -311,57 +311,6 @@ virNumaGetNodeCPUs(int node, + # undef MASK_CPU_ISSET + # undef n_bits + +-/** +- * virNumaNodesetToCPUset: +- * @nodeset: bitmap containing a set of NUMA nodes +- * @cpuset: return location for a bitmap containing a set of CPUs +- * +- * Convert a set of NUMA node to the set of CPUs they contain. +- * +- * Returns 0 on success, <0 on failure. +- */ +-int +-virNumaNodesetToCPUset(virBitmap *nodeset, +- virBitmap **cpuset) +-{ +- g_autoptr(virBitmap) allNodesCPUs = NULL; +- size_t nodesetSize; +- size_t i; +- +- *cpuset = NULL; +- +- if (!nodeset) +- return 0; +- +- allNodesCPUs = virBitmapNew(0); +- nodesetSize = virBitmapSize(nodeset); +- +- for (i = 0; i < nodesetSize; i++) { +- g_autoptr(virBitmap) nodeCPUs = NULL; +- int rc; +- +- if (!virBitmapIsBitSet(nodeset, i)) +- continue; +- +- rc = virNumaGetNodeCPUs(i, &nodeCPUs); +- if (rc < 0) { +- /* Error is reported for cases other than non-existent NUMA node. */ +- if (rc == -2) { +- virReportError(VIR_ERR_OPERATION_FAILED, +- _("NUMA node %zu is not available"), +- i); +- } +- return -1; +- } +- +- virBitmapUnion(allNodesCPUs, nodeCPUs); +- } +- +- *cpuset = g_steal_pointer(&allNodesCPUs); +- +- return 0; +-} +- + #else /* !WITH_NUMACTL */ + + int +@@ -417,17 +366,6 @@ virNumaGetNodeCPUs(int node G_GNUC_UNUSED, + return -1; + } + +-int +-virNumaNodesetToCPUset(virBitmap *nodeset G_GNUC_UNUSED, +- virBitmap **cpuset) +-{ +- *cpuset = NULL; +- +- virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +- _("NUMA isn't available on this host")); +- return -1; +-} +- + #endif /* !WITH_NUMACTL */ + + /** +@@ -1050,3 +988,56 @@ virNumaGetHostMemoryNodeset(void) + + return nodeset; + } ++ ++ ++/** ++ * virNumaNodesetToCPUset: ++ * @nodeset: bitmap containing a set of NUMA nodes ++ * @cpuset: return location for a bitmap containing a set of CPUs ++ * ++ * Convert a set of NUMA node to the set of CPUs they contain. ++ * ++ * Returns 0 on success, ++ * -1 on failure (with error reported). ++ */ ++int ++virNumaNodesetToCPUset(virBitmap *nodeset, ++ virBitmap **cpuset) ++{ ++ g_autoptr(virBitmap) allNodesCPUs = NULL; ++ size_t nodesetSize; ++ size_t i; ++ ++ *cpuset = NULL; ++ ++ if (!nodeset) ++ return 0; ++ ++ allNodesCPUs = virBitmapNew(0); ++ nodesetSize = virBitmapSize(nodeset); ++ ++ for (i = 0; i < nodesetSize; i++) { ++ g_autoptr(virBitmap) nodeCPUs = NULL; ++ int rc; ++ ++ if (!virBitmapIsBitSet(nodeset, i)) ++ continue; ++ ++ rc = virNumaGetNodeCPUs(i, &nodeCPUs); ++ if (rc < 0) { ++ /* Error is reported for cases other than non-existent NUMA node. */ ++ if (rc == -2) { ++ virReportError(VIR_ERR_OPERATION_FAILED, ++ _("NUMA node %zu is not available"), ++ i); ++ } ++ return -1; ++ } ++ ++ virBitmapUnion(allNodesCPUs, nodeCPUs); ++ } ++ ++ *cpuset = g_steal_pointer(&allNodesCPUs); ++ ++ return 0; ++} +-- +2.40.0 diff --git a/SOURCES/libvirt-virnumamock-Introduce-virNumaGetNodeOfCPU-mock.patch b/SOURCES/libvirt-virnumamock-Introduce-virNumaGetNodeOfCPU-mock.patch new file mode 100644 index 0000000..45e94ea --- /dev/null +++ b/SOURCES/libvirt-virnumamock-Introduce-virNumaGetNodeOfCPU-mock.patch @@ -0,0 +1,463 @@ +From 3dedbaa936d82e51442e4363fdafe6ec5d651dbf Mon Sep 17 00:00:00 2001 +Message-Id: <3dedbaa936d82e51442e4363fdafe6ec5d651dbf@dist-git> +From: Michal Privoznik +Date: Tue, 7 Mar 2023 15:44:41 +0100 +Subject: [PATCH] virnumamock: Introduce virNumaGetNodeOfCPU() mock + +Introduce a mock of virNumaGetNodeOfCPU() because soon we will +need virNumaCPUSetToNodeset() to return predictable results. +Also, fill in missing symlinks in vircaps2xmldata/. + +Signed-off-by: Michal Privoznik +Reviewed-by: Kristina Hanicova +Reviewed-by: Andrea Bolognani +(cherry picked from commit 213b6822a8ae508e0dd5e262b28c2c7000140293) +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2185039 +Signed-off-by: Michal Privoznik +--- + src/util/virnuma.h | 2 +- + .../linux-basic/system/cpu/cpu0/node0 | 1 + + .../linux-basic/system/cpu/cpu1/node0 | 1 + + .../linux-basic/system/cpu/cpu10/node2 | 1 + + .../linux-basic/system/cpu/cpu11/node2 | 1 + + .../linux-basic/system/cpu/cpu12/node3 | 1 + + .../linux-basic/system/cpu/cpu13/node3 | 1 + + .../linux-basic/system/cpu/cpu14/node3 | 1 + + .../linux-basic/system/cpu/cpu15/node3 | 1 + + .../linux-basic/system/cpu/cpu2/node0 | 1 + + .../linux-basic/system/cpu/cpu3/node0 | 1 + + .../linux-basic/system/cpu/cpu4/node1 | 1 + + .../linux-basic/system/cpu/cpu5/node1 | 1 + + .../linux-basic/system/cpu/cpu6/node1 | 1 + + .../linux-basic/system/cpu/cpu7/node1 | 1 + + .../linux-basic/system/cpu/cpu8/node2 | 1 + + .../linux-basic/system/cpu/cpu9/node2 | 1 + + .../linux-caches/system/cpu/cpu0/node0 | 1 + + .../linux-caches/system/cpu/cpu1/node0 | 1 + + .../linux-caches/system/cpu/cpu2/node0 | 1 + + .../linux-caches/system/cpu/cpu3/node0 | 1 + + .../linux-caches/system/cpu/cpu4/node0 | 1 + + .../linux-caches/system/cpu/cpu5/node0 | 1 + + .../linux-caches/system/cpu/cpu6/node0 | 1 + + .../linux-caches/system/cpu/cpu7/node0 | 1 + + .../system/cpu/cpu0/node0 | 1 + + .../linux-resctrl/system/cpu/cpu0/node0 | 1 + + .../linux-resctrl/system/cpu/cpu1/node0 | 1 + + .../linux-resctrl/system/cpu/cpu10/node1 | 1 + + .../linux-resctrl/system/cpu/cpu11/node1 | 1 + + .../linux-resctrl/system/cpu/cpu2/node0 | 1 + + .../linux-resctrl/system/cpu/cpu3/node0 | 1 + + .../linux-resctrl/system/cpu/cpu4/node0 | 1 + + .../linux-resctrl/system/cpu/cpu5/node0 | 1 + + .../linux-resctrl/system/cpu/cpu6/node1 | 1 + + .../linux-resctrl/system/cpu/cpu7/node1 | 1 + + .../linux-resctrl/system/cpu/cpu8/node1 | 1 + + .../linux-resctrl/system/cpu/cpu9/node1 | 1 + + tests/virnumamock.c | 42 +++++++++++++++++++ + 39 files changed, 80 insertions(+), 1 deletion(-) + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu0/node0 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu1/node0 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu10/node2 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu11/node2 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu12/node3 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu13/node3 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu14/node3 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu15/node3 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu2/node0 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu3/node0 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu4/node1 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu5/node1 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu6/node1 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu7/node1 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu8/node2 + create mode 120000 tests/vircaps2xmldata/linux-basic/system/cpu/cpu9/node2 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu0/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu1/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu2/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu3/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu4/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu5/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu6/node0 + create mode 120000 tests/vircaps2xmldata/linux-caches/system/cpu/cpu7/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl-skx-twocaches/system/cpu/cpu0/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu0/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu1/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu10/node1 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu11/node1 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu2/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu3/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu4/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu5/node0 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu6/node1 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu7/node1 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu8/node1 + create mode 120000 tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu9/node1 + +diff --git a/src/util/virnuma.h b/src/util/virnuma.h +index 2c30ef4e31..edd701d5c8 100644 +--- a/src/util/virnuma.h ++++ b/src/util/virnuma.h +@@ -45,7 +45,7 @@ int virNumaGetNodeMemory(int node, + + unsigned int virNumaGetMaxCPUs(void) G_NO_INLINE; + +-int virNumaGetNodeOfCPU(int cpu); ++int virNumaGetNodeOfCPU(int cpu) G_NO_INLINE; + int virNumaGetNodeCPUs(int node, virBitmap **cpus) G_NO_INLINE; + int virNumaCPUSetToNodeset(virBitmap *cpuset, + virBitmap **nodeset); +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu0/node0 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu0/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu0/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu1/node0 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu1/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu1/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu10/node2 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu10/node2 +new file mode 120000 +index 0000000000..e04af16eeb +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu10/node2 +@@ -0,0 +1 @@ ++../../node/node2 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu11/node2 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu11/node2 +new file mode 120000 +index 0000000000..e04af16eeb +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu11/node2 +@@ -0,0 +1 @@ ++../../node/node2 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu12/node3 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu12/node3 +new file mode 120000 +index 0000000000..f213d662fe +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu12/node3 +@@ -0,0 +1 @@ ++../../node/node3 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu13/node3 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu13/node3 +new file mode 120000 +index 0000000000..f213d662fe +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu13/node3 +@@ -0,0 +1 @@ ++../../node/node3 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu14/node3 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu14/node3 +new file mode 120000 +index 0000000000..f213d662fe +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu14/node3 +@@ -0,0 +1 @@ ++../../node/node3 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu15/node3 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu15/node3 +new file mode 120000 +index 0000000000..f213d662fe +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu15/node3 +@@ -0,0 +1 @@ ++../../node/node3 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu2/node0 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu2/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu2/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu3/node0 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu3/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu3/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu4/node1 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu4/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu4/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu5/node1 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu5/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu5/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu6/node1 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu6/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu6/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu7/node1 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu7/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu7/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu8/node2 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu8/node2 +new file mode 120000 +index 0000000000..e04af16eeb +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu8/node2 +@@ -0,0 +1 @@ ++../../node/node2 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-basic/system/cpu/cpu9/node2 b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu9/node2 +new file mode 120000 +index 0000000000..e04af16eeb +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-basic/system/cpu/cpu9/node2 +@@ -0,0 +1 @@ ++../../node/node2 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu0/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu0/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu0/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu1/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu1/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu1/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu2/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu2/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu2/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu3/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu3/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu3/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu4/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu4/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu4/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu5/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu5/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu5/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu6/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu6/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu6/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-caches/system/cpu/cpu7/node0 b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu7/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-caches/system/cpu/cpu7/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl-skx-twocaches/system/cpu/cpu0/node0 b/tests/vircaps2xmldata/linux-resctrl-skx-twocaches/system/cpu/cpu0/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl-skx-twocaches/system/cpu/cpu0/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu0/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu0/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu0/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu1/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu1/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu1/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu10/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu10/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu10/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu11/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu11/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu11/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu2/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu2/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu2/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu3/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu3/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu3/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu4/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu4/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu4/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu5/node0 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu5/node0 +new file mode 120000 +index 0000000000..222b6af326 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu5/node0 +@@ -0,0 +1 @@ ++../../node/node0 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu6/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu6/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu6/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu7/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu7/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu7/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu8/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu8/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu8/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu9/node1 b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu9/node1 +new file mode 120000 +index 0000000000..1f9c101cd1 +--- /dev/null ++++ b/tests/vircaps2xmldata/linux-resctrl/system/cpu/cpu9/node1 +@@ -0,0 +1 @@ ++../../node/node1 +\ No newline at end of file +diff --git a/tests/virnumamock.c b/tests/virnumamock.c +index 87c9a58c6f..8d5c862fa2 100644 +--- a/tests/virnumamock.c ++++ b/tests/virnumamock.c +@@ -21,6 +21,7 @@ + #include "internal.h" + #include "virnuma.h" + #include "virfile.h" ++#include "virstring.h" + + #define VIR_FROM_THIS VIR_FROM_NONE + +@@ -171,3 +172,44 @@ virNumaGetNodeCPUs(int node, virBitmap **cpus) + + return virBitmapCountBits(*cpus); + } ++ ++int ++virNumaGetNodeOfCPU(int cpu) ++{ ++ g_autoptr(DIR) cpuDir = NULL; ++ g_autofree char *sysfs_cpu_path = NULL; ++ struct dirent *ent = NULL; ++ int dirErr = 0; ++ ++ sysfs_cpu_path = g_strdup_printf("%s/cpu/cpu%d", SYSFS_SYSTEM_PATH, cpu); ++ ++ if (virDirOpen(&cpuDir, sysfs_cpu_path) < 0) ++ return -1; ++ ++ while ((dirErr = virDirRead(cpuDir, &ent, sysfs_cpu_path)) > 0) { ++ g_autofree char *entPath = NULL; ++ const char *number = NULL; ++ int node; ++ ++ if (!(number = STRSKIP(ent->d_name, "node"))) ++ continue; ++ ++ entPath = g_strdup_printf("%s/%s", sysfs_cpu_path, ent->d_name); ++ ++ if (!virFileIsLink(entPath)) ++ continue; ++ ++ if (virStrToLong_i(number, NULL, 10, &node) < 0) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ return node; ++ } ++ ++ if (dirErr < 0) ++ return -1; ++ ++ errno = EINVAL; ++ return -1; ++} +-- +2.40.0 diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index 11f2a49..fd79e48 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -229,7 +229,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 9.0.0 -Release: 10%{?dist}%{?extra_release} +Release: 10.1%{?dist}%{?extra_release} License: LGPLv2+ URL: https://libvirt.org/ @@ -290,6 +290,21 @@ Patch49: libvirt-security-make-args-to-virSecuritySELinuxContextAddRange-const.p Patch50: libvirt-security-make-it-possible-to-set-SELinux-label-of-child-process-from-its-binary.patch Patch51: libvirt-qemu-set-SELinux-label-of-passt-process-to-its-own-binary-s-label.patch Patch52: libvirt-po-Updated-translation-files-from-upstream.patch +Patch53: libvirt-virnuma-Move-virNumaNodesetToCPUset-out-of-WITH_NUMACTL.patch +Patch54: libvirt-virnuma-Introduce-virNumaCPUSetToNodeset.patch +Patch55: libvirt-virnumamock-Introduce-virNumaGetNodeOfCPU-mock.patch +Patch56: libvirt-qemuxml2argvtest-Use-virnuma-mock.patch +Patch57: libvirt-qemuxml2argvdata-Adjust-maximum-NUMA-node-used.patch +Patch58: libvirt-qemuxml2argvdata-Extend-vCPUs-placement-in-memory-hotplug-dimm-addr.xml.patch +Patch59: libvirt-qemuxml2argvmock-Drop-virNuma-mocks.patch +Patch60: libvirt-qemu-Move-cpuset-preference-evaluation-into-a-separate-function.patch +Patch61: libvirt-qemu-Fix-qemuDomainGetEmulatorPinInfo.patch +Patch62: libvirt-qemuBuildMemoryBackendProps-Join-two-conditions.patch +Patch63: libvirt-qemu-Add-nodemaskRet-argument-to-qemuBuildMemoryBackendProps.patch +Patch64: libvirt-qemu-Add-nodemask-argument-to-qemuBuildThreadContextProps.patch +Patch65: libvirt-qemuBuildThreadContextProps-Prune-.node-affinity-wrt-emulatorpin.patch +Patch66: libvirt-docs-Document-memory-allocation-and-emulator-pinning-limitation.patch +Patch67: libvirt-conf-Fix-migration-in-some-firmware-autoselection-scenarios.patch Requires: libvirt-daemon = %{version}-%{release} @@ -2383,6 +2398,23 @@ exit 0 %endif %changelog +* Fri Apr 14 2023 Jiri Denemark - 9.0.0-10.1.el9_2 +- virnuma: Move virNumaNodesetToCPUset() out of WITH_NUMACTL (rhbz#2185039) +- virnuma: Introduce virNumaCPUSetToNodeset() (rhbz#2185039) +- virnumamock: Introduce virNumaGetNodeOfCPU() mock (rhbz#2185039) +- qemuxml2argvtest: Use virnuma mock (rhbz#2185039) +- qemuxml2argvdata: Adjust maximum NUMA node used (rhbz#2185039) +- qemuxml2argvdata: Extend vCPUs placement in memory-hotplug-dimm-addr.xml (rhbz#2185039) +- qemuxml2argvmock: Drop virNuma* mocks (rhbz#2185039) +- qemu: Move cpuset preference evaluation into a separate function (rhbz#2185039) +- qemu: Fix qemuDomainGetEmulatorPinInfo() (rhbz#2185039) +- qemuBuildMemoryBackendProps: Join two conditions (rhbz#2185039) +- qemu: Add @nodemaskRet argument to qemuBuildMemoryBackendProps() (rhbz#2185039) +- qemu: Add @nodemask argument to qemuBuildThreadContextProps() (rhbz#2185039) +- qemuBuildThreadContextProps: Prune .node-affinity wrt (rhbz#2185039) +- docs: Document memory allocation and emulator pinning limitation (rhbz#2185039) +- conf: Fix migration in some firmware autoselection scenarios (rhbz#2186383) + * Wed Mar 22 2023 Jiri Denemark - 9.0.0-10 - po: Updated translation files from upstream (rhbz#2139664)