diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index cf098523d0..abdbce92dd 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3613,6 +3613,7 @@ qemuBuildThreadContextProps(virJSONValue **tcProps, g_autoptr(virJSONValue) nodemaskCopy = NULL; g_autofree char *tcAlias = NULL; const char *memalias = NULL; + bool prealloc = false; *tcProps = NULL; @@ -3645,6 +3646,12 @@ qemuBuildThreadContextProps(virJSONValue **tcProps, NULL) < 0) return -1; + if (virJSONValueObjectGetBoolean(*memProps, "prealloc", &prealloc) >= 0 && + prealloc) { + priv->threadContextAliases = g_slist_prepend(priv->threadContextAliases, + g_steal_pointer(&tcAlias)); + } + *tcProps = g_steal_pointer(&props); return 0; } diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0d579bfc9b..ef1a9c8c74 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -1811,6 +1811,8 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivate *priv) priv->preMigrationMemlock = 0; virHashRemoveAll(priv->statsSchema); + + g_slist_free_full(g_steal_pointer(&priv->threadContextAliases), g_free); } diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index d5f4fbad12..a9af8502d2 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -251,6 +251,8 @@ struct _qemuDomainObjPrivate { * briefly when starting a guest. Don't save/parse into XML. */ pid_t schedCoreChildPID; pid_t schedCoreChildFD; + + GSList *threadContextAliases; /* List of IDs of thread-context objects */ }; #define QEMU_DOMAIN_PRIVATE(vm) \ diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 4b26c384cf..0769f30d74 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -7500,6 +7500,50 @@ qemuProcessSetupLifecycleActions(virDomainObj *vm, } +int +qemuProcessDeleteThreadContext(virDomainObj *vm) +{ + qemuDomainObjPrivate *priv = vm->privateData; + GSList *next = priv->threadContextAliases; + int ret = -1; + + if (!next) + return 0; + + for (; next; next = next->next) { + if (qemuMonitorDelObject(priv->mon, next->data, true) < 0) + goto cleanup; + } + + ret = 0; + cleanup: + g_slist_free_full(g_steal_pointer(&priv->threadContextAliases), g_free); + return ret; +} + + +static int +qemuProcessDeleteThreadContextHelper(virDomainObj *vm, + virDomainAsyncJob asyncJob) +{ + qemuDomainObjPrivate *priv = vm->privateData; + int ret = -1; + + if (!priv->threadContextAliases) + return 0; + + VIR_DEBUG("Deleting thread context objects"); + if (qemuDomainObjEnterMonitorAsync(vm, asyncJob) < 0) + return -1; + + ret = qemuProcessDeleteThreadContext(vm); + + qemuDomainObjExitMonitor(vm); + + return ret; +} + + /** * qemuProcessLaunch: * @@ -7860,6 +7904,9 @@ qemuProcessLaunch(virConnectPtr conn, if (qemuProcessSetupLifecycleActions(vm, asyncJob) < 0) goto cleanup; + if (qemuProcessDeleteThreadContextHelper(vm, asyncJob) < 0) + goto cleanup; + ret = 0; cleanup: diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h index d1f58ee258..9a24745f15 100644 --- a/src/qemu/qemu_process.h +++ b/src/qemu/qemu_process.h @@ -123,6 +123,8 @@ int qemuProcessPrepareHost(virQEMUDriver *driver, virDomainObj *vm, unsigned int flags); +int qemuProcessDeleteThreadContext(virDomainObj *vm); + int qemuProcessLaunch(virConnectPtr conn, virQEMUDriver *driver, virDomainObj *vm,