Add capability to calculate hypervisor baseline using QMP message exchanges with QEMU in addition to existing capability to calculate baseline using libvirt utility functions. A new utility function encapsulates the core logic for interacting with QEMU using QMP baseline messages. The QMP messages only allow two cpu models to be evaluated at a time so a sequence of QMP baseline messages must be used to include all the models in the baseline when more than 2 cpu models are input. A QEMU process must be started prior to sending the series of QEMU messages to compute baseline. The QEMU process is started and maintained in the main hypervisor baseline function and only a pointer to the QEMU process monitor is passed to the baseline utility function. The QEMU process is maintained in the main hypervisor baseline function because the process will also be used for feature expansion (via QEMU) in a later patch. Signed-off-by: Chris Venteicher <cventeic@xxxxxxxxxx> --- src/qemu/qemu_driver.c | 97 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e9f5686dbe..5068805f51 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -13696,6 +13696,78 @@ qemuConnectBaselineCPU(virConnectPtr conn ATTRIBUTE_UNUSED, } +/* in: + * cpus[0]->model = "z14"; + * cpus[0]->features[0].name = "xxx"; + * cpus[0]->features[1].name = "yyy"; + * *** + * cpus[n]->model = "z13"; + * cpus[n]->features[0].name = "xxx"; + * cpus[n]->features[1].name = "yyy"; + * + * out: + * *baseline->model = "z13-base"; + * *baseline->features[0].name = "yyy"; + */ +static int +qemuConnectBaselineHypervisorCPUViaQEMU(qemuMonitorPtr mon, + virCPUDefPtr *cpus, + virCPUDefPtr *baseline) +{ + qemuMonitorCPUModelInfoPtr model_baseline = NULL; + qemuMonitorCPUModelInfoPtr new_model_baseline = NULL; + qemuMonitorCPUModelInfoPtr next_model = NULL; + bool migratable = true; + int ret = -1; + size_t i; + + *baseline = NULL; + + if (!cpus || !cpus[0]) { + virReportError(VIR_ERR_INVALID_ARG, "%s", _("no cpus")); + goto cleanup; + } + + for (i = 0; cpus[i]; i++) { /* cpus terminated by NULL element */ + virCPUDefPtr cpu = cpus[i]; + + VIR_DEBUG("cpu[%lu]->model = %s", i, NULLSTR(cpu->model)); + + if (!(next_model = virQEMUCapsCPUModelInfoFromCPUDef(cpu))) + goto cleanup; + + if (i == 0) { + model_baseline = next_model; + continue; + } + + if (qemuMonitorGetCPUModelBaseline(mon, model_baseline, + next_model, &new_model_baseline) < 0) + goto cleanup; + + qemuMonitorCPUModelInfoFree(model_baseline); + qemuMonitorCPUModelInfoFree(next_model); + + next_model = NULL; + + model_baseline = new_model_baseline; + } + + if (!(*baseline = virQEMUCapsCPUModelInfoToCPUDef(model_baseline, migratable))) + goto cleanup; + + VIR_DEBUG("baseline->model = %s", (*baseline)->model); + + ret = 0; + + cleanup: + qemuMonitorCPUModelInfoFree(model_baseline); + qemuMonitorCPUModelInfoFree(next_model); + + return ret; +} + + static int qemuConnectBaselineHypervisorCPUViaLibvirt( virQEMUCapsPtr qemuCaps, @@ -13764,6 +13836,11 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, virCPUDefPtr cpu = NULL; char *cpustr = NULL; bool useLibvirt = false; + bool useQemu = false; + bool forceTCG = false; + qemuMonitorCPUModelInfoPtr modelInfo = NULL; + qemuMonitorCPUModelInfoPtr expansion = NULL; + qemuProcessQMPPtr proc = NULL; virCheckFlags(VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES | VIR_CONNECT_BASELINE_CPU_MIGRATABLE, NULL); @@ -13784,6 +13861,7 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, goto cleanup; useLibvirt = ARCH_IS_X86(arch); + useQemu = ARCH_IS_S390(arch); if (useLibvirt) { migratable = !!(flags & VIR_CONNECT_BASELINE_CPU_MIGRATABLE); @@ -13792,6 +13870,21 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, virttype, arch, cpus, ncpus, &cpu) < 0) goto cleanup; + + } else if (useQemu) { + const char *binary = virQEMUCapsGetBinary(qemuCaps); + virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver); + + if (!(proc = qemuProcessQMPNew(binary, cfg->libDir, + cfg->user, cfg->group, forceTCG))) + goto cleanup; + + if (qemuProcessQMPStart(proc) < 0) + goto cleanup; + + if ((qemuConnectBaselineHypervisorCPUViaQEMU(proc->mon, cpus, &cpu) < 0) || !cpu) + goto cleanup; + } else { virReportError(VIR_ERR_OPERATION_UNSUPPORTED, _("computing baseline hypervisor CPU is not supported " @@ -13819,6 +13912,10 @@ qemuConnectBaselineHypervisorCPU(virConnectPtr conn, virCPUDefListFree(cpus); virCPUDefFree(cpu); virObjectUnref(qemuCaps); + qemuMonitorCPUModelInfoFree(modelInfo); + qemuMonitorCPUModelInfoFree(expansion); + qemuProcessQMPStop(proc); + qemuProcessQMPFree(proc); return cpustr; } -- 2.17.1 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list