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.
Signed-off-by: Gui Jianfeng <guijianfeng(a)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,
--
1.7.1