On Thu, 30 Jun 2011 11:08:32 +0800
Gui Jianfeng <guijianfeng(a)cn.fujitsu.com> wrote:
Currently, libvirt makes use of sched_setaffinity() to set Guest
processes'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.
Is that issue able to be fixed by cpuset ?
Thanks,
-Kame
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 | 22 ++++++++++++++++++++++
src/qemu/qemu_conf.c | 3 ++-
src/util/cgroup.c | 18 ++++++++++++++++++
src/util/cgroup.h | 2 ++
5 files changed, 45 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..eb92409 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -296,6 +296,28 @@ int qemuSetupCgroup(struct qemud_driver *driver,
}
}
+ if (vm->def->cpumask != NULL) {
+ if (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);
+ } else {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Cpuset is not available on this host"));
+ }
+ }
+
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