From ba63d8f7d843461f77a8206c1ef9da38388713e5 Mon Sep 17 00:00:00 2001 From: Martin Kletzander Date: Wed, 17 Oct 2012 16:39:31 +0200 Subject: [PATCH] qemu: Pin the emulator when only cpuset is specified According to our recent changes (clarifications), we should be pinning qemu's emulator processes using the 'cpuset' attribute in case there is no specified. This however doesn't work entirely as expected and this patch should resolve all the remaining issues. --- src/qemu/qemu_cgroup.c | 25 ++++++++++++++++--------- src/qemu/qemu_cgroup.h | 4 ++-- src/qemu/qemu_driver.c | 3 ++- src/qemu/qemu_process.c | 16 ++++++++-------- 4 files changed, 28 insertions(+), 20 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 166f9b97b7..6b94686a79 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -501,7 +501,7 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, for (i = 0; i < nvcpupin; i++) { if (vcpuid == vcpupin[i]->vcpuid) { - return qemuSetupCgroupEmulatorPin(cgroup, vcpupin[i]); + return qemuSetupCgroupEmulatorPin(cgroup, vcpupin[i]->cpumask); } } @@ -509,12 +509,12 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, } int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, - virDomainVcpuPinDefPtr vcpupin) + virBitmapPtr cpumask) { int rc = 0; char *new_cpus = NULL; - new_cpus = virBitmapFormat(vcpupin->cpumask); + new_cpus = virBitmapFormat(cpumask); if (!new_cpus) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("failed to convert cpu mask")); @@ -643,6 +643,7 @@ cleanup: int qemuSetupCgroupForEmulator(struct qemud_driver *driver, virDomainObjPtr vm) { + virBitmapPtr cpumask = NULL; virCgroupPtr cgroup = NULL; virCgroupPtr cgroup_emulator = NULL; virDomainDefPtr def = vm->def; @@ -690,12 +691,18 @@ int qemuSetupCgroupForEmulator(struct qemud_driver *driver, } } - if (def->cputune.emulatorpin && - qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { - rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, - def->cputune.emulatorpin); - if (rc < 0) - goto cleanup; + if (def->cputune.emulatorpin) + cpumask = def->cputune.emulatorpin->cpumask; + else if (def->cpumask) + cpumask = def->cpumask; + + if (cpumask) { + if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { + rc = qemuSetupCgroupEmulatorPin(cgroup_emulator, cpumask); + if (rc < 0) + goto cleanup; + } + cpumask = NULL; /* sanity */ } if (period || quota) { diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index b7b021189e..362080aa26 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -1,7 +1,7 @@ /* * qemu_cgroup.h: QEMU cgroup management * - * Copyright (C) 2006-2007, 2009-2011 Red Hat, Inc. + * Copyright (C) 2006-2007, 2009-2012 Red Hat, Inc. * Copyright (C) 2006 Daniel P. Berrange * * This library is free software; you can redistribute it and/or @@ -57,7 +57,7 @@ int qemuSetupCgroupVcpuPin(virCgroupPtr cgroup, virDomainVcpuPinDefPtr *vcpupin, int nvcpupin, int vcpuid); -int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virDomainVcpuPinDefPtr vcpupin); +int qemuSetupCgroupEmulatorPin(virCgroupPtr cgroup, virBitmapPtr cpumask); int qemuSetupCgroupForVcpu(struct qemud_driver *driver, virDomainObjPtr vm); int qemuSetupCgroupForEmulator(struct qemud_driver *driver, virDomainObjPtr vm); diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index fa37bfd3cb..adfbfa6acf 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4245,7 +4245,8 @@ qemudDomainPinEmulator(virDomainPtr dom, if (virCgroupForDomain(driver->cgroup, vm->def->name, &cgroup_dom, 0) == 0) { if (virCgroupForEmulator(cgroup_dom, &cgroup_emulator, 0) == 0) { - if (qemuSetupCgroupEmulatorPin(cgroup_emulator, newVcpuPin[0]) < 0) { + if (qemuSetupCgroupEmulatorPin(cgroup_emulator, + newVcpuPin[0]->cpumask) < 0) { virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("failed to set cpuset.cpus in cgroup" " for emulator threads")); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index a94e9c4a36..e08ec6757f 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -2024,11 +2024,12 @@ cleanup: return ret; } -/* Set CPU affinities for emulator threads if emulatorpin xml provided. */ +/* Set CPU affinities for emulator threads. */ static int qemuProcessSetEmulatorAffinites(virConnectPtr conn, virDomainObjPtr vm) { + virBitmapPtr cpumask; virDomainDefPtr def = vm->def; virNodeInfo nodeinfo; int ret = -1; @@ -2036,15 +2037,14 @@ qemuProcessSetEmulatorAffinites(virConnectPtr conn, if (virNodeGetInfo(conn, &nodeinfo) != 0) return -1; - if (!def->cputune.emulatorpin) - return 0; - - if (virProcessInfoSetAffinity(vm->pid, - def->cputune.emulatorpin->cpumask) < 0) { + if (def->cputune.emulatorpin) + cpumask = def->cputune.emulatorpin->cpumask; + else if (def->cpumask) + cpumask = def->cpumask; + else goto cleanup; - } - ret = 0; + ret = virProcessInfoSetAffinity(vm->pid, cpumask); cleanup: return ret; } -- GitLab