aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--kernel/sched_debug.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 1dfae3d014b5..4d36f3726da7 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -16,6 +16,8 @@
16#include <linux/kallsyms.h> 16#include <linux/kallsyms.h>
17#include <linux/utsname.h> 17#include <linux/utsname.h>
18 18
19static DEFINE_SPINLOCK(sched_debug_lock);
20
19/* 21/*
20 * This allows printing both to /proc/sched_debug and 22 * This allows printing both to /proc/sched_debug and
21 * to the console 23 * to the console
@@ -86,6 +88,23 @@ static void print_cfs_group_stats(struct seq_file *m, int cpu, struct task_group
86} 88}
87#endif 89#endif
88 90
91#ifdef CONFIG_CGROUP_SCHED
92static char group_path[PATH_MAX];
93
94static char *task_group_path(struct task_group *tg)
95{
96 /*
97 * May be NULL if the underlying cgroup isn't fully-created yet
98 */
99 if (!tg->css.cgroup) {
100 group_path[0] = '\0';
101 return group_path;
102 }
103 cgroup_path(tg->css.cgroup, group_path, PATH_MAX);
104 return group_path;
105}
106#endif
107
89static void 108static void
90print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) 109print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
91{ 110{
@@ -108,6 +127,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p)
108 SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld", 127 SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld",
109 0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L); 128 0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L);
110#endif 129#endif
130#ifdef CONFIG_CGROUP_SCHED
131 SEQ_printf(m, " %s", task_group_path(task_group(p)));
132#endif
111 133
112 SEQ_printf(m, "\n"); 134 SEQ_printf(m, "\n");
113} 135}
@@ -144,7 +166,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
144 struct sched_entity *last; 166 struct sched_entity *last;
145 unsigned long flags; 167 unsigned long flags;
146 168
169#ifdef CONFIG_FAIR_GROUP_SCHED
170 SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, task_group_path(cfs_rq->tg));
171#else
147 SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu); 172 SEQ_printf(m, "\ncfs_rq[%d]:\n", cpu);
173#endif
148 SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "exec_clock", 174 SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "exec_clock",
149 SPLIT_NS(cfs_rq->exec_clock)); 175 SPLIT_NS(cfs_rq->exec_clock));
150 176
@@ -191,7 +217,11 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
191 217
192void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq) 218void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
193{ 219{
220#ifdef CONFIG_RT_GROUP_SCHED
221 SEQ_printf(m, "\nrt_rq[%d]:%s\n", cpu, task_group_path(rt_rq->tg));
222#else
194 SEQ_printf(m, "\nrt_rq[%d]:\n", cpu); 223 SEQ_printf(m, "\nrt_rq[%d]:\n", cpu);
224#endif
195 225
196#define P(x) \ 226#define P(x) \
197 SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(rt_rq->x)) 227 SEQ_printf(m, " .%-30s: %Ld\n", #x, (long long)(rt_rq->x))
@@ -212,6 +242,7 @@ extern __read_mostly int sched_clock_running;
212static void print_cpu(struct seq_file *m, int cpu) 242static void print_cpu(struct seq_file *m, int cpu)
213{ 243{
214 struct rq *rq = cpu_rq(cpu); 244 struct rq *rq = cpu_rq(cpu);
245 unsigned long flags;
215 246
216#ifdef CONFIG_X86 247#ifdef CONFIG_X86
217 { 248 {
@@ -266,10 +297,14 @@ static void print_cpu(struct seq_file *m, int cpu)
266 297
267#undef P 298#undef P
268#endif 299#endif
300 spin_lock_irqsave(&sched_debug_lock, flags);
269 print_cfs_stats(m, cpu); 301 print_cfs_stats(m, cpu);
270 print_rt_stats(m, cpu); 302 print_rt_stats(m, cpu);
271 303
304 rcu_read_lock();
272 print_rq(m, rq, cpu); 305 print_rq(m, rq, cpu);
306 rcu_read_unlock();
307 spin_unlock_irqrestore(&sched_debug_lock, flags);
273} 308}
274 309
275static const char *sched_tunable_scaling_names[] = { 310static const char *sched_tunable_scaling_names[] = {