[Devel] [PATCH RHEL7 COMMIT] sched: use cpuacct->cpustat for showing cpu stats
Konstantin Khorenko
khorenko at virtuozzo.com
Thu Jun 4 05:58:45 PDT 2015
The commit is pushed to "branch-rh7-3.10.0-123.1.2-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-123.1.2.vz7.5.9
------>
commit 642aed8e5e5e730e7863cc4c3eb3f1e591dc94e6
Author: Vladimir Davydov <vdavydov at parallels.com>
Date: Thu Jun 4 16:58:45 2015 +0400
sched: use cpuacct->cpustat for showing cpu stats
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.
Related to https://jira.sw.ru/browse/PSBM-33642
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 50273af..d562f64 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 dbb7e2c..b33f7c8 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 ed60562..cf129ea 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 e0c03d8..e4f92a5 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;
More information about the Devel
mailing list