aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/controllers/cpuacct.txt32
-rw-r--r--kernel/sched.c12
2 files changed, 41 insertions, 3 deletions
diff --git a/Documentation/controllers/cpuacct.txt b/Documentation/controllers/cpuacct.txt
new file mode 100644
index 000000000000..bb775fbe43d7
--- /dev/null
+++ b/Documentation/controllers/cpuacct.txt
@@ -0,0 +1,32 @@
1CPU Accounting Controller
2-------------------------
3
4The CPU accounting controller is used to group tasks using cgroups and
5account the CPU usage of these groups of tasks.
6
7The CPU accounting controller supports multi-hierarchy groups. An accounting
8group accumulates the CPU usage of all of its child groups and the tasks
9directly present in its group.
10
11Accounting groups can be created by first mounting the cgroup filesystem.
12
13# mkdir /cgroups
14# mount -t cgroup -ocpuacct none /cgroups
15
16With the above step, the initial or the parent accounting group
17becomes visible at /cgroups. At bootup, this group includes all the
18tasks in the system. /cgroups/tasks lists the tasks in this cgroup.
19/cgroups/cpuacct.usage gives the CPU time (in nanoseconds) obtained by
20this group which is essentially the CPU time obtained by all the tasks
21in the system.
22
23New accounting groups can be created under the parent group /cgroups.
24
25# cd /cgroups
26# mkdir g1
27# echo $$ > g1
28
29The above steps create a new group g1 and move the current shell
30process (bash) into it. CPU time consumed by this bash and its children
31can be obtained from g1/cpuacct.usage and the same is accumulated in
32/cgroups/cpuacct.usage also.
diff --git a/kernel/sched.c b/kernel/sched.c
index 59db86c915f9..ebaf432365f6 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -9196,11 +9196,12 @@ struct cgroup_subsys cpu_cgroup_subsys = {
9196 * (balbir@in.ibm.com). 9196 * (balbir@in.ibm.com).
9197 */ 9197 */
9198 9198
9199/* track cpu usage of a group of tasks */ 9199/* track cpu usage of a group of tasks and its child groups */
9200struct cpuacct { 9200struct cpuacct {
9201 struct cgroup_subsys_state css; 9201 struct cgroup_subsys_state css;
9202 /* cpuusage holds pointer to a u64-type object on every cpu */ 9202 /* cpuusage holds pointer to a u64-type object on every cpu */
9203 u64 *cpuusage; 9203 u64 *cpuusage;
9204 struct cpuacct *parent;
9204}; 9205};
9205 9206
9206struct cgroup_subsys cpuacct_subsys; 9207struct cgroup_subsys cpuacct_subsys;
@@ -9234,6 +9235,9 @@ static struct cgroup_subsys_state *cpuacct_create(
9234 return ERR_PTR(-ENOMEM); 9235 return ERR_PTR(-ENOMEM);
9235 } 9236 }
9236 9237
9238 if (cgrp->parent)
9239 ca->parent = cgroup_ca(cgrp->parent);
9240
9237 return &ca->css; 9241 return &ca->css;
9238} 9242}
9239 9243
@@ -9313,14 +9317,16 @@ static int cpuacct_populate(struct cgroup_subsys *ss, struct cgroup *cgrp)
9313static void cpuacct_charge(struct task_struct *tsk, u64 cputime) 9317static void cpuacct_charge(struct task_struct *tsk, u64 cputime)
9314{ 9318{
9315 struct cpuacct *ca; 9319 struct cpuacct *ca;
9320 int cpu;
9316 9321
9317 if (!cpuacct_subsys.active) 9322 if (!cpuacct_subsys.active)
9318 return; 9323 return;
9319 9324
9325 cpu = task_cpu(tsk);
9320 ca = task_ca(tsk); 9326 ca = task_ca(tsk);
9321 if (ca) {
9322 u64 *cpuusage = percpu_ptr(ca->cpuusage, task_cpu(tsk));
9323 9327
9328 for (; ca; ca = ca->parent) {
9329 u64 *cpuusage = percpu_ptr(ca->cpuusage, cpu);
9324 *cpuusage += cputime; 9330 *cpuusage += cputime;
9325 } 9331 }
9326} 9332}