cgroup, sched: Move basic cpu stats from cgroup.stat to cpu.stat
authorTejun Heo <tj@kernel.org>
Mon, 23 Oct 2017 23:18:27 +0000 (16:18 -0700)
committerTejun Heo <tj@kernel.org>
Thu, 26 Oct 2017 17:56:33 +0000 (10:56 -0700)
The basic cpu stat is currently shown with "cpu." prefix in
cgroup.stat, and the same information is duplicated in cpu.stat when
cpu controller is enabled.  This is ugly and not very scalable as we
want to expand the coverage of stat information which is always
available.

This patch makes cgroup core always create "cpu.stat" file and show
the basic cpu stat there and calls the cpu controller to show the
extra stats when enabled.  This ensures that the same information
isn't presented in multiple places and makes future expansion of basic
stats easier.

Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Documentation/cgroup-v2.txt
include/linux/cgroup-defs.h
include/linux/cgroup.h
kernel/cgroup/cgroup-internal.h
kernel/cgroup/cgroup.c
kernel/cgroup/stat.c
kernel/sched/core.c

index 0bbdc720dd7c4b554f0522c36f64abd96061d153..779211fbb69ffac450f22b0ad6864c7c6c2bd98f 100644 (file)
@@ -886,15 +886,6 @@ All cgroup core files are prefixed with "cgroup."
                A dying cgroup can consume system resources not exceeding
                limits, which were active at the moment of cgroup deletion.
 
-         cpu.usage_usec
-               CPU time consumed in the subtree.
-
-         cpu.user_usec
-               User CPU time consumed in the subtree.
-
-         cpu.system_usec
-               System CPU time consumed in the subtree.
-
 
 Controllers
 ===========
@@ -915,12 +906,16 @@ All time durations are in microseconds.
 
   cpu.stat
        A read-only flat-keyed file which exists on non-root cgroups.
+       This file exists whether the controller is enabled or not.
 
-       It reports the following six stats:
+       It always reports the following three stats:
 
        - usage_usec
        - user_usec
        - system_usec
+
+       and the following three when the controller is enabled:
+
        - nr_periods
        - nr_throttled
        - throttled_usec
index 3e55bbd31ad1578f898f5558eae7e594ec7d2bc8..ada6df7b1f55b8ee530489dd8ba9e1739db1ec71 100644 (file)
@@ -569,6 +569,8 @@ struct cgroup_subsys {
        void (*css_released)(struct cgroup_subsys_state *css);
        void (*css_free)(struct cgroup_subsys_state *css);
        void (*css_reset)(struct cgroup_subsys_state *css);
+       int (*css_extra_stat_show)(struct seq_file *seq,
+                                  struct cgroup_subsys_state *css);
 
        int (*can_attach)(struct cgroup_taskset *tset);
        void (*cancel_attach)(struct cgroup_taskset *tset);
index 328a70ce0e23c82387b9391687017b12255cba20..03cad08b09d138bfbaa0bacd27683c0bea348557 100644 (file)
@@ -703,8 +703,6 @@ static inline void cpuacct_account_field(struct task_struct *tsk, int index,
                                         u64 val) {}
 #endif
 
-void cgroup_stat_show_cputime(struct seq_file *seq, const char *prefix);
-
 void __cgroup_account_cputime(struct cgroup *cgrp, u64 delta_exec);
 void __cgroup_account_cputime_field(struct cgroup *cgrp,
                                    enum cpu_usage_stat index, u64 delta_exec);
index fa642c99586af84a216dc02c407f6d59297c6a13..4dc317090920414479bd3241be6757ef6dcd8d38 100644 (file)
@@ -205,6 +205,7 @@ int cgroup_task_count(const struct cgroup *cgrp);
 void cgroup_stat_flush(struct cgroup *cgrp);
 int cgroup_stat_init(struct cgroup *cgrp);
 void cgroup_stat_exit(struct cgroup *cgrp);
+void cgroup_stat_show_cputime(struct seq_file *seq);
 void cgroup_stat_boot(void);
 
 /*
index 7975b20f1fd122ec5c29e451113c1fe53e724d3a..d9773e49a1b4593db19200e365a6cd415a94293a 100644 (file)
@@ -463,6 +463,28 @@ static struct cgroup_subsys_state *cgroup_css(struct cgroup *cgrp,
                return &cgrp->self;
 }
 
+/**
+ * cgroup_tryget_css - try to get a cgroup's css for the specified subsystem
+ * @cgrp: the cgroup of interest
+ * @ss: the subsystem of interest
+ *
+ * Find and get @cgrp's css assocaited with @ss.  If the css doesn't exist
+ * or is offline, %NULL is returned.
+ */
+static struct cgroup_subsys_state *cgroup_tryget_css(struct cgroup *cgrp,
+                                                    struct cgroup_subsys *ss)
+{
+       struct cgroup_subsys_state *css;
+
+       rcu_read_lock();
+       css = cgroup_css(cgrp, ss);
+       if (!css || !css_tryget_online(css))
+               css = NULL;
+       rcu_read_unlock();
+
+       return css;
+}
+
 /**
  * cgroup_e_css - obtain a cgroup's effective css for the specified subsystem
  * @cgrp: the cgroup of interest
@@ -3311,11 +3333,40 @@ static int cgroup_stat_show(struct seq_file *seq, void *v)
        seq_printf(seq, "nr_dying_descendants %d\n",
                   cgroup->nr_dying_descendants);
 
-       cgroup_stat_show_cputime(seq, "cpu.");
-
        return 0;
 }
 
+static int __maybe_unused cgroup_extra_stat_show(struct seq_file *seq,
+                                                struct cgroup *cgrp, int ssid)
+{
+       struct cgroup_subsys *ss = cgroup_subsys[ssid];
+       struct cgroup_subsys_state *css;
+       int ret;
+
+       if (!ss->css_extra_stat_show)
+               return 0;
+
+       css = cgroup_tryget_css(cgrp, ss);
+       if (!css)
+               return 0;
+
+       ret = ss->css_extra_stat_show(seq, css);
+       css_put(css);
+       return ret;
+}
+
+static int cpu_stat_show(struct seq_file *seq, void *v)
+{
+       struct cgroup *cgrp = seq_css(seq)->cgroup;
+       int ret = 0;
+
+       cgroup_stat_show_cputime(seq);
+#ifdef CONFIG_CGROUP_SCHED
+       ret = cgroup_extra_stat_show(seq, cgrp, cpu_cgrp_id);
+#endif
+       return ret;
+}
+
 static int cgroup_file_open(struct kernfs_open_file *of)
 {
        struct cftype *cft = of->kn->priv;
@@ -4423,6 +4474,11 @@ static struct cftype cgroup_base_files[] = {
                .name = "cgroup.stat",
                .seq_show = cgroup_stat_show,
        },
+       {
+               .name = "cpu.stat",
+               .flags = CFTYPE_NOT_ON_ROOT,
+               .seq_show = cpu_stat_show,
+       },
        { }     /* terminate */
 };
 
