Merge tag 'renesas-pinctrl-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / kernel / sched / cpuacct.c
index 071ae8d..dbb7e2c 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/seq_file.h>
 #include <linux/rcupdate.h>
 #include <linux/kernel_stat.h>
+#include <linux/err.h>
 
 #include "sched.h"
 
  * (balbir@in.ibm.com).
  */
 
-struct cpuacct root_cpuacct;
+/* Time spent by the tasks of the cpu accounting group executing in ... */
+enum cpuacct_stat_index {
+       CPUACCT_STAT_USER,      /* ... user mode */
+       CPUACCT_STAT_SYSTEM,    /* ... kernel mode */
+
+       CPUACCT_STAT_NSTATS,
+};
+
+/* track cpu usage of a group of tasks and its child groups */
+struct cpuacct {
+       struct cgroup_subsys_state css;
+       /* cpuusage holds pointer to a u64-type object on every cpu */
+       u64 __percpu *cpuusage;
+       struct kernel_cpustat __percpu *cpustat;
+};
+
+/* return cpu accounting group corresponding to this container */
+static inline struct cpuacct *cgroup_ca(struct cgroup *cgrp)
+{
+       return container_of(cgroup_subsys_state(cgrp, cpuacct_subsys_id),
+                           struct cpuacct, css);
+}
+
+/* return cpu accounting group to which this task belongs */
+static inline struct cpuacct *task_ca(struct task_struct *tsk)
+{
+       return container_of(task_subsys_state(tsk, cpuacct_subsys_id),
+                           struct cpuacct, css);
+}
+
+static inline struct cpuacct *__parent_ca(struct cpuacct *ca)
+{
+       return cgroup_ca(ca->css.cgroup->parent);
+}
+
+static inline struct cpuacct *parent_ca(struct cpuacct *ca)
+{
+       if (!ca->css.cgroup->parent)
+               return NULL;
+       return cgroup_ca(ca->css.cgroup->parent);
+}
+
+static DEFINE_PER_CPU(u64, root_cpuacct_cpuusage);
+static struct cpuacct root_cpuacct = {
+       .cpustat        = &kernel_cpustat,
+       .cpuusage       = &root_cpuacct_cpuusage,
+};
 
 /* create a new cpu accounting group */
 static struct cgroup_subsys_state *cpuacct_css_alloc(struct cgroup *cgrp)
@@ -201,9 +248,6 @@ void cpuacct_charge(struct task_struct *tsk, u64 cputime)
        struct cpuacct *ca;
        int cpu;
 
-       if (unlikely(!cpuacct_subsys.active))
-               return;
-
        cpu = task_cpu(tsk);
 
        rcu_read_lock();
@@ -232,9 +276,6 @@ void cpuacct_account_field(struct task_struct *p, int index, u64 val)
        struct kernel_cpustat *kcpustat;
        struct cpuacct *ca;
 
-       if (unlikely(!cpuacct_subsys.active))
-               return;
-
        rcu_read_lock();
        ca = task_ca(p);
        while (ca != &root_cpuacct) {
@@ -245,17 +286,11 @@ void cpuacct_account_field(struct task_struct *p, int index, u64 val)
        rcu_read_unlock();
 }
 
-void __init cpuacct_init(void)
-{
-       root_cpuacct.cpustat = &kernel_cpustat;
-       root_cpuacct.cpuusage = alloc_percpu(u64);
-       BUG_ON(!root_cpuacct.cpuusage); /* Too early, not expected to fail */
-}
-
 struct cgroup_subsys cpuacct_subsys = {
-       .name = "cpuacct",
-       .css_alloc = cpuacct_css_alloc,
-       .css_free = cpuacct_css_free,
-       .subsys_id = cpuacct_subsys_id,
-       .base_cftypes = files,
+       .name           = "cpuacct",
+       .css_alloc      = cpuacct_css_alloc,
+       .css_free       = cpuacct_css_free,
+       .subsys_id      = cpuacct_subsys_id,
+       .base_cftypes   = files,
+       .early_init     = 1,
 };