[Devel] [PATCH rh7 2/3] sched: use cpuacct->cpustat for showing cpu stats

Vladimir Davydov vdavydov at parallels.com
Fri May 29 10:02:27 PDT 2015


In contrast to RH6, where tg->cpustat was used, now cpu stats are
accounted in the cpuacct cgroup. So zap tg->cpustat and use
cpuacct->cpustat for showing cpu.proc.stat instead. Fortunately cpu and
cpuacct cgroups are always mounted together (even by systemd by
default), so this will work.

Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
 kernel/sched/core.c    | 22 ++++++++--------------
 kernel/sched/cpuacct.c |  5 +++++
 kernel/sched/cpuacct.h |  1 +
 kernel/sched/sched.h   |  1 -
 4 files changed, 14 insertions(+), 15 deletions(-)

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 50273af3ea34..d562f6430c67 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -7394,7 +7394,6 @@ void __init sched_init(void)
 #endif /* CONFIG_CPUMASK_OFFSTACK */
 	}
 
-	root_task_group.cpustat = alloc_percpu(struct kernel_cpustat);
 	root_task_group.taskstats = alloc_percpu(struct taskstats);
 
 #ifdef CONFIG_SMP
@@ -7695,7 +7694,6 @@ static void free_sched_group(struct task_group *tg)
 	free_fair_sched_group(tg);
 	free_rt_sched_group(tg);
 	autogroup_free(tg);
-	free_percpu(tg->cpustat);
 	free_percpu(tg->taskstats);
 	kfree(tg);
 }
@@ -7715,10 +7713,6 @@ struct task_group *sched_create_group(struct task_group *parent)
 	if (!alloc_rt_sched_group(tg, parent))
 		goto err;
 
-	tg->cpustat = alloc_percpu(struct kernel_cpustat);
-	if (!tg->cpustat)
-		goto err;
-
 	tg->taskstats = alloc_percpu(struct taskstats);
 	if (!tg->taskstats)
 		goto err;
@@ -8680,11 +8674,12 @@ static u64 cpu_cgroup_usage_cpu(struct task_group *tg, int i)
 #endif
 }
 
-static void cpu_cgroup_update_stat(struct task_group *tg, int i)
+static void cpu_cgroup_update_stat(struct cgroup *cgrp, int i)
 {
 #if defined(CONFIG_SCHEDSTATS) && defined(CONFIG_FAIR_GROUP_SCHED)
+	struct task_group *tg = cgroup_tg(cgrp);
 	struct sched_entity *se = tg->se[i];
-	struct kernel_cpustat *kcpustat = per_cpu_ptr(tg->cpustat, i);
+	struct kernel_cpustat *kcpustat = cpuacct_cpustat(cgrp, i);
 	u64 now = cpu_clock(i);
 	u64 delta, idle, iowait;
 
@@ -8745,9 +8740,9 @@ int cpu_cgroup_proc_stat(struct cgroup *cgrp, struct cftype *cft,
 	user = nice = system = idle = iowait = steal = 0;
 
 	for_each_possible_cpu(i) {
-		kcpustat = per_cpu_ptr(tg->cpustat, i);
+		kcpustat = cpuacct_cpustat(cgrp, i);
 
-		cpu_cgroup_update_stat(tg, i);
+		cpu_cgroup_update_stat(cgrp, i);
 
 		user += kcpustat->cpustat[CPUTIME_USER];
 		nice += kcpustat->cpustat[CPUTIME_NICE];
@@ -8781,7 +8776,7 @@ int cpu_cgroup_proc_stat(struct cgroup *cgrp, struct cftype *cft,
 		for_each_online_cpu(j) {
 			if (j % nr_ve_vcpus != i)
 				continue;
-			kcpustat = per_cpu_ptr(tg->cpustat, j);
+			kcpustat = cpuacct_cpustat(cgrp, j);
 
 			user += kcpustat->cpustat[CPUTIME_USER];
 			nice += kcpustat->cpustat[CPUTIME_NICE];
@@ -8850,14 +8845,13 @@ int cpu_cgroup_proc_loadavg(struct cgroup *cgrp, struct cftype *cft,
 void cpu_cgroup_get_stat(struct cgroup *cgrp, struct kernel_cpustat *kstat)
 {
 	int i, j;
-	struct task_group *tg = cgroup_tg(cgrp);
 
 	memset(kstat, 0, sizeof(struct kernel_cpustat));
 
 	for_each_possible_cpu(i) {
-		struct kernel_cpustat *st = per_cpu_ptr(tg->cpustat, i);
+		struct kernel_cpustat *st = cpuacct_cpustat(cgrp, i);
 
-		cpu_cgroup_update_stat(tg, i);
+		cpu_cgroup_update_stat(cgrp, i);
 
 		for (j = 0; j < NR_STATS; j++)
 			kstat->cpustat[j] += st->cpustat[j];
diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c
index dbb7e2cd95eb..b33f7c8438ea 100644
--- a/kernel/sched/cpuacct.c
+++ b/kernel/sched/cpuacct.c
@@ -286,6 +286,11 @@ void cpuacct_account_field(struct task_struct *p, int index, u64 val)
 	rcu_read_unlock();
 }
 
+struct kernel_cpustat *cpuacct_cpustat(struct cgroup *cgrp, int cpu)
+{
+	return per_cpu_ptr(cgroup_ca(cgrp)->cpustat, cpu);
+}
+
 struct cgroup_subsys cpuacct_subsys = {
 	.name		= "cpuacct",
 	.css_alloc	= cpuacct_css_alloc,
diff --git a/kernel/sched/cpuacct.h b/kernel/sched/cpuacct.h
index ed605624a5e7..cf129eae1003 100644
--- a/kernel/sched/cpuacct.h
+++ b/kernel/sched/cpuacct.h
@@ -2,6 +2,7 @@
 
 extern void cpuacct_charge(struct task_struct *tsk, u64 cputime);
 extern void cpuacct_account_field(struct task_struct *p, int index, u64 val);
+extern struct kernel_cpustat *cpuacct_cpustat(struct cgroup *cgrp, int cpu);
 
 #else
 
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index e0c03d8bf910..e4f92a552d75 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -167,7 +167,6 @@ struct task_group {
 	struct autogroup *autogroup;
 #endif
 
-	struct kernel_cpustat __percpu *cpustat;
 	struct taskstats __percpu *taskstats;
 	unsigned long avenrun[3];	/* loadavg data */
 	struct timespec start_time;
-- 
2.1.4




More information about the Devel mailing list