mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-01 17:35:17 +00:00
qemu: use query-cpus-fast in JSON monitor
Use query-cpus-fast instead of query-cpus if supported by QEMU. Based on the QEMU_CAPS_QUERY_CPUS_FAST capability. Signed-off-by: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com> Reviewed-by: John Ferlan <jferlan@redhat.com>
This commit is contained in:
parent
56665e9984
commit
41e335f99b
@ -9035,15 +9035,19 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|||||||
size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
|
size_t maxvcpus = virDomainDefGetVcpusMax(vm->def);
|
||||||
size_t i;
|
size_t i;
|
||||||
bool hotplug;
|
bool hotplug;
|
||||||
|
bool fast;
|
||||||
int rc;
|
int rc;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
|
||||||
hotplug = qemuDomainSupportsNewVcpuHotplug(vm);
|
hotplug = qemuDomainSupportsNewVcpuHotplug(vm);
|
||||||
|
fast = virQEMUCapsGet(QEMU_DOMAIN_PRIVATE(vm)->qemuCaps,
|
||||||
|
QEMU_CAPS_QUERY_CPUS_FAST);
|
||||||
|
|
||||||
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus, hotplug);
|
rc = qemuMonitorGetCPUInfo(qemuDomainGetMonitor(vm), &info, maxvcpus,
|
||||||
|
hotplug, fast);
|
||||||
|
|
||||||
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -9062,7 +9066,7 @@ qemuDomainRefreshVcpuInfo(virQEMUDriverPtr driver,
|
|||||||
* thread, but it runs every vCPU in that same thread. So it
|
* thread, but it runs every vCPU in that same thread. So it
|
||||||
* is impossible to setup different affinity per thread.
|
* is impossible to setup different affinity per thread.
|
||||||
*
|
*
|
||||||
* What's more the 'query-cpus' command returns bizarre
|
* What's more the 'query-cpus[-fast]' command returns bizarre
|
||||||
* data for the threads. It gives the TCG thread for the
|
* data for the threads. It gives the TCG thread for the
|
||||||
* vCPU 0, but for vCPUs 1-> N, it actually replies with
|
* vCPU 0, but for vCPUs 1-> N, it actually replies with
|
||||||
* the main process thread ID.
|
* the main process thread ID.
|
||||||
@ -9150,6 +9154,7 @@ qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver,
|
|||||||
virBitmapPtr haltedmap = NULL;
|
virBitmapPtr haltedmap = NULL;
|
||||||
size_t i;
|
size_t i;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
|
bool fast;
|
||||||
|
|
||||||
/* Not supported currently for TCG, see qemuDomainRefreshVcpuInfo */
|
/* Not supported currently for TCG, see qemuDomainRefreshVcpuInfo */
|
||||||
if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
if (vm->def->virtType == VIR_DOMAIN_VIRT_QEMU)
|
||||||
@ -9163,8 +9168,10 @@ qemuDomainRefreshVcpuHalted(virQEMUDriverPtr driver,
|
|||||||
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
haltedmap = qemuMonitorGetCpuHalted(qemuDomainGetMonitor(vm), maxvcpus);
|
fast = virQEMUCapsGet(QEMU_DOMAIN_PRIVATE(vm)->qemuCaps,
|
||||||
|
QEMU_CAPS_QUERY_CPUS_FAST);
|
||||||
|
haltedmap = qemuMonitorGetCpuHalted(qemuDomainGetMonitor(vm), maxvcpus,
|
||||||
|
fast);
|
||||||
if (qemuDomainObjExitMonitor(driver, vm) < 0 || !haltedmap)
|
if (qemuDomainObjExitMonitor(driver, vm) < 0 || !haltedmap)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -1847,15 +1847,16 @@ qemuMonitorGetCPUInfoLegacy(struct qemuMonitorQueryCpusEntry *cpuentries,
|
|||||||
*
|
*
|
||||||
* This function stitches together data retrieved via query-hotpluggable-cpus
|
* This function stitches together data retrieved via query-hotpluggable-cpus
|
||||||
* which returns entities on the hotpluggable level (which may describe more
|
* which returns entities on the hotpluggable level (which may describe more
|
||||||
* than one guest logical vcpu) with the output of query-cpus, having an entry
|
* than one guest logical vcpu) with the output of query-cpus (or
|
||||||
* per enabled guest logical vcpu.
|
* query-cpus-fast), having an entry per enabled guest logical vcpu.
|
||||||
*
|
*
|
||||||
* query-hotpluggable-cpus conveys following information:
|
* query-hotpluggable-cpus conveys following information:
|
||||||
* - topology information and number of logical vcpus this entry creates
|
* - topology information and number of logical vcpus this entry creates
|
||||||
* - device type name of the entry that needs to be used when hotplugging
|
* - device type name of the entry that needs to be used when hotplugging
|
||||||
* - qom path in qemu which can be used to map the entry against query-cpus
|
* - qom path in qemu which can be used to map the entry against
|
||||||
|
* query-cpus[-fast]
|
||||||
*
|
*
|
||||||
* query-cpus conveys following information:
|
* query-cpus[-fast] conveys following information:
|
||||||
* - thread id of a given guest logical vcpu
|
* - thread id of a given guest logical vcpu
|
||||||
* - order in which the vcpus were inserted
|
* - order in which the vcpus were inserted
|
||||||
* - qom path to allow mapping the two together
|
* - qom path to allow mapping the two together
|
||||||
@ -1890,7 +1891,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl
|
|||||||
for (i = 0; i < nhotplugvcpus; i++)
|
for (i = 0; i < nhotplugvcpus; i++)
|
||||||
totalvcpus += hotplugvcpus[i].vcpus;
|
totalvcpus += hotplugvcpus[i].vcpus;
|
||||||
|
|
||||||
/* trim '/thread...' suffix from the data returned by query-cpus */
|
/* trim '/thread...' suffix from the data returned by query-cpus[-fast] */
|
||||||
for (i = 0; i < ncpuentries; i++) {
|
for (i = 0; i < ncpuentries; i++) {
|
||||||
if (cpuentries[i].qom_path &&
|
if (cpuentries[i].qom_path &&
|
||||||
(tmp = strstr(cpuentries[i].qom_path, "/thread")))
|
(tmp = strstr(cpuentries[i].qom_path, "/thread")))
|
||||||
@ -1903,7 +1904,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Note the order in which the hotpluggable entities are inserted by
|
/* Note the order in which the hotpluggable entities are inserted by
|
||||||
* matching them to the query-cpus entries */
|
* matching them to the query-cpus[-fast] entries */
|
||||||
for (i = 0; i < ncpuentries; i++) {
|
for (i = 0; i < ncpuentries; i++) {
|
||||||
for (j = 0; j < nhotplugvcpus; j++) {
|
for (j = 0; j < nhotplugvcpus; j++) {
|
||||||
if (!cpuentries[i].qom_path ||
|
if (!cpuentries[i].qom_path ||
|
||||||
@ -1958,7 +1959,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (anyvcpu == maxvcpus) {
|
if (anyvcpu == maxvcpus) {
|
||||||
VIR_DEBUG("too many query-cpus entries for a given "
|
VIR_DEBUG("too many query-cpus[-fast] entries for a given "
|
||||||
"query-hotpluggable-cpus entry");
|
"query-hotpluggable-cpus entry");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -1986,6 +1987,7 @@ qemuMonitorGetCPUInfoHotplug(struct qemuMonitorQueryHotpluggableCpusEntry *hotpl
|
|||||||
* @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
|
* @vcpus: pointer filled by array of qemuMonitorCPUInfo structures
|
||||||
* @maxvcpus: total possible number of vcpus
|
* @maxvcpus: total possible number of vcpus
|
||||||
* @hotplug: query data relevant for hotplug support
|
* @hotplug: query data relevant for hotplug support
|
||||||
|
* @fast: use QMP query-cpus-fast if supported
|
||||||
*
|
*
|
||||||
* Detects VCPU information. If qemu doesn't support or fails reporting
|
* Detects VCPU information. If qemu doesn't support or fails reporting
|
||||||
* information this function will return success as other parts of libvirt
|
* information this function will return success as other parts of libvirt
|
||||||
@ -1998,7 +2000,8 @@ int
|
|||||||
qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUInfoPtr *vcpus,
|
qemuMonitorCPUInfoPtr *vcpus,
|
||||||
size_t maxvcpus,
|
size_t maxvcpus,
|
||||||
bool hotplug)
|
bool hotplug,
|
||||||
|
bool fast)
|
||||||
{
|
{
|
||||||
struct qemuMonitorQueryHotpluggableCpusEntry *hotplugcpus = NULL;
|
struct qemuMonitorQueryHotpluggableCpusEntry *hotplugcpus = NULL;
|
||||||
size_t nhotplugcpus = 0;
|
size_t nhotplugcpus = 0;
|
||||||
@ -2024,7 +2027,8 @@ qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (mon->json)
|
if (mon->json)
|
||||||
rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, hotplug);
|
rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, hotplug,
|
||||||
|
fast);
|
||||||
else
|
else
|
||||||
rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
|
rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
|
||||||
|
|
||||||
@ -2062,11 +2066,12 @@ qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
|||||||
* qemuMonitorGetCpuHalted:
|
* qemuMonitorGetCpuHalted:
|
||||||
*
|
*
|
||||||
* Returns a bitmap of vcpu id's that are halted. The id's correspond to the
|
* Returns a bitmap of vcpu id's that are halted. The id's correspond to the
|
||||||
* 'CPU' field as reported by query-cpus'.
|
* 'CPU' field as reported by query-cpus[-fast]'.
|
||||||
*/
|
*/
|
||||||
virBitmapPtr
|
virBitmapPtr
|
||||||
qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
|
qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
|
||||||
size_t maxvcpus)
|
size_t maxvcpus,
|
||||||
|
bool fast ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
|
struct qemuMonitorQueryCpusEntry *cpuentries = NULL;
|
||||||
size_t ncpuentries = 0;
|
size_t ncpuentries = 0;
|
||||||
@ -2077,7 +2082,8 @@ qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
|
|||||||
QEMU_CHECK_MONITOR_NULL(mon);
|
QEMU_CHECK_MONITOR_NULL(mon);
|
||||||
|
|
||||||
if (mon->json)
|
if (mon->json)
|
||||||
rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, false);
|
rc = qemuMonitorJSONQueryCPUs(mon, &cpuentries, &ncpuentries, false,
|
||||||
|
false);
|
||||||
else
|
else
|
||||||
rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
|
rc = qemuMonitorTextQueryCPUs(mon, &cpuentries, &ncpuentries);
|
||||||
|
|
||||||
|
@ -542,8 +542,11 @@ void qemuMonitorCPUInfoFree(qemuMonitorCPUInfoPtr list,
|
|||||||
int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
int qemuMonitorGetCPUInfo(qemuMonitorPtr mon,
|
||||||
qemuMonitorCPUInfoPtr *vcpus,
|
qemuMonitorCPUInfoPtr *vcpus,
|
||||||
size_t maxvcpus,
|
size_t maxvcpus,
|
||||||
bool hotplug);
|
bool hotplug,
|
||||||
virBitmapPtr qemuMonitorGetCpuHalted(qemuMonitorPtr mon, size_t maxvcpus);
|
bool fast);
|
||||||
|
virBitmapPtr qemuMonitorGetCpuHalted(qemuMonitorPtr mon,
|
||||||
|
size_t maxvcpus,
|
||||||
|
bool fast);
|
||||||
|
|
||||||
int qemuMonitorGetVirtType(qemuMonitorPtr mon,
|
int qemuMonitorGetVirtType(qemuMonitorPtr mon,
|
||||||
virDomainVirtType *virtType);
|
virDomainVirtType *virtType);
|
||||||
|
@ -1532,7 +1532,8 @@ int qemuMonitorJSONSystemReset(qemuMonitorPtr mon)
|
|||||||
static int
|
static int
|
||||||
qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
|
qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
|
||||||
struct qemuMonitorQueryCpusEntry **entries,
|
struct qemuMonitorQueryCpusEntry **entries,
|
||||||
size_t *nentries)
|
size_t *nentries,
|
||||||
|
bool fast)
|
||||||
{
|
{
|
||||||
struct qemuMonitorQueryCpusEntry *cpus = NULL;
|
struct qemuMonitorQueryCpusEntry *cpus = NULL;
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
@ -1557,11 +1558,19 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Some older qemu versions don't report the thread_id so treat this as
|
/* Some older qemu versions don't report the thread_id so treat this as
|
||||||
* non-fatal, simply returning no data */
|
* non-fatal, simply returning no data.
|
||||||
ignore_value(virJSONValueObjectGetNumberInt(entry, "CPU", &cpuid));
|
* The return data of query-cpus-fast has different field names
|
||||||
ignore_value(virJSONValueObjectGetNumberInt(entry, "thread_id", &thread));
|
*/
|
||||||
ignore_value(virJSONValueObjectGetBoolean(entry, "halted", &halted));
|
if (fast) {
|
||||||
qom_path = virJSONValueObjectGetString(entry, "qom_path");
|
ignore_value(virJSONValueObjectGetNumberInt(entry, "cpu-index", &cpuid));
|
||||||
|
ignore_value(virJSONValueObjectGetNumberInt(entry, "thread-id", &thread));
|
||||||
|
qom_path = virJSONValueObjectGetString(entry, "qom-path");
|
||||||
|
} else {
|
||||||
|
ignore_value(virJSONValueObjectGetNumberInt(entry, "CPU", &cpuid));
|
||||||
|
ignore_value(virJSONValueObjectGetNumberInt(entry, "thread_id", &thread));
|
||||||
|
ignore_value(virJSONValueObjectGetBoolean(entry, "halted", &halted));
|
||||||
|
qom_path = virJSONValueObjectGetString(entry, "qom_path");
|
||||||
|
}
|
||||||
|
|
||||||
cpus[i].qemu_id = cpuid;
|
cpus[i].qemu_id = cpuid;
|
||||||
cpus[i].tid = thread;
|
cpus[i].tid = thread;
|
||||||
@ -1586,10 +1595,12 @@ qemuMonitorJSONExtractCPUInfo(virJSONValuePtr data,
|
|||||||
* @mon: monitor object
|
* @mon: monitor object
|
||||||
* @entries: filled with detected entries on success
|
* @entries: filled with detected entries on success
|
||||||
* @nentries: number of entries returned
|
* @nentries: number of entries returned
|
||||||
|
* @force: force exit on error
|
||||||
|
* @fast: use query-cpus-fast
|
||||||
*
|
*
|
||||||
* Queries qemu for cpu-related information. Failure to execute the command or
|
* Queries qemu for cpu-related information. Failure to execute the command or
|
||||||
* extract results does not produce an error as libvirt can continue without
|
* extract results does not produce an error as libvirt can continue without
|
||||||
* this information.
|
* this information, unless the caller has specified @force == true.
|
||||||
*
|
*
|
||||||
* Returns 0 on success, -1 on a fatal error (oom ...) and -2 if the
|
* Returns 0 on success, -1 on a fatal error (oom ...) and -2 if the
|
||||||
* query failed gracefully.
|
* query failed gracefully.
|
||||||
@ -1598,13 +1609,19 @@ int
|
|||||||
qemuMonitorJSONQueryCPUs(qemuMonitorPtr mon,
|
qemuMonitorJSONQueryCPUs(qemuMonitorPtr mon,
|
||||||
struct qemuMonitorQueryCpusEntry **entries,
|
struct qemuMonitorQueryCpusEntry **entries,
|
||||||
size_t *nentries,
|
size_t *nentries,
|
||||||
bool force)
|
bool force,
|
||||||
|
bool fast)
|
||||||
{
|
{
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
virJSONValuePtr cmd = qemuMonitorJSONMakeCommand("query-cpus", NULL);
|
virJSONValuePtr cmd;
|
||||||
virJSONValuePtr reply = NULL;
|
virJSONValuePtr reply = NULL;
|
||||||
virJSONValuePtr data;
|
virJSONValuePtr data;
|
||||||
|
|
||||||
|
if (fast)
|
||||||
|
cmd = qemuMonitorJSONMakeCommand("query-cpus-fast", NULL);
|
||||||
|
else
|
||||||
|
cmd = qemuMonitorJSONMakeCommand("query-cpus", NULL);
|
||||||
|
|
||||||
if (!cmd)
|
if (!cmd)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -1619,7 +1636,7 @@ qemuMonitorJSONQueryCPUs(qemuMonitorPtr mon,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = qemuMonitorJSONExtractCPUInfo(data, entries, nentries);
|
ret = qemuMonitorJSONExtractCPUInfo(data, entries, nentries, fast);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
virJSONValueFree(cmd);
|
virJSONValueFree(cmd);
|
||||||
|
@ -60,7 +60,8 @@ int qemuMonitorJSONSystemReset(qemuMonitorPtr mon);
|
|||||||
int qemuMonitorJSONQueryCPUs(qemuMonitorPtr mon,
|
int qemuMonitorJSONQueryCPUs(qemuMonitorPtr mon,
|
||||||
struct qemuMonitorQueryCpusEntry **entries,
|
struct qemuMonitorQueryCpusEntry **entries,
|
||||||
size_t *nentries,
|
size_t *nentries,
|
||||||
bool force);
|
bool force,
|
||||||
|
bool fast);
|
||||||
int qemuMonitorJSONGetVirtType(qemuMonitorPtr mon,
|
int qemuMonitorJSONGetVirtType(qemuMonitorPtr mon,
|
||||||
virDomainVirtType *virtType);
|
virDomainVirtType *virtType);
|
||||||
int qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon,
|
int qemuMonitorJSONUpdateVideoMemorySize(qemuMonitorPtr mon,
|
||||||
|
@ -1425,7 +1425,7 @@ testQemuMonitorJSONqemuMonitorJSONQueryCPUs(const void *data)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (qemuMonitorJSONQueryCPUs(qemuMonitorTestGetMonitor(test),
|
if (qemuMonitorJSONQueryCPUs(qemuMonitorTestGetMonitor(test),
|
||||||
&cpudata, &ncpudata, true) < 0)
|
&cpudata, &ncpudata, true, false) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (ncpudata != 4) {
|
if (ncpudata != 4) {
|
||||||
@ -2638,7 +2638,7 @@ testQemuMonitorCPUInfo(const void *opaque)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
rc = qemuMonitorGetCPUInfo(qemuMonitorTestGetMonitor(test),
|
rc = qemuMonitorGetCPUInfo(qemuMonitorTestGetMonitor(test),
|
||||||
&vcpus, data->maxvcpus, true);
|
&vcpus, data->maxvcpus, true, false);
|
||||||
|
|
||||||
if (rc < 0)
|
if (rc < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user