summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2016-12-08 17:47:52 +0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2016-12-15 22:25:44 +0300
commit699b5b920db04a6ff5c03a519e4c182aeb350952 (patch)
treeaab4112c7710f7cb813ecaad9a1d27b441ff1b39
parent3bc2fa9cb829ccf6527e7117d9af769d93ee6d39 (diff)
downloadlinux-699b5b920db04a6ff5c03a519e4c182aeb350952.tar.xz
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>
-rw-r--r--tools/perf/builtin-sched.c30
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 {
/* options for timehist command */
bool summary;
bool summary_only;
+ bool idle_hist;
bool show_callchain;
unsigned int max_stack;
bool show_cpu_visual;
@@ -2101,6 +2102,15 @@ static struct thread *get_idle_thread(int cpu)
return idle_threads[cpu];
}
+static void save_idle_callchain(struct idle_thread_runtime *itr,
+ struct perf_sample *sample)
+{
+ if (!symbol_conf.use_callchain || sample->callchain == NULL)
+ return;
+
+ callchain_cursor__copy(&itr->cursor, &callchain_cursor);
+}
+
/*
* handle runtime stats saved per thread
*/
@@ -2154,6 +2164,26 @@ static struct thread *timehist_get_thread(struct perf_sched *sched,
}
save_task_callchain(sched, sample, evsel, machine);
+ if (sched->idle_hist) {
+ struct thread *idle;
+ struct idle_thread_runtime *itr;
+
+ idle = get_idle_thread(sample->cpu);
+ if (idle == NULL) {
+ pr_err("Failed to get idle thread for cpu %d.\n", sample->cpu);
+ return NULL;
+ }
+
+ itr = thread__priv(idle);
+ if (itr == NULL)
+ return NULL;
+
+ itr->last_thread = thread;
+
+ /* copy task callchain when entering to idle */
+ if (perf_evsel__intval(evsel, sample, "next_pid") == 0)
+ save_idle_callchain(itr, sample);
+ }
}
return thread;