diff options
author | Namhyung Kim <namhyung@kernel.org> | 2016-12-08 09:47:52 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2016-12-15 14:25:44 -0500 |
commit | 699b5b920db04a6ff5c03a519e4c182aeb350952 (patch) | |
tree | aab4112c7710f7cb813ecaad9a1d27b441ff1b39 /tools/perf/builtin-sched.c | |
parent | 3bc2fa9cb829ccf6527e7117d9af769d93ee6d39 (diff) |
perf sched timehist: Save callchain when entering idle
In order to investigate the idleness reason, it is necessary to keep the
callchains when entering idle. This can be identified by the
sched:sched_switch event having the next_pid field as 0.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: David Ahern <dsahern@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Minchan Kim <minchan@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/20161208144755.16673-4-namhyung@kernel.org
Link: http://lkml.kernel.org/r/20161213080632.19099-1-namhyung@kernel.org
[ Merged fix from Namhyung, see second Link: tag ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-sched.c')
-rw-r--r-- | tools/perf/builtin-sched.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c index e108b0f6a246..dc83b803ca54 100644 --- a/tools/perf/builtin-sched.c +++ b/tools/perf/builtin-sched.c | |||
@@ -200,6 +200,7 @@ struct perf_sched { | |||
200 | /* options for timehist command */ | 200 | /* options for timehist command */ |
201 | bool summary; | 201 | bool summary; |
202 | bool summary_only; | 202 | bool summary_only; |
203 | bool idle_hist; | ||
203 | bool show_callchain; | 204 | bool show_callchain; |
204 | unsigned int max_stack; | 205 | unsigned int max_stack; |
205 | bool show_cpu_visual; | 206 | bool show_cpu_visual; |
@@ -2101,6 +2102,15 @@ static struct thread *get_idle_thread(int cpu) | |||
2101 | return idle_threads[cpu]; | 2102 | return idle_threads[cpu]; |
2102 | } | 2103 | } |
2103 | 2104 | ||
2105 | static void save_idle_callchain(struct idle_thread_runtime *itr, | ||
2106 | struct perf_sample *sample) | ||
2107 | { | ||
2108 | if (!symbol_conf.use_callchain || sample->callchain == NULL) | ||
2109 | return; | ||
2110 | |||
2111 | callchain_cursor__copy(&itr->cursor, &callchain_cursor); | ||
2112 | } | ||
2113 | |||
2104 | /* | 2114 | /* |
2105 | * handle runtime stats saved per thread | 2115 | * handle runtime stats saved per thread |
2106 | */ | 2116 | */ |
@@ -2154,6 +2164,26 @@ static struct thread *timehist_get_thread(struct perf_sched *sched, | |||
2154 | } | 2164 | } |
2155 | 2165 | ||
2156 | save_task_callchain(sched, sample, evsel, machine); | 2166 | save_task_callchain(sched, sample, evsel, machine); |
2167 | if (sched->idle_hist) { | ||
2168 | struct thread *idle; | ||
2169 | struct idle_thread_runtime *itr; | ||
2170 | |||
2171 | idle = get_idle_thread(sample->cpu); | ||
2172 | if (idle == NULL) { | ||
2173 | pr_err("Failed to get idle thread for cpu %d.\n", sample->cpu); | ||
2174 | return NULL; | ||
2175 | } | ||
2176 | |||
2177 | itr = thread__priv(idle); | ||
2178 | if (itr == NULL) | ||
2179 | return NULL; | ||
2180 | |||
2181 | itr->last_thread = thread; | ||
2182 | |||
2183 | /* copy task callchain when entering to idle */ | ||
2184 | if (perf_evsel__intval(evsel, sample, "next_pid") == 0) | ||
2185 | save_idle_callchain(itr, sample); | ||
2186 | } | ||
2157 | } | 2187 | } |
2158 | 2188 | ||
2159 | return thread; | 2189 | return thread; |