aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched/debug.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 22:42:08 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-26 22:42:08 -0500
commitdcad0fceae528e8007610308bad7e5a3370e5c39 (patch)
tree1af69697e0988e8dbdf42d915508bd58a1887b4f /kernel/sched/debug.c
parentf8ef15d6b9d8e38729cd740a43919adf88468119 (diff)
parent7f6575f1fb963d5231afbceecd3feadb6ab58cd3 (diff)
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler fixes from Ingo Molnar. * 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: cputime: Use local_clock() for full dynticks cputime accounting cputime: Constify timeval_to_cputime(timeval) argument sched: Move RR_TIMESLICE from sysctl.h to rt.h sched: Fix /proc/sched_debug failure on very very large systems sched: Fix /proc/sched_stat failure on very very large systems sched/core: Remove the obsolete and unused nr_uninterruptible() function
Diffstat (limited to 'kernel/sched/debug.c')
-rw-r--r--kernel/sched/debug.c90
1 files changed, 79 insertions, 11 deletions
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c
index 557e7b53b323..75024a673520 100644
--- a/kernel/sched/debug.c
+++ b/kernel/sched/debug.c
@@ -262,11 +262,11 @@ static void print_cpu(struct seq_file *m, int cpu)
262 { 262 {
263 unsigned int freq = cpu_khz ? : 1; 263 unsigned int freq = cpu_khz ? : 1;
264 264
265 SEQ_printf(m, "\ncpu#%d, %u.%03u MHz\n", 265 SEQ_printf(m, "cpu#%d, %u.%03u MHz\n",
266 cpu, freq / 1000, (freq % 1000)); 266 cpu, freq / 1000, (freq % 1000));
267 } 267 }
268#else 268#else
269 SEQ_printf(m, "\ncpu#%d\n", cpu); 269 SEQ_printf(m, "cpu#%d\n", cpu);
270#endif 270#endif
271 271
272#define P(x) \ 272#define P(x) \
@@ -323,6 +323,7 @@ do { \
323 print_rq(m, rq, cpu); 323 print_rq(m, rq, cpu);
324 rcu_read_unlock(); 324 rcu_read_unlock();
325 spin_unlock_irqrestore(&sched_debug_lock, flags); 325 spin_unlock_irqrestore(&sched_debug_lock, flags);
326 SEQ_printf(m, "\n");
326} 327}
327 328
328static const char *sched_tunable_scaling_names[] = { 329static const char *sched_tunable_scaling_names[] = {
@@ -331,11 +332,10 @@ static const char *sched_tunable_scaling_names[] = {
331 "linear" 332 "linear"
332}; 333};
333 334
334static int sched_debug_show(struct seq_file *m, void *v) 335static void sched_debug_header(struct seq_file *m)
335{ 336{
336 u64 ktime, sched_clk, cpu_clk; 337 u64 ktime, sched_clk, cpu_clk;
337 unsigned long flags; 338 unsigned long flags;
338 int cpu;
339 339
340 local_irq_save(flags); 340 local_irq_save(flags);
341 ktime = ktime_to_ns(ktime_get()); 341 ktime = ktime_to_ns(ktime_get());
@@ -377,33 +377,101 @@ static int sched_debug_show(struct seq_file *m, void *v)
377#undef PN 377#undef PN
378#undef P 378#undef P
379 379
380 SEQ_printf(m, " .%-40s: %d (%s)\n", "sysctl_sched_tunable_scaling", 380 SEQ_printf(m, " .%-40s: %d (%s)\n",
381 "sysctl_sched_tunable_scaling",
381 sysctl_sched_tunable_scaling, 382 sysctl_sched_tunable_scaling,
382 sched_tunable_scaling_names[sysctl_sched_tunable_scaling]); 383 sched_tunable_scaling_names[sysctl_sched_tunable_scaling]);
384 SEQ_printf(m, "\n");
385}
383 386
384 for_each_online_cpu(cpu) 387static int sched_debug_show(struct seq_file *m, void *v)
385 print_cpu(m, cpu); 388{
389 int cpu = (unsigned long)(v - 2);
386 390
387 SEQ_printf(m, "\n"); 391 if (cpu != -1)
392 print_cpu(m, cpu);
393 else
394 sched_debug_header(m);
388 395
389 return 0; 396 return 0;
390} 397}
391 398
392void sysrq_sched_debug_show(void) 399void sysrq_sched_debug_show(void)
393{ 400{
394 sched_debug_show(NULL, NULL); 401 int cpu;
402
403 sched_debug_header(NULL);
404 for_each_online_cpu(cpu)
405 print_cpu(NULL, cpu);
406
407}
408
409/*
410 * This itererator needs some explanation.
411 * It returns 1 for the header position.
412 * This means 2 is cpu 0.
413 * In a hotplugged system some cpus, including cpu 0, may be missing so we have
414 * to use cpumask_* to iterate over the cpus.
415 */
416static void *sched_debug_start(struct seq_file *file, loff_t *offset)
417{
418 unsigned long n = *offset;
419
420 if (n == 0)
421 return (void *) 1;
422
423 n--;
424
425 if (n > 0)
426 n = cpumask_next(n - 1, cpu_online_mask);
427 else
428 n = cpumask_first(cpu_online_mask);
429
430 *offset = n + 1;
431
432 if (n < nr_cpu_ids)
433 return (void *)(unsigned long)(n + 2);
434 return NULL;
435}
436
437static void *sched_debug_next(struct seq_file *file, void *data, loff_t *offset)
438{
439 (*offset)++;
440 return sched_debug_start(file, offset);
441}
442
443static void sched_debug_stop(struct seq_file *file, void *data)
444{
445}
446
447static const struct seq_operations sched_debug_sops = {
448 .start = sched_debug_start,
449 .next = sched_debug_next,
450 .stop = sched_debug_stop,
451 .show = sched_debug_show,
452};
453
454static int sched_debug_release(struct inode *inode, struct file *file)
455{
456 seq_release(inode, file);
457
458 return 0;
395} 459}
396 460
397static int sched_debug_open(struct inode *inode, struct file *filp) 461static int sched_debug_open(struct inode *inode, struct file *filp)
398{ 462{
399 return single_open(filp, sched_debug_show, NULL); 463 int ret = 0;
464
465 ret = seq_open(filp, &sched_debug_sops);
466
467 return ret;
400} 468}
401 469
402static const struct file_operations sched_debug_fops = { 470static const struct file_operations sched_debug_fops = {
403 .open = sched_debug_open, 471 .open = sched_debug_open,
404 .read = seq_read, 472 .read = seq_read,
405 .llseek = seq_lseek, 473 .llseek = seq_lseek,
406 .release = single_release, 474 .release = sched_debug_release,
407}; 475};
408 476
409static int __init init_sched_debug_procfs(void) 477static int __init init_sched_debug_procfs(void)