diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-04 11:56:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-07-04 11:56:53 -0400 |
commit | 22a093b2fb52fb656658a32adc80c24ddc200ca4 (patch) | |
tree | d0edd1065ee10369ca204404e43bdeece71d3d5e | |
parent | c1776a18e3b5a3559f3dff5df0ecce570abd3a9f (diff) | |
parent | 397f2378f136128623fc237746157aa2564d1082 (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:
"Debug info and other statistics fixes and related enhancements"
* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched/numa: Fix numa balancing stats in /proc/pid/sched
sched/numa: Show numa_group ID in /proc/sched_debug task listings
sched/debug: Move print_cfs_rq() declaration to kernel/sched/sched.h
sched/stat: Expose /proc/pid/schedstat if CONFIG_SCHED_INFO=y
sched/stat: Simplify the sched_info accounting dependency
-rw-r--r-- | fs/proc/base.c | 11 | ||||
-rw-r--r-- | include/linux/sched.h | 8 | ||||
-rw-r--r-- | init/Kconfig | 1 | ||||
-rw-r--r-- | kernel/sched/core.c | 2 | ||||
-rw-r--r-- | kernel/sched/debug.c | 40 | ||||
-rw-r--r-- | kernel/sched/fair.c | 22 | ||||
-rw-r--r-- | kernel/sched/sched.h | 13 | ||||
-rw-r--r-- | kernel/sched/stats.h | 4 | ||||
-rw-r--r-- | lib/Kconfig.debug | 5 |
9 files changed, 71 insertions, 35 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index 1d540b3f226f..87782e874b6a 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -491,14 +491,17 @@ static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns, | |||
491 | } | 491 | } |
492 | #endif | 492 | #endif |
493 | 493 | ||
494 | #ifdef CONFIG_SCHEDSTATS | 494 | #ifdef CONFIG_SCHED_INFO |
495 | /* | 495 | /* |
496 | * Provides /proc/PID/schedstat | 496 | * Provides /proc/PID/schedstat |
497 | */ | 497 | */ |
498 | static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns, | 498 | static int proc_pid_schedstat(struct seq_file *m, struct pid_namespace *ns, |
499 | struct pid *pid, struct task_struct *task) | 499 | struct pid *pid, struct task_struct *task) |
500 | { | 500 | { |
501 | seq_printf(m, "%llu %llu %lu\n", | 501 | if (unlikely(!sched_info_on())) |
502 | seq_printf(m, "0 0 0\n"); | ||
503 | else | ||
504 | seq_printf(m, "%llu %llu %lu\n", | ||
502 | (unsigned long long)task->se.sum_exec_runtime, | 505 | (unsigned long long)task->se.sum_exec_runtime, |
503 | (unsigned long long)task->sched_info.run_delay, | 506 | (unsigned long long)task->sched_info.run_delay, |
504 | task->sched_info.pcount); | 507 | task->sched_info.pcount); |
@@ -2787,7 +2790,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2787 | #ifdef CONFIG_STACKTRACE | 2790 | #ifdef CONFIG_STACKTRACE |
2788 | ONE("stack", S_IRUSR, proc_pid_stack), | 2791 | ONE("stack", S_IRUSR, proc_pid_stack), |
2789 | #endif | 2792 | #endif |
2790 | #ifdef CONFIG_SCHEDSTATS | 2793 | #ifdef CONFIG_SCHED_INFO |
2791 | ONE("schedstat", S_IRUGO, proc_pid_schedstat), | 2794 | ONE("schedstat", S_IRUGO, proc_pid_schedstat), |
2792 | #endif | 2795 | #endif |
2793 | #ifdef CONFIG_LATENCYTOP | 2796 | #ifdef CONFIG_LATENCYTOP |
@@ -3135,7 +3138,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
3135 | #ifdef CONFIG_STACKTRACE | 3138 | #ifdef CONFIG_STACKTRACE |
3136 | ONE("stack", S_IRUSR, proc_pid_stack), | 3139 | ONE("stack", S_IRUSR, proc_pid_stack), |
3137 | #endif | 3140 | #endif |
3138 | #ifdef CONFIG_SCHEDSTATS | 3141 | #ifdef CONFIG_SCHED_INFO |
3139 | ONE("schedstat", S_IRUGO, proc_pid_schedstat), | 3142 | ONE("schedstat", S_IRUGO, proc_pid_schedstat), |
3140 | #endif | 3143 | #endif |
3141 | #ifdef CONFIG_LATENCYTOP | 3144 | #ifdef CONFIG_LATENCYTOP |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 8aa4a251742f..ae21f1591615 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -192,8 +192,6 @@ struct task_group; | |||
192 | #ifdef CONFIG_SCHED_DEBUG | 192 | #ifdef CONFIG_SCHED_DEBUG |
193 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); | 193 | extern void proc_sched_show_task(struct task_struct *p, struct seq_file *m); |
194 | extern void proc_sched_set_task(struct task_struct *p); | 194 | extern void proc_sched_set_task(struct task_struct *p); |
195 | extern void | ||
196 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); | ||
197 | #endif | 195 | #endif |
198 | 196 | ||
199 | /* | 197 | /* |
@@ -838,7 +836,7 @@ extern struct user_struct root_user; | |||
838 | struct backing_dev_info; | 836 | struct backing_dev_info; |
839 | struct reclaim_state; | 837 | struct reclaim_state; |
840 | 838 | ||
841 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 839 | #ifdef CONFIG_SCHED_INFO |
842 | struct sched_info { | 840 | struct sched_info { |
843 | /* cumulative counters */ | 841 | /* cumulative counters */ |
844 | unsigned long pcount; /* # of times run on this cpu */ | 842 | unsigned long pcount; /* # of times run on this cpu */ |
@@ -848,7 +846,7 @@ struct sched_info { | |||
848 | unsigned long long last_arrival,/* when we last ran on a cpu */ | 846 | unsigned long long last_arrival,/* when we last ran on a cpu */ |
849 | last_queued; /* when we were last queued to run */ | 847 | last_queued; /* when we were last queued to run */ |
850 | }; | 848 | }; |
851 | #endif /* defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) */ | 849 | #endif /* CONFIG_SCHED_INFO */ |
852 | 850 | ||
853 | #ifdef CONFIG_TASK_DELAY_ACCT | 851 | #ifdef CONFIG_TASK_DELAY_ACCT |
854 | struct task_delay_info { | 852 | struct task_delay_info { |
@@ -1397,7 +1395,7 @@ struct task_struct { | |||
1397 | int rcu_tasks_idle_cpu; | 1395 | int rcu_tasks_idle_cpu; |
1398 | #endif /* #ifdef CONFIG_TASKS_RCU */ | 1396 | #endif /* #ifdef CONFIG_TASKS_RCU */ |
1399 | 1397 | ||
1400 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 1398 | #ifdef CONFIG_SCHED_INFO |
1401 | struct sched_info sched_info; | 1399 | struct sched_info sched_info; |
1402 | #endif | 1400 | #endif |
1403 | 1401 | ||
diff --git a/init/Kconfig b/init/Kconfig index 53c41a84dd03..af09b4fb43d2 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -435,6 +435,7 @@ config TASKSTATS | |||
435 | config TASK_DELAY_ACCT | 435 | config TASK_DELAY_ACCT |
436 | bool "Enable per-task delay accounting" | 436 | bool "Enable per-task delay accounting" |
437 | depends on TASKSTATS | 437 | depends on TASKSTATS |
438 | select SCHED_INFO | ||
438 | help | 439 | help |
439 | Collect information on time spent by a task waiting for system | 440 | Collect information on time spent by a task waiting for system |
440 | resources like cpu, synchronous block I/O completion and swapping | 441 | resources like cpu, synchronous block I/O completion and swapping |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index b803e1b8ab0c..5caa029dec5d 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2164,7 +2164,7 @@ int sched_fork(unsigned long clone_flags, struct task_struct *p) | |||
2164 | set_task_cpu(p, cpu); | 2164 | set_task_cpu(p, cpu); |
2165 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); | 2165 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); |
2166 | 2166 | ||
2167 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 2167 | #ifdef CONFIG_SCHED_INFO |
2168 | if (likely(sched_info_on())) | 2168 | if (likely(sched_info_on())) |
2169 | memset(&p->sched_info, 0, sizeof(p->sched_info)); | 2169 | memset(&p->sched_info, 0, sizeof(p->sched_info)); |
2170 | #endif | 2170 | #endif |
diff --git a/kernel/sched/debug.c b/kernel/sched/debug.c index 315c68e015d9..4222ec50ab88 100644 --- a/kernel/sched/debug.c +++ b/kernel/sched/debug.c | |||
@@ -142,7 +142,7 @@ print_task(struct seq_file *m, struct rq *rq, struct task_struct *p) | |||
142 | 0LL, 0L); | 142 | 0LL, 0L); |
143 | #endif | 143 | #endif |
144 | #ifdef CONFIG_NUMA_BALANCING | 144 | #ifdef CONFIG_NUMA_BALANCING |
145 | SEQ_printf(m, " %d", task_node(p)); | 145 | SEQ_printf(m, " %d %d", task_node(p), task_numa_group_id(p)); |
146 | #endif | 146 | #endif |
147 | #ifdef CONFIG_CGROUP_SCHED | 147 | #ifdef CONFIG_CGROUP_SCHED |
148 | SEQ_printf(m, " %s", task_group_path(task_group(p))); | 148 | SEQ_printf(m, " %s", task_group_path(task_group(p))); |
@@ -517,11 +517,21 @@ __initcall(init_sched_debug_procfs); | |||
517 | SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)p->F)) | 517 | SEQ_printf(m, "%-45s:%14Ld.%06ld\n", #F, SPLIT_NS((long long)p->F)) |
518 | 518 | ||
519 | 519 | ||
520 | #ifdef CONFIG_NUMA_BALANCING | ||
521 | void print_numa_stats(struct seq_file *m, int node, unsigned long tsf, | ||
522 | unsigned long tpf, unsigned long gsf, unsigned long gpf) | ||
523 | { | ||
524 | SEQ_printf(m, "numa_faults node=%d ", node); | ||
525 | SEQ_printf(m, "task_private=%lu task_shared=%lu ", tsf, tpf); | ||
526 | SEQ_printf(m, "group_private=%lu group_shared=%lu\n", gsf, gpf); | ||
527 | } | ||
528 | #endif | ||
529 | |||
530 | |||
520 | static void sched_show_numa(struct task_struct *p, struct seq_file *m) | 531 | static void sched_show_numa(struct task_struct *p, struct seq_file *m) |
521 | { | 532 | { |
522 | #ifdef CONFIG_NUMA_BALANCING | 533 | #ifdef CONFIG_NUMA_BALANCING |
523 | struct mempolicy *pol; | 534 | struct mempolicy *pol; |
524 | int node, i; | ||
525 | 535 | ||
526 | if (p->mm) | 536 | if (p->mm) |
527 | P(mm->numa_scan_seq); | 537 | P(mm->numa_scan_seq); |
@@ -533,26 +543,12 @@ static void sched_show_numa(struct task_struct *p, struct seq_file *m) | |||
533 | mpol_get(pol); | 543 | mpol_get(pol); |
534 | task_unlock(p); | 544 | task_unlock(p); |
535 | 545 | ||
536 | SEQ_printf(m, "numa_migrations, %ld\n", xchg(&p->numa_pages_migrated, 0)); | 546 | P(numa_pages_migrated); |
537 | 547 | P(numa_preferred_nid); | |
538 | for_each_online_node(node) { | 548 | P(total_numa_faults); |
539 | for (i = 0; i < 2; i++) { | 549 | SEQ_printf(m, "current_node=%d, numa_group_id=%d\n", |
540 | unsigned long nr_faults = -1; | 550 | task_node(p), task_numa_group_id(p)); |
541 | int cpu_current, home_node; | 551 | show_numa_stats(p, m); |
542 | |||
543 | if (p->numa_faults) | ||
544 | nr_faults = p->numa_faults[2*node + i]; | ||
545 | |||
546 | cpu_current = !i ? (task_node(p) == node) : | ||
547 | (pol && node_isset(node, pol->v.nodes)); | ||
548 | |||
549 | home_node = (p->numa_preferred_nid == node); | ||
550 | |||
551 | SEQ_printf(m, "numa_faults_memory, %d, %d, %d, %d, %ld\n", | ||
552 | i, node, cpu_current, home_node, nr_faults); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | mpol_put(pol); | 552 | mpol_put(pol); |
557 | #endif | 553 | #endif |
558 | } | 554 | } |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 3d57cc0ca0a6..65c8f3ebdc3c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -8473,7 +8473,27 @@ void print_cfs_stats(struct seq_file *m, int cpu) | |||
8473 | print_cfs_rq(m, cpu, cfs_rq); | 8473 | print_cfs_rq(m, cpu, cfs_rq); |
8474 | rcu_read_unlock(); | 8474 | rcu_read_unlock(); |
8475 | } | 8475 | } |
8476 | #endif | 8476 | |
8477 | #ifdef CONFIG_NUMA_BALANCING | ||
8478 | void show_numa_stats(struct task_struct *p, struct seq_file *m) | ||
8479 | { | ||
8480 | int node; | ||
8481 | unsigned long tsf = 0, tpf = 0, gsf = 0, gpf = 0; | ||
8482 | |||
8483 | for_each_online_node(node) { | ||
8484 | if (p->numa_faults) { | ||
8485 | tsf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 0)]; | ||
8486 | tpf = p->numa_faults[task_faults_idx(NUMA_MEM, node, 1)]; | ||
8487 | } | ||
8488 | if (p->numa_group) { | ||
8489 | gsf = p->numa_group->faults[task_faults_idx(NUMA_MEM, node, 0)], | ||
8490 | gpf = p->numa_group->faults[task_faults_idx(NUMA_MEM, node, 1)]; | ||
8491 | } | ||
8492 | print_numa_stats(m, node, tsf, tpf, gsf, gpf); | ||
8493 | } | ||
8494 | } | ||
8495 | #endif /* CONFIG_NUMA_BALANCING */ | ||
8496 | #endif /* CONFIG_SCHED_DEBUG */ | ||
8477 | 8497 | ||
8478 | __init void init_sched_fair_class(void) | 8498 | __init void init_sched_fair_class(void) |
8479 | { | 8499 | { |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 885889190a1f..84d48790bb6d 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -1689,9 +1689,22 @@ static inline void double_rq_unlock(struct rq *rq1, struct rq *rq2) | |||
1689 | 1689 | ||
1690 | extern struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq); | 1690 | extern struct sched_entity *__pick_first_entity(struct cfs_rq *cfs_rq); |
1691 | extern struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq); | 1691 | extern struct sched_entity *__pick_last_entity(struct cfs_rq *cfs_rq); |
1692 | |||
1693 | #ifdef CONFIG_SCHED_DEBUG | ||
1692 | extern void print_cfs_stats(struct seq_file *m, int cpu); | 1694 | extern void print_cfs_stats(struct seq_file *m, int cpu); |
1693 | extern void print_rt_stats(struct seq_file *m, int cpu); | 1695 | extern void print_rt_stats(struct seq_file *m, int cpu); |
1694 | extern void print_dl_stats(struct seq_file *m, int cpu); | 1696 | extern void print_dl_stats(struct seq_file *m, int cpu); |
1697 | extern void | ||
1698 | print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq); | ||
1699 | |||
1700 | #ifdef CONFIG_NUMA_BALANCING | ||
1701 | extern void | ||
1702 | show_numa_stats(struct task_struct *p, struct seq_file *m); | ||
1703 | extern void | ||
1704 | print_numa_stats(struct seq_file *m, int node, unsigned long tsf, | ||
1705 | unsigned long tpf, unsigned long gsf, unsigned long gpf); | ||
1706 | #endif /* CONFIG_NUMA_BALANCING */ | ||
1707 | #endif /* CONFIG_SCHED_DEBUG */ | ||
1695 | 1708 | ||
1696 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); | 1709 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); |
1697 | extern void init_rt_rq(struct rt_rq *rt_rq); | 1710 | extern void init_rt_rq(struct rt_rq *rt_rq); |
diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h index 077ebbd5e10f..b0fbc7632de5 100644 --- a/kernel/sched/stats.h +++ b/kernel/sched/stats.h | |||
@@ -47,7 +47,7 @@ rq_sched_info_depart(struct rq *rq, unsigned long long delta) | |||
47 | # define schedstat_set(var, val) do { } while (0) | 47 | # define schedstat_set(var, val) do { } while (0) |
48 | #endif | 48 | #endif |
49 | 49 | ||
50 | #if defined(CONFIG_SCHEDSTATS) || defined(CONFIG_TASK_DELAY_ACCT) | 50 | #ifdef CONFIG_SCHED_INFO |
51 | static inline void sched_info_reset_dequeued(struct task_struct *t) | 51 | static inline void sched_info_reset_dequeued(struct task_struct *t) |
52 | { | 52 | { |
53 | t->sched_info.last_queued = 0; | 53 | t->sched_info.last_queued = 0; |
@@ -156,7 +156,7 @@ sched_info_switch(struct rq *rq, | |||
156 | #define sched_info_depart(rq, t) do { } while (0) | 156 | #define sched_info_depart(rq, t) do { } while (0) |
157 | #define sched_info_arrive(rq, next) do { } while (0) | 157 | #define sched_info_arrive(rq, next) do { } while (0) |
158 | #define sched_info_switch(rq, t, next) do { } while (0) | 158 | #define sched_info_switch(rq, t, next) do { } while (0) |
159 | #endif /* CONFIG_SCHEDSTATS || CONFIG_TASK_DELAY_ACCT */ | 159 | #endif /* CONFIG_SCHED_INFO */ |
160 | 160 | ||
161 | /* | 161 | /* |
162 | * The following are functions that support scheduler-internal time accounting. | 162 | * The following are functions that support scheduler-internal time accounting. |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index b908048f8d6a..e2894b23efb6 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -841,9 +841,14 @@ config SCHED_DEBUG | |||
841 | that can help debug the scheduler. The runtime overhead of this | 841 | that can help debug the scheduler. The runtime overhead of this |
842 | option is minimal. | 842 | option is minimal. |
843 | 843 | ||
844 | config SCHED_INFO | ||
845 | bool | ||
846 | default n | ||
847 | |||
844 | config SCHEDSTATS | 848 | config SCHEDSTATS |
845 | bool "Collect scheduler statistics" | 849 | bool "Collect scheduler statistics" |
846 | depends on DEBUG_KERNEL && PROC_FS | 850 | depends on DEBUG_KERNEL && PROC_FS |
851 | select SCHED_INFO | ||
847 | help | 852 | help |
848 | If you say Y here, additional code will be inserted into the | 853 | If you say Y here, additional code will be inserted into the |
849 | scheduler and related routines to collect statistics about | 854 | scheduler and related routines to collect statistics about |