diff options
-rw-r--r-- | Documentation/controllers/cpuacct.txt | 32 | ||||
-rw-r--r-- | kernel/sched.c | 12 |
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 @@ | |||
1 | CPU Accounting Controller | ||
2 | ------------------------- | ||
3 | |||
4 | The CPU accounting controller is used to group tasks using cgroups and | ||
5 | account the CPU usage of these groups of tasks. | ||
6 | |||
7 | The CPU accounting controller supports multi-hierarchy groups. An accounting | ||
8 | group accumulates the CPU usage of all of its child groups and the tasks | ||
9 | directly present in its group. | ||
10 | |||
11 | Accounting groups can be created by first mounting the cgroup filesystem. | ||
12 | |||
13 | # mkdir /cgroups | ||
14 | # mount -t cgroup -ocpuacct none /cgroups | ||
15 | |||
16 | With the above step, the initial or the parent accounting group | ||
17 | becomes visible at /cgroups. At bootup, this group includes all the | ||
18 | tasks in the system. /cgroups/tasks lists the tasks in this cgroup. | ||
19 | /cgroups/cpuacct.usage gives the CPU time (in nanoseconds) obtained by | ||
20 | this group which is essentially the CPU time obtained by all the tasks | ||
21 | in the system. | ||
22 | |||
23 | New accounting groups can be created under the parent group /cgroups. | ||
24 | |||
25 | # cd /cgroups | ||
26 | # mkdir g1 | ||
27 | # echo $$ > g1 | ||
28 | |||
29 | The above steps create a new group g1 and move the current shell | ||
30 | process (bash) into it. CPU time consumed by this bash and its children | ||
31 | can 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 */ |
9200 | struct cpuacct { | 9200 | struct 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 | ||
9206 | struct cgroup_subsys cpuacct_subsys; | 9207 | struct 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) | |||
9313 | static void cpuacct_charge(struct task_struct *tsk, u64 cputime) | 9317 | static 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 | } |