diff options
author | Ingo Molnar <mingo@kernel.org> | 2013-10-07 06:29:30 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2013-10-09 08:48:04 -0400 |
commit | b32e86b4301e345611f0446265f782a229faadf6 (patch) | |
tree | 8cc0a8b731e63f2b3450f89330d49009374c99fb | |
parent | 7dbd13ed06513b047216a7ffc718bad9df0660f1 (diff) |
sched/numa: Add debugging
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Rik van Riel <riel@redhat.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Mel Gorman <mgorman@suse.de>
Cc: Srikar Dronamraju <srikar@linux.vnet.ibm.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Signed-off-by: Peter Zijlstra <peterz@infradead.org>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Link: http://lkml.kernel.org/r/1381141781-10992-53-git-send-email-mgorman@suse.de
-rw-r--r-- | include/linux/sched.h | 6 | ||||
-rw-r--r-- | kernel/sched/debug.c | 60 | ||||
-rw-r--r-- | kernel/sched/fair.c | 5 |
3 files changed, 68 insertions, 3 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index f6385107c352..1127a46ac3d2 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1366,6 +1366,7 @@ struct task_struct { | |||
1366 | unsigned long *numa_faults_buffer; | 1366 | unsigned long *numa_faults_buffer; |
1367 | 1367 | ||
1368 | int numa_preferred_nid; | 1368 | int numa_preferred_nid; |
1369 | unsigned long numa_pages_migrated; | ||
1369 | #endif /* CONFIG_NUMA_BALANCING */ | 1370 | #endif /* CONFIG_NUMA_BALANCING */ |
1370 | 1371 | ||
1371 | struct rcu_head rcu; | 1372 | struct rcu_head rcu; |
@@ -2661,6 +2662,11 @@ static inline unsigned int task_cpu(const struct task_struct *p) | |||
2661 | return task_thread_info(p)->cpu; | 2662 | return task_thread_info(p)->cpu; |
2662 | } | 2663 | } |
2663 | 2664 | ||
2665 | static inline int task_node(const struct task_struct *p) | ||
2666 | { | ||
2667 | return cpu_to_node(task_cpu(p)); | ||
2668 | } | ||
2669 | |||
2664 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); | 2670 | extern void set_task_cpu(struct task_struct *p, unsigned int cpu); |
2665 | 2671 | ||
2666 | #else | 2672 | #else |
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 196559994f7c..e6ba5e31c7ca 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
16 | #include <linux/kallsyms.h> | 16 | #include <linux/kallsyms.h> |
17 | #include <linux/utsname.h> | 17 | #include <linux/utsname.h> |
18 | #include <linux/mempolicy.h> | ||
18 | 19 | ||
19 | #include "sched.h" | 20 | #include "sched.h" |
20 | 21 | ||
@@ -137,6 +138,9 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) | |||
137 | SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld", | 138 | SEQ_printf(m, "%15Ld %15Ld %15Ld.%06ld %15Ld.%06ld %15Ld.%06ld", |
138 | 0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L); | 139 | 0LL, 0LL, 0LL, 0L, 0LL, 0L, 0LL, 0L); |
139 | #endif | 140 | #endif |
141 | #ifdef CONFIG_NUMA_BALANCING | ||
142 | SEQ_printf(m, " %d", cpu_to_node(task_cpu(p))); | ||
143 | #endif | ||
140 | #ifdef CONFIG_CGROUP_SCHED | 144 | #ifdef CONFIG_CGROUP_SCHED |
141 | SEQ_printf(m, " %s", task_group_path(task_group(p))); | 145 | SEQ_printf(m, " %s", task_group_path(task_group(p))); |
142 | #endif | 146 | #endif |
@@ -159,7 +163,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu) | |||
159 | read_lock_irqsave(&tasklist_lock, flags); | 163 | read_lock_irqsave(&tasklist_lock, flags); |
160 | 164 | ||
161 | do_each_thread(g, p) { | 165 | do_each_thread(g, p) { |
162 | if (!p->on_rq || task_cpu(p) != rq_cpu) | 166 | if (task_cpu(p) != rq_cpu) |
163 | continue; | 167 | continue; |
164 | 168 | ||
165 | print_task(m, rq, p); | 169 | print_task(m, rq, p); |
@@ -345,7 +349,7 @@ static void sched_debug_header(struct seq_file *m) | |||
345 | cpu_clk = local_clock(); | 349 | cpu_clk = local_clock(); |
346 | local_irq_restore(flags); | 350 | local_irq_restore(flags); |
347 | 351 | ||
348 | SEQ_printf(m, "Sched Debug Version: v0.10, %s %.*s\n", | 352 | SEQ_printf(m, "Sched Debug Version: v0.11, %s %.*s\n", |
349 | init_utsname()->release, | 353 | init_utsname()->release, |
350 | (int)strcspn(init_utsname()->version, " "), | 354 | (int)strcspn(init_utsname()->version, " "), |
351 | init_utsname()->version); | 355 | init_utsname()->version); |
@@ -488,6 +492,56 @@ static int __init init_sched_debug_procfs(void) | |||
488 | 492 | ||
489 | __initcall(init_sched_debug_procfs); | 493 | __initcall(init_sched_debug_procfs); |
490 | 494 | ||
495 | #define __P(F) \ | ||
496 | SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)F) | ||
497 | #define P(F) \ | ||
498 | SEQ_printf(m, "%-45s:%21Ld\n", #F, (long long)p->F) | ||
499 | #define __PN(F) \ | ||
500 | SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)F)) | ||
501 | #define PN(F) \ | ||
502 | SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)p->F)) | ||
503 | |||
504 | |||
505 | static void sched_show_numa(struct task_struct *p, struct seq_file *m) | ||
506 | { | ||
507 | #ifdef CONFIG_NUMA_BALANCING | ||
508 | struct mempolicy *pol; | ||
509 | int node, i; | ||
510 | |||
511 | if (p->mm) | ||
512 | P(mm->numa_scan_seq); | ||
513 | |||
514 | task_lock(p); | ||
515 | pol = p->mempolicy; | ||
516 | if (pol && !(pol->flags & MPOL_F_MORON)) | ||
517 | pol = NULL; | ||
518 | mpol_get(pol); | ||
519 | task_unlock(p); | ||
520 | |||
521 | SEQ_printf(m, "numa_migrations, %ld\n", xchg(&p->numa_pages_migrated, 0)); | ||
522 | |||
523 | for_each_online_node(node) { | ||
524 | for (i = 0; i < 2; i++) { | ||
525 | unsigned long nr_faults = -1; | ||
526 | int cpu_current, home_node; | ||
527 | |||
528 | if (p->numa_faults) | ||
529 | nr_faults = p->numa_faults[2*node + i]; | ||
530 | |||
531 | cpu_current = !i ? (task_node(p) == node) : | ||
532 | (pol && node_isset(node, pol->v.nodes)); | ||
533 | |||
534 | home_node = (p->numa_preferred_nid == node); | ||
535 | |||
536 | SEQ_printf(m, "numa_faults, %d, %d, %d, %d, %ld\n", | ||
537 | i, node, cpu_current, home_node, nr_faults); | ||
538 | } | ||
539 | } | ||
540 | |||
541 | mpol_put(pol); | ||
542 | #endif | ||
543 | } | ||
544 | |||
491 | void proc_sched_show_task(struct task_struct *p, struct seq_file *m) | 545 | void proc_sched_show_task(struct task_struct *p, struct seq_file *m) |
492 | { | 546 | { |
493 | unsigned long nr_switches; | 547 | unsigned long nr_switches; |
@@ -591,6 +645,8 @@ void proc_sched_show_task(struct task_struct *p, struct seq_file *m) | |||
591 | SEQ_printf(m, "%-45s:%21Ld\n", | 645 | SEQ_printf(m, "%-45s:%21Ld\n", |
592 | "clock-delta", (long long)(t1-t0)); | 646 | "clock-delta", (long long)(t1-t0)); |
593 | } | 647 | } |
648 | |||
649 | sched_show_numa(p, m); | ||
594 | } | 650 | } |
595 | 651 | ||
596 | void proc_sched_set_task(struct task_struct *p) | 652 | void proc_sched_set_task(struct task_struct *p) |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 147349987bfe..2876a37cdfc4 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -1137,7 +1137,7 @@ static int task_numa_migrate(struct task_struct *p) | |||
1137 | .p = p, | 1137 | .p = p, |
1138 | 1138 | ||
1139 | .src_cpu = task_cpu(p), | 1139 | .src_cpu = task_cpu(p), |
1140 | .src_nid = cpu_to_node(task_cpu(p)), | 1140 | .src_nid = task_node(p), |
1141 | 1141 | ||
1142 | .imbalance_pct = 112, | 1142 | .imbalance_pct = 112, |
1143 | 1143 | ||
@@ -1515,6 +1515,9 @@ void task_numa_fault(int last_cpupid, int node, int pages, int flags) | |||
1515 | if (p->numa_migrate_retry && time_after(jiffies, p->numa_migrate_retry)) | 1515 | if (p->numa_migrate_retry && time_after(jiffies, p->numa_migrate_retry)) |
1516 | numa_migrate_preferred(p); | 1516 | numa_migrate_preferred(p); |
1517 | 1517 | ||
1518 | if (migrated) | ||
1519 | p->numa_pages_migrated += pages; | ||
1520 | |||
1518 | p->numa_faults_buffer[task_faults_idx(node, priv)] += pages; | 1521 | p->numa_faults_buffer[task_faults_idx(node, priv)] += pages; |
1519 | } | 1522 | } |
1520 | 1523 | ||