From 9d8b172f29ac0e5d1923d348e395e9643625ef7f Mon Sep 17 00:00:00 2001 From: Masami Hiramatsu Date: Wed, 9 Dec 2015 11:11:23 +0900 Subject: [PATCH] perf tools: Make perf_session__register_idle_thread drop the refcount Note that since the thread was already inserted to the session list, it will be released when the session is released. Also, in perf_session__register_idle_thread() failure path, the thread should be put before returning. Refcnt debugger shows that the perf_session__register_idle_thread gets the returned thread, but the caller (__cmd_top) does not put the returned idle thread. ---- ==== [0] ==== Unreclaimed thread@0x24e6240 Refcount +1 => 0 at ./perf(thread__new+0xe5) [0x4c8a75] ./perf(machine__findnew_thread+0x9a) [0x4bbdba] ./perf(perf_session__register_idle_thread+0x28) [0x4c63c8] ./perf(cmd_top+0xd7d) [0x43cf6d] ./perf() [0x47ba35] ./perf(main+0x617) [0x4225b7] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f06027c5af5] ./perf() [0x42272d] Refcount +1 => 1 at ./perf(thread__get+0x2c) [0x4c8bcc] ./perf(machine__findnew_thread+0xee) [0x4bbe0e] ./perf(perf_session__register_idle_thread+0x28) [0x4c63c8] ./perf(cmd_top+0xd7d) [0x43cf6d] ./perf() [0x47ba35] ./perf(main+0x617) [0x4225b7] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f06027c5af5] ./perf() [0x42272d] Refcount +1 => 2 at ./perf(thread__get+0x2c) [0x4c8bcc] ./perf(machine__findnew_thread+0x112) [0x4bbe32] ./perf(perf_session__register_idle_thread+0x28) [0x4c63c8] ./perf(cmd_top+0xd7d) [0x43cf6d] ./perf() [0x47ba35] ./perf(main+0x617) [0x4225b7] /lib64/libc.so.6(__libc_start_main+0xf5) [0x7f06027c5af5] ./perf() [0x42272d] ---- Signed-off-by: Masami Hiramatsu Tested-by: Arnaldo Carvalho de Melo Cc: Adrian Hunter Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Link: http://lkml.kernel.org/r/20151209021122.10245.69707.stgit@localhost.localdomain [ Drop the refcount in perf_session__register_idle_thread() ] Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/builtin-top.c | 2 +- tools/perf/util/session.c | 11 +++++++---- tools/perf/util/session.h | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 84fd6368ed6d..785aa2dd8f0b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -964,7 +964,7 @@ static int __cmd_top(struct perf_top *top) if (ret) goto out_delete; - if (perf_session__register_idle_thread(top->session) == NULL) + if (perf_session__register_idle_thread(top->session) < 0) goto out_delete; machine__synthesize_threads(&top->session->machines.host, &opts->target, diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index c35ffdd360fe..9774686525b4 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c @@ -1311,17 +1311,20 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid) return machine__findnew_thread(&session->machines.host, -1, pid); } -struct thread *perf_session__register_idle_thread(struct perf_session *session) +int perf_session__register_idle_thread(struct perf_session *session) { struct thread *thread; + int err = 0; thread = machine__findnew_thread(&session->machines.host, 0, 0); if (thread == NULL || thread__set_comm(thread, "swapper", 0)) { pr_err("problem inserting idle task.\n"); - thread = NULL; + err = -1; } - return thread; + /* machine__findnew_thread() got the thread, so put it */ + thread__put(thread); + return err; } static void perf_session__warn_about_errors(const struct perf_session *session) @@ -1676,7 +1679,7 @@ int perf_session__process_events(struct perf_session *session) u64 size = perf_data_file__size(session->file); int err; - if (perf_session__register_idle_thread(session) == NULL) + if (perf_session__register_idle_thread(session) < 0) return -ENOMEM; if (!perf_data_file__is_pipe(session->file)) diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 3e900c0efc73..5f792e35d4c1 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h @@ -89,7 +89,7 @@ struct machine *perf_session__findnew_machine(struct perf_session *session, pid_ } struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); -struct thread *perf_session__register_idle_thread(struct perf_session *session); +int perf_session__register_idle_thread(struct perf_session *session); size_t perf_session__fprintf(struct perf_session *session, FILE *fp); -- 2.20.1