diff options
author | Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> | 2015-12-08 21:11:23 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-12-10 14:28:58 -0500 |
commit | 9d8b172f29ac0e5d1923d348e395e9643625ef7f (patch) | |
tree | fbef908a219bb1e5733e97c466044b94525894e6 | |
parent | 8488335c039ff4917754332763e21c01a81435b4 (diff) |
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 <masami.hiramatsu.pt@hitachi.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
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 <acme@redhat.com>
-rw-r--r-- | tools/perf/builtin-top.c | 2 | ||||
-rw-r--r-- | tools/perf/util/session.c | 11 | ||||
-rw-r--r-- | 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) | |||
964 | if (ret) | 964 | if (ret) |
965 | goto out_delete; | 965 | goto out_delete; |
966 | 966 | ||
967 | if (perf_session__register_idle_thread(top->session) == NULL) | 967 | if (perf_session__register_idle_thread(top->session) < 0) |
968 | goto out_delete; | 968 | goto out_delete; |
969 | 969 | ||
970 | machine__synthesize_threads(&top->session->machines.host, &opts->target, | 970 | 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) | |||
1311 | return machine__findnew_thread(&session->machines.host, -1, pid); | 1311 | return machine__findnew_thread(&session->machines.host, -1, pid); |
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | struct thread *perf_session__register_idle_thread(struct perf_session *session) | 1314 | int perf_session__register_idle_thread(struct perf_session *session) |
1315 | { | 1315 | { |
1316 | struct thread *thread; | 1316 | struct thread *thread; |
1317 | int err = 0; | ||
1317 | 1318 | ||
1318 | thread = machine__findnew_thread(&session->machines.host, 0, 0); | 1319 | thread = machine__findnew_thread(&session->machines.host, 0, 0); |
1319 | if (thread == NULL || thread__set_comm(thread, "swapper", 0)) { | 1320 | if (thread == NULL || thread__set_comm(thread, "swapper", 0)) { |
1320 | pr_err("problem inserting idle task.\n"); | 1321 | pr_err("problem inserting idle task.\n"); |
1321 | thread = NULL; | 1322 | err = -1; |
1322 | } | 1323 | } |
1323 | 1324 | ||
1324 | return thread; | 1325 | /* machine__findnew_thread() got the thread, so put it */ |
1326 | thread__put(thread); | ||
1327 | return err; | ||
1325 | } | 1328 | } |
1326 | 1329 | ||
1327 | static void perf_session__warn_about_errors(const struct perf_session *session) | 1330 | 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) | |||
1676 | u64 size = perf_data_file__size(session->file); | 1679 | u64 size = perf_data_file__size(session->file); |
1677 | int err; | 1680 | int err; |
1678 | 1681 | ||
1679 | if (perf_session__register_idle_thread(session) == NULL) | 1682 | if (perf_session__register_idle_thread(session) < 0) |
1680 | return -ENOMEM; | 1683 | return -ENOMEM; |
1681 | 1684 | ||
1682 | if (!perf_data_file__is_pipe(session->file)) | 1685 | 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_ | |||
89 | } | 89 | } |
90 | 90 | ||
91 | struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); | 91 | struct thread *perf_session__findnew(struct perf_session *session, pid_t pid); |
92 | struct thread *perf_session__register_idle_thread(struct perf_session *session); | 92 | int perf_session__register_idle_thread(struct perf_session *session); |
93 | 93 | ||
94 | size_t perf_session__fprintf(struct perf_session *session, FILE *fp); | 94 | size_t perf_session__fprintf(struct perf_session *session, FILE *fp); |
95 | 95 | ||