index 9cce79e8932075cf5999acf2caf63d25d80f0309..133b465691d6fe82462c33215639b6b7f97f04b7 100644 (file)
@@ -256,7 +256,7 @@ void __cgroup_account_cputime_field(struct cgroup *cgrp,
        cgroup_cpu_stat_account_end(cgrp, cstat);
 }
 
-void cgroup_stat_show_cputime(struct seq_file *seq, const char *prefix)
+void cgroup_stat_show_cputime(struct seq_file *seq)
 {
        struct cgroup *cgrp = seq_css(seq)->cgroup;
        u64 usage, utime, stime;
@@ -278,10 +278,10 @@ void cgroup_stat_show_cputime(struct seq_file *seq, const char *prefix)
        do_div(utime, NSEC_PER_USEC);
        do_div(stime, NSEC_PER_USEC);
 
-       seq_printf(seq, "%susage_usec %llu\n"
-                  "%suser_usec %llu\n"
-                  "%ssystem_usec %llu\n",
-                  prefix, usage, prefix, utime, prefix, stime);
+       seq_printf(seq, "usage_usec %llu\n"
+                  "user_usec %llu\n"
+                  "system_usec %llu\n",
+                  usage, utime, stime);
 }
 
 int cgroup_stat_init(struct cgroup *cgrp)
index ad255162a83015dbe783d32fd631b0b5551e408a..0b3eec389552e33de6c4ef9e046d5d5191711fac 100644 (file)
@@ -6678,13 +6678,12 @@ static struct cftype cpu_legacy_files[] = {
        { }     /* Terminate */
 };
 
-static int cpu_stat_show(struct seq_file *sf, void *v)
+static int cpu_extra_stat_show(struct seq_file *sf,
+                              struct cgroup_subsys_state *css)
 {
-       cgroup_stat_show_cputime(sf, "");
-
 #ifdef CONFIG_CFS_BANDWIDTH
        {
-               struct task_group *tg = css_tg(seq_css(sf));
+               struct task_group *tg = css_tg(css);
                struct cfs_bandwidth *cfs_b = &tg->cfs_bandwidth;
                u64 throttled_usec;
 
@@ -6817,11 +6816,6 @@ static ssize_t cpu_max_write(struct kernfs_open_file *of,
 #endif
 
 static struct cftype cpu_files[] = {
-       {
-               .name = "stat",
-               .flags = CFTYPE_NOT_ON_ROOT,
-               .seq_show = cpu_stat_show,
-       },
 #ifdef CONFIG_FAIR_GROUP_SCHED
        {
                .name = "weight",
@@ -6852,6 +6846,7 @@ struct cgroup_subsys cpu_cgrp_subsys = {
        .css_online     = cpu_cgroup_css_online,
        .css_released   = cpu_cgroup_css_released,
        .css_free       = cpu_cgroup_css_free,
+       .css_extra_stat_show = cpu_extra_stat_show,
        .fork           = cpu_cgroup_fork,
        .can_attach     = cpu_cgroup_can_attach,
        .attach         = cpu_cgroup_attach,