On Thu, Jul 21, 2011 at 10:08:03AM +0800, Wen Congyang wrote: > Introduce the function virCgroupForVcpu() to create sub directory for each vcpu. > --- > src/libvirt_private.syms | 1 + > src/util/cgroup.c | 72 ++++++++++++++++++++++++++++++++++++++++++--- > src/util/cgroup.h | 5 +++ > 3 files changed, 73 insertions(+), 5 deletions(-) > > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms > index 3e3b1dd..30804eb 100644 > --- a/src/libvirt_private.syms > +++ b/src/libvirt_private.syms > @@ -67,6 +67,7 @@ virCgroupDenyAllDevices; > virCgroupDenyDevicePath; > virCgroupForDomain; > virCgroupForDriver; > +virCgroupForVcpu; > virCgroupFree; > virCgroupGetBlkioWeight; > virCgroupGetCpuShares; > diff --git a/src/util/cgroup.c b/src/util/cgroup.c > index 740cedf..8994aca 100644 > --- a/src/util/cgroup.c > +++ b/src/util/cgroup.c > @@ -52,6 +52,16 @@ struct virCgroup { > struct virCgroupController controllers[VIR_CGROUP_CONTROLLER_LAST]; > }; > > +typedef enum { > + VIR_CGROUP_NONE = 0, /* create subdir under each cgroup if possible. */ > + VIR_CGROUP_MEM_HIERACHY = 1 << 0, /* call virCgroupSetMemoryUseHierarchy > + * before creating subcgroups and > + * attaching tasks > + */ > + VIR_CGROUP_VCPU = 1 << 1, /* create subdir only under the cgroup cpu, > + * cpuacct and cpuset if possible. */ > +} virCgroupFlags; > + > /** > * virCgroupFree: > * > @@ -503,7 +513,7 @@ static int virCgroupSetMemoryUseHierarchy(virCgroupPtr group) > } > > static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group, > - int create, bool memory_hierarchy) > + int create, unsigned int flags) > { > int i; > int rc = 0; > @@ -516,6 +526,13 @@ static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group, > if (!group->controllers[i].mountPoint) > continue; > > + /* We need to control cpu bandwidth for each vcpu now */ > + if ((flags & VIR_CGROUP_VCPU) && i != VIR_CGROUP_CONTROLLER_CPU) { small nit, I woudl put () on both side of the && > + /* treat it as unmounted and we can use virCgroupAddTask */ > + VIR_FREE(group->controllers[i].mountPoint); > + continue; > + } > + > rc = virCgroupPathOfController(group, i, "", &path); > if (rc < 0) > return rc; > @@ -555,7 +572,7 @@ static int virCgroupMakeGroup(virCgroupPtr parent, virCgroupPtr group, > * Note that virCgroupSetMemoryUseHierarchy should always be > * called prior to creating subcgroups and attaching tasks. > */ > - if (memory_hierarchy && > + if ((flags & VIR_CGROUP_MEM_HIERACHY) && > group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint != NULL && same here > (i == VIR_CGROUP_CONTROLLER_MEMORY || > STREQ(group->controllers[i].mountPoint, group->controllers[VIR_CGROUP_CONTROLLER_MEMORY].mountPoint))) { > @@ -641,7 +658,7 @@ static int virCgroupAppRoot(int privileged, > if (rc != 0) > goto cleanup; > > - rc = virCgroupMakeGroup(rootgrp, *group, create, false); > + rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE); > > cleanup: > virCgroupFree(&rootgrp); > @@ -801,7 +818,7 @@ int virCgroupForDriver(const char *name, > VIR_FREE(path); > > if (rc == 0) { > - rc = virCgroupMakeGroup(rootgrp, *group, create, false); > + rc = virCgroupMakeGroup(rootgrp, *group, create, VIR_CGROUP_NONE); > if (rc != 0) > virCgroupFree(group); > } > @@ -861,7 +878,7 @@ int virCgroupForDomain(virCgroupPtr driver, > * a group for driver, is to avoid overhead to track > * cumulative usage that we don't need. > */ > - rc = virCgroupMakeGroup(driver, *group, create, true); > + rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_MEM_HIERACHY); > if (rc != 0) > virCgroupFree(group); > } > @@ -879,6 +896,51 @@ int virCgroupForDomain(virCgroupPtr driver ATTRIBUTE_UNUSED, > #endif > > /** > + * virCgroupForVcpu: > + * > + * @driver: group for the domain > + * @vcpuid: id of the vcpu > + * @group: Pointer to returned virCgroupPtr > + * > + * Returns 0 on success > + */ > +#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R > +int virCgroupForVcpu(virCgroupPtr driver, > + int vcpuid, > + virCgroupPtr *group, > + int create) > +{ > + int rc; > + char *path; > + > + if (driver == NULL) > + return -EINVAL; > + > + if (virAsprintf(&path, "%s/vcpu%d", driver->path, vcpuid) < 0) > + return -ENOMEM; > + > + rc = virCgroupNew(path, group); > + VIR_FREE(path); > + > + if (rc == 0) { > + rc = virCgroupMakeGroup(driver, *group, create, VIR_CGROUP_VCPU); > + if (rc != 0) > + virCgroupFree(group); > + } > + > + return rc; > +} > +#else > +int virCgroupForVcpu(virCgroupPtr driver ATTRIBUTE_UNUSED, > + int vcpuid ATTRIBUTE_UNUSED, > + virCgroupPtr *group ATTRIBUTE_UNUSED, > + int create ATTRIBUTE_UNUSED) > +{ > + return -ENXIO; > +} > +#endif > + > +/** > * virCgroupSetBlkioWeight: > * > * @group: The cgroup to change io weight for > diff --git a/src/util/cgroup.h b/src/util/cgroup.h > index 8ae756d..1d04418 100644 > --- a/src/util/cgroup.h > +++ b/src/util/cgroup.h > @@ -40,6 +40,11 @@ int virCgroupForDomain(virCgroupPtr driver, > virCgroupPtr *group, > int create); > > +int virCgroupForVcpu(virCgroupPtr driver, > + int vcpuid, > + virCgroupPtr *group, > + int create); > + > int virCgroupPathOfController(virCgroupPtr group, > int controller, > const char *key, > -- > 1.7.1 ACK, Daniel -- Daniel Veillard | libxml Gnome XML XSLT toolkit http://xmlsoft.org/ daniel@xxxxxxxxxxxx | Rpmfind RPM search engine http://rpmfind.net/ http://veillard.com/ | virtualization library http://libvirt.org/ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list