Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d8b172f authored by Masami Hiramatsu's avatar Masami Hiramatsu Committed by Arnaldo Carvalho de Melo
Browse files

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: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Tested-by: default avatarArnaldo 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 8488335c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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,
+7 −4
Original line number Diff line number Diff line
@@ -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))
+1 −1
Original line number Diff line number Diff line
@@ -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);