ch_driver: emulator threadinfo & pinning callbacks

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
Praveen K Paladugu 2022-01-25 16:19:59 +00:00 committed by Michal Privoznik
parent 81226d8803
commit 782ef1a992

View File

@ -1280,6 +1280,161 @@ chDomainPinVcpu(virDomainPtr dom,
VIR_DOMAIN_AFFECT_LIVE);
}
static int
chDomainGetEmulatorPinInfo(virDomainPtr dom,
unsigned char *cpumaps,
int maplen,
unsigned int flags)
{
virDomainObj *vm = NULL;
virDomainDef *def;
virCHDomainObjPrivate *priv;
bool live;
int ret = -1;
virBitmap *cpumask = NULL;
g_autoptr(virBitmap) bitmap = NULL;
virBitmap *autoCpuset = NULL;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
if (!(vm = virCHDomainObjFromDomain(dom)))
goto cleanup;
if (virDomainGetEmulatorPinInfoEnsureACL(dom->conn, vm->def) < 0)
goto cleanup;
if (!(def = virDomainObjGetOneDefState(vm, flags, &live)))
goto cleanup;
if (live) {
priv = vm->privateData;
autoCpuset = priv->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 (!(bitmap = virHostCPUGetAvailableCPUsBitmap()))
goto cleanup;
cpumask = bitmap;
}
virBitmapToDataBuf(cpumask, cpumaps, maplen);
ret = 1;
cleanup:
virDomainObjEndAPI(&vm);
return ret;
}
static int
chDomainPinEmulator(virDomainPtr dom,
unsigned char *cpumap,
int maplen,
unsigned int flags)
{
virCHDriver *driver = dom->conn->privateData;
virDomainObj *vm;
virDomainDef *def;
virDomainDef *persistentDef;
int ret = -1;
virCHDomainObjPrivate *priv;
g_autoptr(virBitmap) pcpumap = NULL;
g_autoptr(virCHDriverConfig) cfg = NULL;
virTypedParameterPtr eventParams = NULL;
int eventNparams = 0;
int eventMaxparams = 0;
virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |
VIR_DOMAIN_AFFECT_CONFIG, -1);
cfg = virCHDriverGetConfig(driver);
if (!(vm = virCHDomainObjFromDomain(dom)))
goto cleanup;
if (virDomainPinEmulatorEnsureACL(dom->conn, vm->def, flags) < 0)
goto cleanup;
if (virCHDomainObjBeginJob(vm, CH_JOB_MODIFY) < 0)
goto cleanup;
if (virDomainObjGetDefs(vm, flags, &def, &persistentDef) < 0)
goto endjob;
priv = vm->privateData;
if (!(pcpumap = virBitmapNewData(cpumap, maplen)))
goto endjob;
if (virBitmapIsAllClear(pcpumap)) {
virReportError(VIR_ERR_INVALID_ARG, "%s",
_("Empty cpu list for pinning"));
goto endjob;
}
if (def) {
g_autoptr(virCgroup) cgroup_emulator = NULL;
g_autofree char *str = NULL;
if (virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_CPUSET)) {
if (virCgroupNewThread(priv->cgroup, VIR_CGROUP_THREAD_EMULATOR,
0, false, &cgroup_emulator) < 0)
goto endjob;
if (virDomainCgroupSetupCpusetCpus(cgroup_emulator, pcpumap) < 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
_("failed to set cpuset.cpus in cgroup"
" for emulator threads"));
goto endjob;
}
}
if (virProcessSetAffinity(vm->pid, pcpumap, false) < 0)
goto endjob;
virBitmapFree(def->cputune.emulatorpin);
def->cputune.emulatorpin = NULL;
if (!(def->cputune.emulatorpin = virBitmapNewCopy(pcpumap)))
goto endjob;
if (virDomainObjSave(vm, driver->xmlopt, cfg->stateDir) < 0)
goto endjob;
str = virBitmapFormat(pcpumap);
if (virTypedParamsAddString(&eventParams, &eventNparams,
&eventMaxparams,
VIR_DOMAIN_TUNABLE_CPU_EMULATORPIN,
str) < 0)
goto endjob;
}
if (persistentDef) {
virBitmapFree(persistentDef->cputune.emulatorpin);
persistentDef->cputune.emulatorpin = virBitmapNewCopy(pcpumap);
/* Inactive XMLs are not saved, yet. */
}
ret = 0;
endjob:
virCHDomainObjEndJob(vm);
cleanup:
virDomainObjEndAPI(&vm);
return ret;
}
#define CH_NB_NUMA_PARAM 2
static int
@ -1585,6 +1740,8 @@ static virHypervisorDriver chHypervisorDriver = {
.domainGetVcpuPinInfo = chDomainGetVcpuPinInfo, /* 8.0.0 */
.domainPinVcpu = chDomainPinVcpu, /* 8.1.0 */
.domainPinVcpuFlags = chDomainPinVcpuFlags, /* 8.1.0 */
.domainPinEmulator = chDomainPinEmulator, /* 8.1.0 */
.domainGetEmulatorPinInfo = chDomainGetEmulatorPinInfo, /* 8.1.0 */
.nodeGetCPUMap = chNodeGetCPUMap, /* 8.0.0 */
.domainSetNumaParameters = chDomainSetNumaParameters, /* 8.1.0 */
.domainGetNumaParameters = chDomainGetNumaParameters, /* 8.1.0 */