All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: John Garry <john.g.garry@oracle.com>,
	Will Deacon <will@kernel.org>, James Clark <james.clark@arm.com>,
	Mike Leach <mike.leach@linaro.org>, Leo Yan <leo.yan@linaro.org>,
	Peter Zijlstra <peterz@infradead.org>,
	Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>, Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	Adrian Hunter <adrian.hunter@intel.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	"Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>,
	Kan Liang <kan.liang@linux.intel.com>,
	German Gomez <german.gomez@arm.com>,
	Ali Saidi <alisaidi@amazon.com>,
	Jing Zhang <renyu.zj@linux.alibaba.com>,
	Athira Rajeev <atrajeev@linux.vnet.ibm.com>,
	Miguel Ojeda <ojeda@kernel.org>,
	ye xingchen <ye.xingchen@zte.com.cn>,
	Liam Howlett <liam.howlett@oracle.com>,
	Dmitrii Dolgov <9erthalion6@gmail.com>,
	Yang Jihong <yangjihong1@huawei.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	Changbin Du <changbin.du@huawei.com>,
	Ravi Bangoria <ravi.bangoria@amd.com>,
	Sean Christopherson <seanjc@google.com>,
	Andi Kleen <ak@linux.intel.com>,
	"Steinar H. Gunderson" <sesse@google.com>,
	Yuan Can <yuancan@huawei.com>,
	Brian Robbins <brianrob@linux.microsoft.com>,
	liuwenyu <liuwenyu7@huawei.com>,
	Ivan Babrou <ivan@cloudflare.com>,
	Fangrui Song <maskray@google.com>,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org, coresight@lists.linaro.org
Subject: [PATCH v2 07/26] perf thread: Add reference count checking
Date: Thu,  8 Jun 2023 16:28:04 -0700	[thread overview]
Message-ID: <20230608232823.4027869-8-irogers@google.com> (raw)
In-Reply-To: <20230608232823.4027869-1-irogers@google.com>

