]> git.proxmox.com Git - mirror_ubuntu-focal-kernel.git/commitdiff
cgroup, rstat: Don't flush subtree root unless necessary
authorTejun Heo <tj@kernel.org>
Fri, 15 Feb 2019 19:01:31 +0000 (11:01 -0800)
committerTejun Heo <tj@kernel.org>
Fri, 15 Feb 2019 19:01:31 +0000 (11:01 -0800)
cgroup_rstat_cpu_pop_updated() is used to traverse the updated cgroups
on flush.  While it was only visiting updated ones in the subtree, it
was visiting @root unconditionally.  We can easily check whether @root
is updated or not by looking at its ->updated_next just as with the
cgroups in the subtree.

* Remove the unnecessary cgroup_parent() test.  The system root cgroup
  is never updated and thus its ->updated_next is always NULL.  No
  need to test whether cgroup_parent() exists in addition to
  ->updated_next.

* Terminate traverse if ->updated_next is NULL.  This can only happen
  for subtree @root and there's no reason to visit it if it's not
  marked updated.

This reduces cpu consumption when reading a lot of rstat backed files.
In a micro benchmark reading stat from ~1600 cgroups, the sys time was
lowered by >40%.

Signed-off-by: Tejun Heo <tj@kernel.org>
kernel/cgroup/rstat.c

index d503d1a9007c9e1d01928c8e7effe5c9f0511753..bb95a35e8c2d0785ec7ce2acfb2c64a74e5935a2 100644 (file)
@@ -87,7 +87,6 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
                                                   struct cgroup *root, int cpu)
 {
        struct cgroup_rstat_cpu *rstatc;
-       struct cgroup *parent;
 
        if (pos == root)
                return NULL;
@@ -115,8 +114,8 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
         * However, due to the way we traverse, @pos will be the first
         * child in most cases. The only exception is @root.
         */
-       parent = cgroup_parent(pos);
-       if (parent && rstatc->updated_next) {
+       if (rstatc->updated_next) {
+               struct cgroup *parent = cgroup_parent(pos);
                struct cgroup_rstat_cpu *prstatc = cgroup_rstat_cpu(parent, cpu);
                struct cgroup_rstat_cpu *nrstatc;
                struct cgroup **nextp;
@@ -140,9 +139,12 @@ static struct cgroup *cgroup_rstat_cpu_pop_updated(struct cgroup *pos,
                 * updated stat.
                 */
                smp_mb();
+
+               return pos;
        }
 
-       return pos;
+       /* only happens for @root */
+       return NULL;
 }
 
 /* see cgroup_rstat_flush() */