
On 2011-7-2 9:42, Gui Jianfeng wrote:
Currently, libvirt makes use of sched_setaffinity() to set Guest's cpu affinity. But, sometimes, for instance, when QEmu uses vhost-net, the kernel part of vhost will create a kernel thread for some purpose. In this case, such kernel thread won't inherit QEmu's cpu affinity.
This patch enables cpuset cgroup in libvirt and setting cpu affinity by configuring cpuset cgroup.
Ping? Gui
Signed-off-by: Gui Jianfeng <guijianfeng@cn.fujitsu.com> --- src/libvirt_private.syms | 1 + src/qemu/qemu_cgroup.c | 18 ++++++++++++++++++ src/qemu/qemu_conf.c | 3 ++- src/util/cgroup.c | 18 ++++++++++++++++++ src/util/cgroup.h | 2 ++ 5 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 626ac6c..e7aebc7 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -83,6 +83,7 @@ virCgroupMounted; virCgroupPathOfController; virCgroupRemove; virCgroupSetBlkioWeight; +virCgroupCpusetSetcpus; virCgroupSetCpuShares; virCgroupSetFreezerState; virCgroupSetMemory; diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 1298924..413bee4 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -296,6 +296,24 @@ int qemuSetupCgroup(struct qemud_driver *driver, } }
+ if (vm->def->cpumask != NULL && + qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_CPUSET)) { + char *cpumask = NULL; + if ((cpumask = + virDomainCpuSetFormat(vm->def->cpumask, vm->def->cpumasklen)) == NULL) + goto cleanup; + + rc = virCgroupCpusetSetcpus(cgroup, cpumask); + if(rc != 0) { + virReportSystemError(-rc, + _("Unable to set cpus for domain %s"), + vm->def->name); + VIR_FREE(cpumask); + goto cleanup; + } + VIR_FREE(cpumask); + } + if (vm->def->blkio.weight != 0) { if (qemuCgroupControllerActive(driver, VIR_CGROUP_CONTROLLER_BLKIO)) { rc = virCgroupSetBlkioWeight(cgroup, vm->def->blkio.weight); diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c index 3d8aba4..8b478c4 100644 --- a/src/qemu/qemu_conf.c +++ b/src/qemu/qemu_conf.c @@ -307,7 +307,8 @@ int qemudLoadDriverConfig(struct qemud_driver *driver, (1 << VIR_CGROUP_CONTROLLER_CPU) | (1 << VIR_CGROUP_CONTROLLER_DEVICES) | (1 << VIR_CGROUP_CONTROLLER_MEMORY) | - (1 << VIR_CGROUP_CONTROLLER_BLKIO); + (1 << VIR_CGROUP_CONTROLLER_BLKIO) | + (1 << VIR_CGROUP_CONTROLLER_CPUSET); } for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) { if (driver->cgroupControllers & (1 << i)) { diff --git a/src/util/cgroup.c b/src/util/cgroup.c index 2e5ef46..89b2ad4 100644 --- a/src/util/cgroup.c +++ b/src/util/cgroup.c @@ -472,6 +472,24 @@ static int virCgroupCpuSetInherit(virCgroupPtr parent, virCgroupPtr group) return rc; }
+int virCgroupCpusetSetcpus(virCgroupPtr group, char *cpustring) +{ + int rc = 0; + const char *key = "cpuset.cpus"; + + VIR_DEBUG("Cpuset: set %s for %s/%s", cpustring, group->path, key); + + rc = virCgroupSetValueStr(group, + VIR_CGROUP_CONTROLLER_CPUSET, + key, + cpustring); + + if (rc != 0) + VIR_ERROR("Failed to set %s for %s/%s", cpustring, group->path, key); + + return rc; +} + static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group) { int rc = 0; diff --git a/src/util/cgroup.h b/src/util/cgroup.h index 8ae756d..ca6a68a 100644 --- a/src/util/cgroup.h +++ b/src/util/cgroup.h @@ -30,6 +30,8 @@ enum {
VIR_ENUM_DECL(virCgroupController);
+int virCgroupCpusetSetcpus(virCgroupPtr group, char *cpustring); + int virCgroupForDriver(const char *name, virCgroupPtr *group, int privileged,