Modify struct declaration and accessor functions for the reference
count checkers additional layer of indirection. Make sure pid_cmp in
builtin-sched.c uses the underlying/original struct in pointer
arithmetic, and not the temporary get/put indirection.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-sched.c    |  4 +-
 tools/perf/tests/hists_link.c |  2 +-
 tools/perf/ui/hist.c          |  5 ++-
 tools/perf/util/hist.c        |  2 +-
 tools/perf/util/machine.c     |  2 +-
 tools/perf/util/sort.c        |  2 +-
 tools/perf/util/thread.c      | 20 +++++----
 tools/perf/util/thread.h      | 79 ++++++++++++++++++-----------------
 8 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c75ad82a6729..cd79068200e5 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1385,7 +1385,7 @@ static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
 {
 	pid_t l_tid, r_tid;
 
-	if (l->thread == r->thread)
+	if (RC_CHK_ACCESS(l->thread) == RC_CHK_ACCESS(r->thread))
 		return 0;
 	l_tid = thread__tid(l->thread);
 	r_tid = thread__tid(r->thread);
@@ -1393,7 +1393,7 @@ static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
 		return -1;
 	if (l_tid > r_tid)
 		return 1;
-	return (int)(l->thread - r->thread);
+	return (int)(RC_CHK_ACCESS(l->thread) - RC_CHK_ACCESS(r->thread));
 }
 
 static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 12bad8840699..2d19657ab5e0 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -148,7 +148,7 @@ static int find_sample(struct sample *samples, size_t nr_samples,
 		       struct thread *t, struct map *m, struct symbol *s)
 {
 	while (nr_samples--) {
-		if (samples->thread == t &&
+		if (RC_CHK_ACCESS(samples->thread) == RC_CHK_ACCESS(t) &&
 		    RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) &&
 		    samples->sym == s)
 			return 1;
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index f164bd26fc41..2bf959d08354 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -11,6 +11,7 @@
 #include "../util/sort.h"
 #include "../util/evsel.h"
 #include "../util/evlist.h"
+#include "../util/thread.h"
 #include "../util/util.h"
 
 /* hist period print (hpp) functions */
@@ -274,7 +275,9 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b,
 		if (ret)
 			return ret;
 
-		if (a->thread != b->thread || !hist_entry__has_callchains(a) || !symbol_conf.use_callchain)
+		if ((a->thread == NULL ? NULL : RC_CHK_ACCESS(a->thread)) !=
+		    (b->thread == NULL ? NULL : RC_CHK_ACCESS(b->thread)) ||
+		    !hist_entry__has_callchains(a) || !symbol_conf.use_callchain)
 			return 0;
 
 		ret = b->callchain->max_depth - a->callchain->max_depth;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index a4c1b617f6e4..dfda52d348a3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -2124,7 +2124,7 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
 					  struct hist_entry *he)
 {
 	if (hists->thread_filter != NULL &&
-	    he->thread != hists->thread_filter) {
+	    RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(hists->thread_filter)) {
 		he->filtered |= (1 << HIST_FILTER__THREAD);
 		return true;
 	}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9fcf357a4d53..261188766307 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2055,7 +2055,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread_rb_n
 	if (!nd)
 		nd = thread_rb_node__find(th, &threads->entries.rb_root);
 
-	if (threads->last_match == th)
+	if (threads->last_match && RC_CHK_ACCESS(threads->last_match) == RC_CHK_ACCESS(th))
 		threads__set_last_match(threads, NULL);
 
 	if (lock)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5e45c770f91d..047c3606802f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -128,7 +128,7 @@ static int hist_entry__thread_filter(struct hist_entry *he, int type, const void
 	if (type != HIST_FILTER__THREAD)
 		return -1;
 
-	return th && he->thread != th;
+	return th && RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(th);
 }
 
 struct sort_entry sort_thread = {
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index bee4ac1051ee..0b166404c5c3 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -41,9 +41,10 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 {
 	char *comm_str;
 	struct comm *comm;
-	struct thread *thread = zalloc(sizeof(*thread));
+	RC_STRUCT(thread) *_thread = zalloc(sizeof(*_thread));
+	struct thread *thread;
 
-	if (thread != NULL) {
+	if (ADD_RC_CHK(thread, _thread) != NULL) {
 		thread__set_pid(thread, pid);
 		thread__set_tid(thread, tid);
 		thread__set_ppid(thread, -1);
@@ -68,7 +69,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		list_add(&comm->list, thread__comm_list(thread));
 		refcount_set(thread__refcnt(thread), 1);
 		/* Thread holds first ref to nsdata. */
-		thread->nsinfo = nsinfo__new(pid);
+		RC_CHK_ACCESS(thread)->nsinfo = nsinfo__new(pid);
 		srccode_state_init(thread__srccode_state(thread));
 	}
 
@@ -105,26 +106,31 @@ void thread__delete(struct thread *thread)
 	}
 	up_write(thread__comm_lock(thread));
 
-	nsinfo__zput(thread->nsinfo);
+	nsinfo__zput(RC_CHK_ACCESS(thread)->nsinfo);
 	srccode_state_free(thread__srccode_state(thread));
 
 	exit_rwsem(thread__namespaces_lock(thread));
 	exit_rwsem(thread__comm_lock(thread));
 	thread__free_stitch_list(thread);
-	free(thread);
+	RC_CHK_FREE(thread);
 }
 
 struct thread *thread__get(struct thread *thread)
 {
-	if (thread)
+	struct thread *result;
+
+	if (RC_CHK_GET(result, thread))
 		refcount_inc(thread__refcnt(thread));
-	return thread;
+
+	return result;
 }
 
 void thread__put(struct thread *thread)
 {
 	if (thread && refcount_dec_and_test(thread__refcnt(thread)))
 		thread__delete(thread);
+	else
+		RC_CHK_PUT(thread);
 }
 
 static struct namespaces *__thread__namespaces(struct thread *thread)
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index b103992c3831..9068a21ce0fa 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -15,6 +15,7 @@
 #include "rwsem.h"
 #include "event.h"
 #include "callchain.h"
+#include <internal/rc_check.h>
 
 struct addr_location;
 struct map;
@@ -34,7 +35,7 @@ struct thread_rb_node {
 	struct thread *thread;
 };
 
-struct thread {
+DECLARE_RC_STRUCT(thread) {
 	struct maps		*maps;
 	pid_t			pid_; /* Not all tools update this */
 	pid_t			tid;
@@ -123,192 +124,192 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
 
 static inline struct maps *thread__maps(struct thread *thread)
 {
-	return thread->maps;
+	return RC_CHK_ACCESS(thread)->maps;
 }
 
 static inline void thread__set_maps(struct thread *thread, struct maps *maps)
 {
-	thread->maps = maps;
+	RC_CHK_ACCESS(thread)->maps = maps;
 }
 
 static inline pid_t thread__pid(const struct thread *thread)
 {
-	return thread->pid_;
+	return RC_CHK_ACCESS(thread)->pid_;
 }
 
 static inline void thread__set_pid(struct thread *thread, pid_t pid_)
 {
-	thread->pid_ = pid_;
+	RC_CHK_ACCESS(thread)->pid_ = pid_;
 }
 
 static inline pid_t thread__tid(const struct thread *thread)
 {
-	return thread->tid;
+	return RC_CHK_ACCESS(thread)->tid;
 }
 
 static inline void thread__set_tid(struct thread *thread, pid_t tid)
 {
-	thread->tid = tid;
+	RC_CHK_ACCESS(thread)->tid = tid;
 }
 
 static inline pid_t thread__ppid(const struct thread *thread)
 {
-	return thread->ppid;
+	return RC_CHK_ACCESS(thread)->ppid;
 }
 
 static inline void thread__set_ppid(struct thread *thread, pid_t ppid)
 {
-	thread->ppid = ppid;
+	RC_CHK_ACCESS(thread)->ppid = ppid;
 }
 
 static inline int thread__cpu(const struct thread *thread)
 {
-	return thread->cpu;
+	return RC_CHK_ACCESS(thread)->cpu;
 }
 
 static inline void thread__set_cpu(struct thread *thread, int cpu)
 {
-	thread->cpu = cpu;
+	RC_CHK_ACCESS(thread)->cpu = cpu;
 }
 
 static inline int thread__guest_cpu(const struct thread *thread)
 {
-	return thread->guest_cpu;
+	return RC_CHK_ACCESS(thread)->guest_cpu;
 }
 
 static inline void thread__set_guest_cpu(struct thread *thread, int guest_cpu)
 {
-	thread->guest_cpu = guest_cpu;
+	RC_CHK_ACCESS(thread)->guest_cpu = guest_cpu;
 }
 
 static inline refcount_t *thread__refcnt(struct thread *thread)
 {
-	return &thread->refcnt;
+	return &RC_CHK_ACCESS(thread)->refcnt;
 }
 
 static inline bool thread__comm_set(const struct thread *thread)
 {
-	return thread->comm_set;
+	return RC_CHK_ACCESS(thread)->comm_set;
 }
 
 static inline void thread__set_comm_set(struct thread *thread, bool set)
 {
-	thread->comm_set = set;
+	RC_CHK_ACCESS(thread)->comm_set = set;
 }
 
 static inline int thread__var_comm_len(const struct thread *thread)
 {
-	return thread->comm_len;
+	return RC_CHK_ACCESS(thread)->comm_len;
 }
 
 static inline void thread__set_comm_len(struct thread *thread, int len)
 {
-	thread->comm_len = len;
+	RC_CHK_ACCESS(thread)->comm_len = len;
 }
 
 static inline struct list_head *thread__namespaces_list(struct thread *thread)
 {
-	return &thread->namespaces_list;
+	return &RC_CHK_ACCESS(thread)->namespaces_list;
 }
 
 static inline int thread__namespaces_list_empty(const struct thread *thread)
 {
-	return list_empty(&thread->namespaces_list);
+	return list_empty(&RC_CHK_ACCESS(thread)->namespaces_list);
 }
 
 static inline struct rw_semaphore *thread__namespaces_lock(struct thread *thread)
 {
-	return &thread->namespaces_lock;
+	return &RC_CHK_ACCESS(thread)->namespaces_lock;
 }
 
 static inline struct list_head *thread__comm_list(struct thread *thread)
 {
-	return &thread->comm_list;
+	return &RC_CHK_ACCESS(thread)->comm_list;
 }
 
 static inline struct rw_semaphore *thread__comm_lock(struct thread *thread)
 {
-	return &thread->comm_lock;
+	return &RC_CHK_ACCESS(thread)->comm_lock;
 }
 
 static inline u64 thread__db_id(const struct thread *thread)
 {
-	return thread->db_id;
+	return RC_CHK_ACCESS(thread)->db_id;
 }
 
 static inline void thread__set_db_id(struct thread *thread, u64 db_id)
 {
-	thread->db_id = db_id;
+	RC_CHK_ACCESS(thread)->db_id = db_id;
 }
 
 static inline void *thread__priv(struct thread *thread)
 {
-	return thread->priv;
+	return RC_CHK_ACCESS(thread)->priv;
 }
 
 static inline void thread__set_priv(struct thread *thread, void *p)
 {
-	thread->priv = p;
+	RC_CHK_ACCESS(thread)->priv = p;
 }
 
 static inline struct thread_stack *thread__ts(struct thread *thread)
 {
-	return thread->ts;
+	return RC_CHK_ACCESS(thread)->ts;
 }
 
 static inline void thread__set_ts(struct thread *thread, struct thread_stack *ts)
 {
-	thread->ts = ts;
+	RC_CHK_ACCESS(thread)->ts = ts;
 }
 
 static inline struct nsinfo *thread__nsinfo(struct thread *thread)
 {
-	return thread->nsinfo;
+	return RC_CHK_ACCESS(thread)->nsinfo;
 }
 
 static inline struct srccode_state *thread__srccode_state(struct thread *thread)
 {
-	return &thread->srccode_state;
+	return &RC_CHK_ACCESS(thread)->srccode_state;
 }
 
 static inline bool thread__filter(const struct thread *thread)
 {
-	return thread->filter;
+	return RC_CHK_ACCESS(thread)->filter;
 }
 
 static inline void thread__set_filter(struct thread *thread, bool filter)
 {
-	thread->filter = filter;
+	RC_CHK_ACCESS(thread)->filter = filter;
 }
 
 static inline int thread__filter_entry_depth(const struct thread *thread)
 {
-	return thread->filter_entry_depth;
+	return RC_CHK_ACCESS(thread)->filter_entry_depth;
 }
 
 static inline void thread__set_filter_entry_depth(struct thread *thread, int depth)
 {
-	thread->filter_entry_depth = depth;
+	RC_CHK_ACCESS(thread)->filter_entry_depth = depth;
 }
 
 static inline bool thread__lbr_stitch_enable(const struct thread *thread)
 {
-	return thread->lbr_stitch_enable;
+	return RC_CHK_ACCESS(thread)->lbr_stitch_enable;
 }
 
 static inline void thread__set_lbr_stitch_enable(struct thread *thread, bool en)
 {
-	thread->lbr_stitch_enable = en;
+	RC_CHK_ACCESS(thread)->lbr_stitch_enable = en;
 }
 
 static inline struct lbr_stitch	*thread__lbr_stitch(struct thread *thread)
 {
-	return thread->lbr_stitch;
+	return RC_CHK_ACCESS(thread)->lbr_stitch;
 }
 
 static inline void thread__set_lbr_stitch(struct thread *thread, struct lbr_stitch *lbrs)
 {
-	thread->lbr_stitch = lbrs;
+	RC_CHK_ACCESS(thread)->lbr_stitch = lbrs;
 }
 
 static inline bool thread__is_filtered(struct thread *thread)
-- 
2.41.0.162.gfafddb0af9-goog


WARNING: multiple messages have this Message-ID (diff)
From: Ian Rogers <irogers@google.com>
To: John Garry <john.g.garry@oracle.com>,
	Will Deacon <will@kernel.org>,  James Clark <james.clark@arm.com>,
	Mike Leach <mike.leach@linaro.org>,  Leo Yan <leo.yan@linaro.org>,
	Peter Zijlstra <peterz@infradead.org>,
	 Ingo Molnar <mingo@redhat.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Mark Rutland <mark.rutland@arm.com>,
	 Alexander Shishkin <alexander.shishkin@linux.intel.com>,
	Jiri Olsa <jolsa@kernel.org>,  Namhyung Kim <namhyung@kernel.org>,
	Ian Rogers <irogers@google.com>,
	 Adrian Hunter <adrian.hunter@intel.com>,
	Suzuki K Poulose <suzuki.poulose@arm.com>,
	 "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>,
	Kan Liang <kan.liang@linux.intel.com>,
	 German Gomez <german.gomez@arm.com>,
	Ali Saidi <alisaidi@amazon.com>,
	 Jing Zhang <renyu.zj@linux.alibaba.com>,
	Athira Rajeev <atrajeev@linux.vnet.ibm.com>,
	 Miguel Ojeda <ojeda@kernel.org>,
	ye xingchen <ye.xingchen@zte.com.cn>,
	 Liam Howlett <liam.howlett@oracle.com>,
	Dmitrii Dolgov <9erthalion6@gmail.com>,
	 Yang Jihong <yangjihong1@huawei.com>,
	K Prateek Nayak <kprateek.nayak@amd.com>,
	 Changbin Du <changbin.du@huawei.com>,
	Ravi Bangoria <ravi.bangoria@amd.com>,
	 Sean Christopherson <seanjc@google.com>,
	Andi Kleen <ak@linux.intel.com>,
	 "Steinar H. Gunderson" <sesse@google.com>,
	Yuan Can <yuancan@huawei.com>,
	 Brian Robbins <brianrob@linux.microsoft.com>,
	liuwenyu <liuwenyu7@huawei.com>,
	 Ivan Babrou <ivan@cloudflare.com>,
	Fangrui Song <maskray@google.com>,
	linux-kernel@vger.kernel.org,
	 linux-arm-kernel@lists.infradead.org,
	linux-perf-users@vger.kernel.org,  coresight@lists.linaro.org
Subject: [PATCH v2 07/26] perf thread: Add reference count checking
Date: Thu,  8 Jun 2023 16:28:04 -0700	[thread overview]
Message-ID: <20230608232823.4027869-8-irogers@google.com> (raw)
In-Reply-To: <20230608232823.4027869-1-irogers@google.com>

Modify struct declaration and accessor functions for the reference
count checkers additional layer of indirection. Make sure pid_cmp in
builtin-sched.c uses the underlying/original struct in pointer
arithmetic, and not the temporary get/put indirection.

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-sched.c    |  4 +-
 tools/perf/tests/hists_link.c |  2 +-
 tools/perf/ui/hist.c          |  5 ++-
 tools/perf/util/hist.c        |  2 +-
 tools/perf/util/machine.c     |  2 +-
 tools/perf/util/sort.c        |  2 +-
 tools/perf/util/thread.c      | 20 +++++----
 tools/perf/util/thread.h      | 79 ++++++++++++++++++-----------------
 8 files changed, 63 insertions(+), 53 deletions(-)

diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index c75ad82a6729..cd79068200e5 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1385,7 +1385,7 @@ static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
 {
 	pid_t l_tid, r_tid;
 
-	if (l->thread == r->thread)
+	if (RC_CHK_ACCESS(l->thread) == RC_CHK_ACCESS(r->thread))
 		return 0;
 	l_tid = thread__tid(l->thread);
 	r_tid = thread__tid(r->thread);
@@ -1393,7 +1393,7 @@ static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
 		return -1;
 	if (l_tid > r_tid)
 		return 1;
-	return (int)(l->thread - r->thread);
+	return (int)(RC_CHK_ACCESS(l->thread) - RC_CHK_ACCESS(r->thread));
 }
 
 static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
diff --git a/tools/perf/tests/hists_link.c b/tools/perf/tests/hists_link.c
index 12bad8840699..2d19657ab5e0 100644
--- a/tools/perf/tests/hists_link.c
+++ b/tools/perf/tests/hists_link.c
@@ -148,7 +148,7 @@ static int find_sample(struct sample *samples, size_t nr_samples,
 		       struct thread *t, struct map *m, struct symbol *s)
 {
 	while (nr_samples--) {
-		if (samples->thread == t &&
+		if (RC_CHK_ACCESS(samples->thread) == RC_CHK_ACCESS(t) &&
 		    RC_CHK_ACCESS(samples->map) == RC_CHK_ACCESS(m) &&
 		    samples->sym == s)
 			return 1;
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index f164bd26fc41..2bf959d08354 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -11,6 +11,7 @@
 #include "../util/sort.h"
 #include "../util/evsel.h"
 #include "../util/evlist.h"
+#include "../util/thread.h"
 #include "../util/util.h"
 
 /* hist period print (hpp) functions */
@@ -274,7 +275,9 @@ static int __hpp__sort_acc(struct hist_entry *a, struct hist_entry *b,
 		if (ret)
 			return ret;
 
-		if (a->thread != b->thread || !hist_entry__has_callchains(a) || !symbol_conf.use_callchain)
+		if ((a->thread == NULL ? NULL : RC_CHK_ACCESS(a->thread)) !=
+		    (b->thread == NULL ? NULL : RC_CHK_ACCESS(b->thread)) ||
+		    !hist_entry__has_callchains(a) || !symbol_conf.use_callchain)
 			return 0;
 
 		ret = b->callchain->max_depth - a->callchain->max_depth;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index a4c1b617f6e4..dfda52d348a3 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -2124,7 +2124,7 @@ static bool hists__filter_entry_by_thread(struct hists *hists,
 					  struct hist_entry *he)
 {
 	if (hists->thread_filter != NULL &&
-	    he->thread != hists->thread_filter) {
+	    RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(hists->thread_filter)) {
 		he->filtered |= (1 << HIST_FILTER__THREAD);
 		return true;
 	}
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 9fcf357a4d53..261188766307 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2055,7 +2055,7 @@ static void __machine__remove_thread(struct machine *machine, struct thread_rb_n
 	if (!nd)
 		nd = thread_rb_node__find(th, &threads->entries.rb_root);
 
-	if (threads->last_match == th)
+	if (threads->last_match && RC_CHK_ACCESS(threads->last_match) == RC_CHK_ACCESS(th))
 		threads__set_last_match(threads, NULL);
 
 	if (lock)
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5e45c770f91d..047c3606802f 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -128,7 +128,7 @@ static int hist_entry__thread_filter(struct hist_entry *he, int type, const void
 	if (type != HIST_FILTER__THREAD)
 		return -1;
 
-	return th && he->thread != th;
+	return th && RC_CHK_ACCESS(he->thread) != RC_CHK_ACCESS(th);
 }
 
 struct sort_entry sort_thread = {
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index bee4ac1051ee..0b166404c5c3 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -41,9 +41,10 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 {
 	char *comm_str;
 	struct comm *comm;
-	struct thread *thread = zalloc(sizeof(*thread));
+	RC_STRUCT(thread) *_thread = zalloc(sizeof(*_thread));
+	struct thread *thread;
 
-	if (thread != NULL) {
+	if (ADD_RC_CHK(thread, _thread) != NULL) {
 		thread__set_pid(thread, pid);
 		thread__set_tid(thread, tid);
 		thread__set_ppid(thread, -1);
@@ -68,7 +69,7 @@ struct thread *thread__new(pid_t pid, pid_t tid)
 		list_add(&comm->list, thread__comm_list(thread));
 		refcount_set(thread__refcnt(thread), 1);
 		/* Thread holds first ref to nsdata. */
-		thread->nsinfo = nsinfo__new(pid);
+		RC_CHK_ACCESS(thread)->nsinfo = nsinfo__new(pid);
 		srccode_state_init(thread__srccode_state(thread));
 	}
 
@@ -105,26 +106,31 @@ void thread__delete(struct thread *thread)
 	}
 	up_write(thread__comm_lock(thread));
 
-	nsinfo__zput(thread->nsinfo);
+	nsinfo__zput(RC_CHK_ACCESS(thread)->nsinfo);
 	srccode_state_free(thread__srccode_state(thread));
 
 	exit_rwsem(thread__namespaces_lock(thread));
 	exit_rwsem(thread__comm_lock(thread));
 	thread__free_stitch_list(thread);
-	free(thread);
+	RC_CHK_FREE(thread);
 }
 
 struct thread *thread__get(struct thread *thread)
 {
-	if (thread)
+	struct thread *result;
+
+	if (RC_CHK_GET(result, thread))
 		refcount_inc(thread__refcnt(thread));
-	return thread;
+
+	return result;
 }
 
 void thread__put(struct thread *thread)
 {
 	if (thread && refcount_dec_and_test(thread__refcnt(thread)))
 		thread__delete(thread);
+	else
+		RC_CHK_PUT(thread);
 }
 
 static struct namespaces *__thread__namespaces(struct thread *thread)
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index b103992c3831..9068a21ce0fa 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -15,6 +15,7 @@
 #include "rwsem.h"
 #include "event.h"
 #include "callchain.h"
+#include <internal/rc_check.h>
 
 struct addr_location;
 struct map;
@@ -34,7 +35,7 @@ struct thread_rb_node {
 	struct thread *thread;
 };
 
-struct thread {
+DECLARE_RC_STRUCT(thread) {
 	struct maps		*maps;
 	pid_t			pid_; /* Not all tools update this */
 	pid_t			tid;
@@ -123,192 +124,192 @@ int thread__memcpy(struct thread *thread, struct machine *machine,
 
 static inline struct maps *thread__maps(struct thread *thread)
 {
-	return thread->maps;
+	return RC_CHK_ACCESS(thread)->maps;
 }
 
 static inline void thread__set_maps(struct thread *thread, struct maps *maps)
 {
-	thread->maps = maps;
+	RC_CHK_ACCESS(thread)->maps = maps;
 }
 
 static inline pid_t thread__pid(const struct thread *thread)
 {
-	return thread->pid_;
+	return RC_CHK_ACCESS(thread)->pid_;
 }
 
 static inline void thread__set_pid(struct thread *thread, pid_t pid_)
 {
-	thread->pid_ = pid_;
+	RC_CHK_ACCESS(thread)->pid_ = pid_;
 }
 
 static inline pid_t thread__tid(const struct thread *thread)
 {
-	return thread->tid;
+	return RC_CHK_ACCESS(thread)->tid;
 }
 
 static inline void thread__set_tid(struct thread *thread, pid_t tid)
 {
-	thread->tid = tid;
+	RC_CHK_ACCESS(thread)->tid = tid;
 }
 
 static inline pid_t thread__ppid(const struct thread *thread)
 {
-	return thread->ppid;
+	return RC_CHK_ACCESS(thread)->ppid;
 }
 
 static inline void thread__set_ppid(struct thread *thread, pid_t ppid)
 {
-	thread->ppid = ppid;
+	RC_CHK_ACCESS(thread)->ppid = ppid;
 }
 
 static inline int thread__cpu(const struct thread *thread)
 {
-	return thread->cpu;
+	return RC_CHK_ACCESS(thread)->cpu;
 }
 
 static inline void thread__set_cpu(struct thread *thread, int cpu)
 {
-	thread->cpu = cpu;
+	RC_CHK_ACCESS(thread)->cpu = cpu;
 }
 
 static inline int thread__guest_cpu(const struct thread *thread)
 {
-	return thread->guest_cpu;
+	return RC_CHK_ACCESS(thread)->guest_cpu;
 }
 
 static inline void thread__set_guest_cpu(struct thread *thread, int guest_cpu)
 {
-	thread->guest_cpu = guest_cpu;
+	RC_CHK_ACCESS(thread)->guest_cpu = guest_cpu;
 }
 
 static inline refcount_t *thread__refcnt(struct thread *thread)
 {
-	return &thread->refcnt;
+	return &RC_CHK_ACCESS(thread)->refcnt;
 }
 
 static inline bool thread__comm_set(const struct thread *thread)
 {
-	return thread->comm_set;
+	return RC_CHK_ACCESS(thread)->comm_set;
 }
 
 static inline void thread__set_comm_set(struct thread *thread, bool set)
 {
-	thread->comm_set = set;
+	RC_CHK_ACCESS(thread)->comm_set = set;
 }
 
 static inline int thread__var_comm_len(const struct thread *thread)
 {
-	return thread->comm_len;
+	return RC_CHK_ACCESS(thread)->comm_len;
 }
 
 static inline void thread__set_comm_len(struct thread *thread, int len)
 {
-	thread->comm_len = len;
+	RC_CHK_ACCESS(thread)->comm_len = len;
 }
 
 static inline struct list_head *thread__namespaces_list(struct thread *thread)
 {
-	return &thread->namespaces_list;
+	return &RC_CHK_ACCESS(thread)->namespaces_list;
 }
 
 static inline int thread__namespaces_list_empty(const struct thread *thread)
 {
-	return list_empty(&thread->namespaces_list);
+	return list_empty(&RC_CHK_ACCESS(thread)->namespaces_list);
 }
 
 static inline struct rw_semaphore *thread__namespaces_lock(struct thread *thread)
 {
-	return &thread->namespaces_lock;
+	return &RC_CHK_ACCESS(thread)->namespaces_lock;
 }
 
 static inline struct list_head *thread__comm_list(struct thread *thread)
 {
-	return &thread->comm_list;
+	return &RC_CHK_ACCESS(thread)->comm_list;
 }
 
 static inline struct rw_semaphore *thread__comm_lock(struct thread *thread)
 {
-	return &thread->comm_lock;
+	return &RC_CHK_ACCESS(thread)->comm_lock;
 }
 
 static inline u64 thread__db_id(const struct thread *thread)
 {
-	return thread->db_id;
+	return RC_CHK_ACCESS(thread)->db_id;
 }
 
 static inline void thread__set_db_id(struct thread *thread, u64 db_id)
 {
-	thread->db_id = db_id;
+	RC_CHK_ACCESS(thread)->db_id = db_id;
 }
 
 static inline void *thread__priv(struct thread *thread)
 {
-	return thread->priv;
+	return RC_CHK_ACCESS(thread)->priv;
 }
 
 static inline void thread__set_priv(struct thread *thread, void *p)
 {
-	thread->priv = p;
+	RC_CHK_ACCESS(thread)->priv = p;
 }
 
 static inline struct thread_stack *thread__ts(struct thread *thread)
 {
-	return thread->ts;
+	return RC_CHK_ACCESS(thread)->ts;
 }
 
 static inline void thread__set_ts(struct thread *thread, struct thread_stack *ts)
 {
-	thread->ts = ts;
+	RC_CHK_ACCESS(thread)->ts = ts;
 }
 
 static inline struct nsinfo *thread__nsinfo(struct thread *thread)
 {
-	return thread->nsinfo;
+	return RC_CHK_ACCESS(thread)->nsinfo;
 }
 
 static inline struct srccode_state *thread__srccode_state(struct thread *thread)
 {
-	return &thread->srccode_state;
+	return &RC_CHK_ACCESS(thread)->srccode_state;
 }
 
 static inline bool thread__filter(const struct thread *thread)
 {
-	return thread->filter;
+	return RC_CHK_ACCESS(thread)->filter;
 }
 
 static inline void thread__set_filter(struct thread *thread, bool filter)
 {
-	thread->filter = filter;
+	RC_CHK_ACCESS(thread)->filter = filter;
 }
 
 static inline int thread__filter_entry_depth(const struct thread *thread)
 {
-	return thread->filter_entry_depth;
+	return RC_CHK_ACCESS(thread)->filter_entry_depth;
 }
 
 static inline void thread__set_filter_entry_depth(struct thread *thread, int depth)
 {
-	thread->filter_entry_depth = depth;
+	RC_CHK_ACCESS(thread)->filter_entry_depth = depth;
 }
 
 static inline bool thread__lbr_stitch_enable(const struct thread *thread)
 {
-	return thread->lbr_stitch_enable;
+	return RC_CHK_ACCESS(thread)->lbr_stitch_enable;
 }
 
 static inline void thread__set_lbr_stitch_enable(struct thread *thread, bool en)
 {
-	thread->lbr_stitch_enable = en;
+	RC_CHK_ACCESS(thread)->lbr_stitch_enable = en;
 }
 
 static inline struct lbr_stitch	*thread__lbr_stitch(struct thread *thread)
 {
-	return thread->lbr_stitch;
+	return RC_CHK_ACCESS(thread)->lbr_stitch;
 }
 
 static inline void thread__set_lbr_stitch(struct thread *thread, struct lbr_stitch *lbrs)
 {
-	thread->lbr_stitch = lbrs;
+	RC_CHK_ACCESS(thread)->lbr_stitch = lbrs;
 }
 
 static inline bool thread__is_filtered(struct thread *thread)
-- 
2.41.0.162.gfafddb0af9-goog


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  parent reply	other threads:[~2023-06-08 23:30 UTC|newest]

Thread overview: 80+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-06-08 23:27 [PATCH v2 00/26] Fix memory leaks (was reference count checking for thread) Ian Rogers
2023-06-08 23:27 ` Ian Rogers
2023-06-08 23:27 ` [PATCH v2 01/26] perf thread: Remove notion of dead threads Ian Rogers
2023-06-08 23:27   ` Ian Rogers
2023-06-08 23:27 ` [PATCH v2 02/26] perf thread: Make threads rbtree non-invasive Ian Rogers
2023-06-08 23:27   ` Ian Rogers
2023-06-09 14:13   ` Arnaldo Carvalho de Melo
2023-06-09 14:13     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` [PATCH v2 03/26] perf thread: Add accessor functions for thread Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-09 14:15   ` Arnaldo Carvalho de Melo
2023-06-09 14:15     ` Arnaldo Carvalho de Melo
2023-06-09 14:50   ` Arnaldo Carvalho de Melo
2023-06-09 14:50     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` [PATCH v2 04/26] perf maps: Make delete static, always use put Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-09 14:17   ` Arnaldo Carvalho de Melo
2023-06-09 14:17     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` [PATCH v2 05/26] perf addr_location: Move to its own header Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-09 14:18   ` Arnaldo Carvalho de Melo
2023-06-09 14:18     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` [PATCH v2 06/26] perf addr_location: Add init/exit/copy functions Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-09 19:48   ` Arnaldo Carvalho de Melo
2023-06-09 19:48     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` Ian Rogers [this message]
2023-06-08 23:28   ` [PATCH v2 07/26] perf thread: Add reference count checking Ian Rogers
2023-06-08 23:28 ` [PATCH v2 08/26] perf machine: Make delete_threads part of machine__exit Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 09/26] perf report: Avoid thread leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 10/26] perf header: Ensure bitmaps are freed Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 11/26] perf stat: Avoid evlist leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 12/26] perf intel-pt: Fix missed put and leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 13/26] perf evlist: Free stats in all evlist destruction Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 14/26] perf python: Avoid 2 leak sanitizer issues Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 15/26] perf jit: Fix two thread leaks Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 16/26] perf symbol-elf: Correct holding a reference Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 17/26] perf maps: Fix overlapping memory leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 18/26] perf machine: Fix leak of kernel dso Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 19/26] perf machine: Don't leak module maps Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 20/26] perf map/maps/thread: Changes to reference counting Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 21/26] perf annotate: Fix parse_objdump_line memory leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 22/26] perf top: Add exit routine for main thread Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 23/26] perf header: Avoid out-of-bounds read Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 24/26] perf callchain: Use pthread keys for tls callchain_cursor Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-09 19:49   ` Arnaldo Carvalho de Melo
2023-06-09 19:49     ` Arnaldo Carvalho de Melo
2023-06-08 23:28 ` [PATCH v2 25/26] perf srcline: Change free_srcline to zfree_srcline Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-08 23:28 ` [PATCH v2 26/26] perf hist: Fix srcline memory leak Ian Rogers
2023-06-08 23:28   ` Ian Rogers
2023-06-12 14:13   ` Arnaldo Carvalho de Melo
2023-06-12 14:13     ` Arnaldo Carvalho de Melo
2023-06-12 14:16     ` Arnaldo Carvalho de Melo
2023-06-12 14:16       ` Arnaldo Carvalho de Melo
2023-06-12 14:46       ` Ian Rogers
2023-06-12 14:46         ` Ian Rogers
2023-06-12 17:23         ` Arnaldo Carvalho de Melo
2023-06-12 17:23           ` Arnaldo Carvalho de Melo
2023-06-12 21:16           ` Andi Kleen
2023-06-12 21:16             ` Andi Kleen
2023-06-12 21:30             ` Arnaldo Carvalho de Melo
2023-06-12 21:30               ` Arnaldo Carvalho de Melo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230608232823.4027869-8-irogers@google.com \
    --to=irogers@google.com \
    --cc=9erthalion6@gmail.com \
    --cc=acme@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=ak@linux.intel.com \
    --cc=alexander.shishkin@linux.intel.com \
    --cc=alisaidi@amazon.com \
    --cc=atrajeev@linux.vnet.ibm.com \
    --cc=brianrob@linux.microsoft.com \
    --cc=changbin.du@huawei.com \
    --cc=coresight@lists.linaro.org \
    --cc=german.gomez@arm.com \
    --cc=ivan@cloudflare.com \
    --cc=james.clark@arm.com \
    --cc=john.g.garry@oracle.com \
    --cc=jolsa@kernel.org \
    --cc=kan.liang@linux.intel.com \
    --cc=kprateek.nayak@amd.com \
    --cc=leo.yan@linaro.org \
    --cc=liam.howlett@oracle.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=liuwenyu7@huawei.com \
    --cc=mark.rutland@arm.com \
    --cc=maskray@google.com \
    --cc=mike.leach@linaro.org \
    --cc=mingo@redhat.com \
    --cc=namhyung@kernel.org \
    --cc=naveen.n.rao@linux.vnet.ibm.com \
    --cc=ojeda@kernel.org \
    --cc=peterz@infradead.org \
    --cc=ravi.bangoria@amd.com \
    --cc=renyu.zj@linux.alibaba.com \
    --cc=seanjc@google.com \
    --cc=sesse@google.com \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    --cc=yangjihong1@huawei.com \
    --cc=ye.xingchen@zte.com.cn \
    --cc=yuancan@huawei.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.