From abd828688407eb86044f1bc9e5133c55d7597596 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Fri, 11 Dec 2015 19:11:23 -0300 Subject: perf thread: Fix reference count initial state We should always return from thread__new(), the constructor, with the object with a reference count of one, so that: struct thread *thread = thread__new(); thread__put(thread); Will call thread__delete(). If any reference is made to that 'thread' variable, it better use thread__get(thread) to hold a reference. We were returning with thread->refcnt set to zero, fix it and some cases where thread__delete() was being called, which were not a problem because just one reference was being used, now that we set it to 1, use thread__put() instead. Reported-by: Masami Hiramatsu Cc: Adrian Hunter Cc: David Ahern Cc: Jiri Olsa Cc: Namhyung Kim Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-4b9mkuk66to4ecckpmpvqx6s@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- tools/perf/util/machine.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'tools/perf/util/machine.c') diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 1407d5107480..ad79297c76c8 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c @@ -352,13 +352,18 @@ static void machine__update_thread_pid(struct machine *machine, } th->mg = map_groups__get(leader->mg); - +out_put: + thread__put(leader); return; - out_err: pr_err("Failed to join map groups for %d:%d\n", th->pid_, th->tid); + goto out_put; } +/* + * Caller must eventually drop thread->refcnt returned with a successfull + * lookup/new thread inserted. + */ static struct thread *____machine__findnew_thread(struct machine *machine, pid_t pid, pid_t tid, bool create) @@ -376,7 +381,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, if (th != NULL) { if (th->tid == tid) { machine__update_thread_pid(machine, th, pid); - return th; + return thread__get(th); } machine->last_match = NULL; @@ -389,7 +394,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, if (th->tid == tid) { machine->last_match = th; machine__update_thread_pid(machine, th, pid); - return th; + return thread__get(th); } if (tid < th->tid) @@ -417,7 +422,7 @@ static struct thread *____machine__findnew_thread(struct machine *machine, if (thread__init_map_groups(th, machine)) { rb_erase_init(&th->rb_node, &machine->threads); RB_CLEAR_NODE(&th->rb_node); - thread__delete(th); + thread__put(th); return NULL; } /* @@ -441,7 +446,7 @@ struct thread *machine__findnew_thread(struct machine *machine, pid_t pid, struct thread *th; pthread_rwlock_wrlock(&machine->threads_lock); - th = thread__get(__machine__findnew_thread(machine, pid, tid)); + th = __machine__findnew_thread(machine, pid, tid); pthread_rwlock_unlock(&machine->threads_lock); return th; } @@ -451,7 +456,7 @@ struct thread *machine__find_thread(struct machine *machine, pid_t pid, { struct thread *th; pthread_rwlock_rdlock(&machine->threads_lock); - th = thread__get(____machine__findnew_thread(machine, pid, tid, false)); + th = ____machine__findnew_thread(machine, pid, tid, false); pthread_rwlock_unlock(&machine->threads_lock); return th; } -- cgit v1.2.3