[PATCH v2 7/7] perf thread: Avoid recursively taking thread__comm_lock

Ian Rogers posted 7 patches 6 months, 3 weeks ago
[PATCH v2 7/7] perf thread: Avoid recursively taking thread__comm_lock
Posted by Ian Rogers 6 months, 3 weeks ago
Fix cases where functions that take thread_comm_lcok were called
holding thread__comm_lock. This created some buggy behavior in perf
top when built with sanitizers. Ensure -Wthread-safety warnings for
clang work.

Fixes: 8f454c95817d ("perf thread: Ensure comm_lock held for comm_list")
Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/util/thread.c | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index c202b98b36c2..f4ad15e1e314 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -201,13 +201,21 @@ int thread__set_namespaces(struct thread *thread, u64 timestamp,
 	return ret;
 }
 
+static struct comm *__thread__comm(struct thread *thread)
+	SHARED_LOCKS_REQUIRED(thread__comm_lock(thread))
+{
+	if (list_empty(thread__comm_list(thread)))
+		return NULL;
+
+	return list_first_entry(thread__comm_list(thread), struct comm, list);
+}
+
 struct comm *thread__comm(struct thread *thread)
 {
 	struct comm *res = NULL;
 
 	down_read(thread__comm_lock(thread));
-	if (!list_empty(thread__comm_list(thread)))
-		res = list_first_entry(thread__comm_list(thread), struct comm, list);
+	res = __thread__comm(thread);
 	up_read(thread__comm_lock(thread));
 	return res;
 }
@@ -243,7 +251,7 @@ static int ____thread__set_comm(struct thread *thread, const char *str,
 				u64 timestamp, bool exec)
 	EXCLUSIVE_LOCKS_REQUIRED(thread__comm_lock(thread))
 {
-	struct comm *new, *curr = thread__comm(thread);
+	struct comm *new, *curr = __thread__comm(thread);
 
 	/* Override the default :tid entry */
 	if (!thread__comm_set(thread)) {
@@ -294,8 +302,9 @@ int thread__set_comm_from_proc(struct thread *thread)
 }
 
 static const char *__thread__comm_str(struct thread *thread)
+	SHARED_LOCKS_REQUIRED(thread__comm_lock(thread))
 {
-	const struct comm *comm = thread__comm(thread);
+	const struct comm *comm = __thread__comm(thread);
 
 	if (!comm)
 		return NULL;
-- 
2.49.0.1238.gf8c92423fb-goog