[Devel] [PATCH rh7 2/2] fairsched: add cpu.proc.loadavg to the cpu cgroup
Vladimir Davydov
vdavydov at parallels.com
Mon May 25 02:48:33 PDT 2015
This file mimics behavior of the system wide /proc/loadavg. It is going
to be a successor of the legacy VZCTL_GET_CPU_STAT ioctl.
Also, use it for showing /proc/loadavg inside a container, just like we
do in case of /proc/stat.
https://jira.sw.ru/browse/PSBM-32284
Signed-off-by: Vladimir Davydov <vdavydov at parallels.com>
---
fs/proc/loadavg.c | 22 +++++++++----------
include/linux/fairsched.h | 5 +++++
include/linux/sched.h | 7 ------
kernel/fairsched.c | 15 +++++++++++++
kernel/sched/core.c | 54 +++++++++++++++++++++++++++++------------------
5 files changed, 65 insertions(+), 38 deletions(-)
diff --git a/fs/proc/loadavg.c b/fs/proc/loadavg.c
index a9c0f558093d..4cbdeef1aa71 100644
--- a/fs/proc/loadavg.c
+++ b/fs/proc/loadavg.c
@@ -6,6 +6,8 @@
#include <linux/seq_file.h>
#include <linux/seqlock.h>
#include <linux/time.h>
+#include <linux/fairsched.h>
+#include <linux/ve.h>
#define LOAD_INT(x) ((x) >> FSHIFT)
#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
@@ -13,25 +15,23 @@
static int loadavg_proc_show(struct seq_file *m, void *v)
{
unsigned long avnrun[3];
- long running, threads;
struct ve_struct *ve;
ve = get_exec_env();
- if (ve_is_super(ve)) {
- get_avenrun(avnrun, FIXED_1/200, 0);
- running = nr_running();
- threads = nr_threads;
- } else {
- get_avenrun_ve(avnrun, FIXED_1/200, 0);
- running = nr_running_ve();
- threads = nr_threads_ve(ve);
+ if (!ve_is_super(ve)) {
+ int ret;
+ ret = fairsched_show_loadavg(ve_name(ve), m);
+ if (ret != -ENOSYS)
+ return ret;
}
- seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%ld %d\n",
+ get_avenrun(avnrun, FIXED_1/200, 0);
+
+ seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
- running, threads,
+ nr_running(), nr_threads,
task_active_pid_ns(current)->last_pid);
return 0;
}
diff --git a/include/linux/fairsched.h b/include/linux/fairsched.h
index 568c25abffbf..12bbc5bc7d5d 100644
--- a/include/linux/fairsched.h
+++ b/include/linux/fairsched.h
@@ -63,12 +63,17 @@ int cpu_cgroup_proc_stat(struct cgroup *cgrp, struct cftype *cft,
struct seq_file *p);
int fairsched_show_stat(const char *name, struct seq_file *p);
+int cpu_cgroup_proc_loadavg(struct cgroup *cgrp, struct cftype *cft,
+ struct seq_file *p);
+int fairsched_show_loadavg(const char *name, struct seq_file *p);
+
#else /* CONFIG_VZ_FAIRSCHED */
static inline int fairsched_new_node(int id, unsigned int vcpus) { return 0; }
static inline int fairsched_move_task(int id, struct task_struct *tsk) { return 0; }
static inline void fairsched_drop_node(int id, int leave) { }
static inline int fairsched_show_stat(const char *name, struct seq_file *p) { return -ENOSYS; }
+static inline int fairsched_show_loadavg(const char *name, struct seq_file *p) { return -ENOSYS; }
static inline int fairsched_get_cpu_avenrun(const char *name, unsigned long *avenrun) { return -ENOSYS; }
static inline int fairsched_get_cpu_stat(const char *name, struct kernel_cpustat *kstat) { return -ENOSYS; }
diff --git a/include/linux/sched.h b/include/linux/sched.h
index edca7b8c2a7b..2871013e89b9 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -117,13 +117,6 @@ extern unsigned long nr_active_cpu(void);
extern atomic_t nr_dead;
extern unsigned long nr_zombie;
-#ifdef CONFIG_VE
-extern unsigned long nr_running_ve(void);
-#else
-#define nr_running_ve() 0
-#endif
-
-
extern void calc_global_load(unsigned long ticks);
extern void update_cpu_load_nohz(void);
diff --git a/kernel/fairsched.c b/kernel/fairsched.c
index 7fe93d25cfd9..412afed6c77d 100644
--- a/kernel/fairsched.c
+++ b/kernel/fairsched.c
@@ -730,6 +730,21 @@ int fairsched_show_stat(const char *name, struct seq_file *p)
return err;
}
+int fairsched_show_loadavg(const char *name, struct seq_file *p)
+{
+ struct cgroup *cgrp;
+ int err;
+
+ cgrp = cgroup_kernel_open(root_node.cpu, 0, name);
+ if (IS_ERR_OR_NULL(cgrp))
+ return cgrp ? PTR_ERR(cgrp) : -ENOENT;
+
+ err = cpu_cgroup_proc_loadavg(cgrp, NULL, p);
+ cgroup_kernel_close(cgrp);
+
+ return err;
+}
+
int fairsched_get_cpu_avenrun(const char *name, unsigned long *avenrun)
{
struct cgroup *cgrp;
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index efc069edebae..c6a5ab063f6a 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -2350,26 +2350,6 @@ unsigned long nr_active_cpu(void)
return this->nr_active;
}
-#ifdef CONFIG_VE
-unsigned long nr_running_ve(void)
-{
- struct task_group *tg = task_group(current);
- unsigned long nr_running = 0;
- int i;
-
- for_each_possible_cpu(i) {
-#ifdef CONFIG_FAIR_GROUP_SCHED
- nr_running += tg->cfs_rq[i]->nr_running;
-#endif
-#ifdef CONFIG_RT_GROUP_SCHED
- nr_running += tg->rt_rq[i]->rt_nr_running;
-#endif
- }
-
- return nr_running;
-}
-#endif
-
/*
* Global load-average calculations
*
@@ -8814,6 +8794,36 @@ int cpu_cgroup_proc_stat(struct cgroup *cgrp, struct cftype *cft,
return 0;
}
+int cpu_cgroup_proc_loadavg(struct cgroup *cgrp, struct cftype *cft,
+ struct seq_file *p)
+{
+ struct task_group *tg = cgroup_tg(cgrp);
+ unsigned long avnrun[3];
+ int nr_running = 0;
+ int i;
+
+ avnrun[0] = tg->avenrun[0] + FIXED_1/200;
+ avnrun[1] = tg->avenrun[1] + FIXED_1/200;
+ avnrun[2] = tg->avenrun[2] + FIXED_1/200;
+
+ for_each_possible_cpu(i) {
+#ifdef CONFIG_FAIR_GROUP_SCHED
+ nr_running += tg->cfs_rq[i]->nr_running;
+#endif
+#ifdef CONFIG_RT_GROUP_SCHED
+ nr_running += tg->rt_rq[i]->rt_nr_running;
+#endif
+ }
+
+ seq_printf(p, "%lu.%02lu %lu.%02lu %lu.%02lu %d/%d %d\n",
+ LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
+ LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
+ LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
+ nr_running, cgroup_task_count(cgrp),
+ task_active_pid_ns(current)->last_pid);
+ return 0;
+}
+
void cpu_cgroup_get_stat(struct cgroup *cgrp, struct kernel_cpustat *kstat)
{
int i, j;
@@ -8935,6 +8945,10 @@ static struct cftype cpu_files[] = {
.read_seq_string = cpu_cgroup_proc_stat,
},
{
+ .name = "proc.loadavg",
+ .read_seq_string = cpu_cgroup_proc_loadavg,
+ },
+ {
.name = "delayacct.total",
.read_map = cpu_cgroup_delay_show,
},
--
2.1.4
More information about the Devel
mailing list