Patch "perf machine thread: Remove exited threads by default" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    perf machine thread: Remove exited threads by default

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     perf-machine-thread-remove-exited-threads-by-default.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit aa5943e4c689dd47af5ce3976c039907b9f0e193
Author: Ian Rogers <irogers@xxxxxxxxxx>
Date:   Thu Nov 2 10:56:47 2023 -0700

    perf machine thread: Remove exited threads by default
    
    [ Upstream commit 9ffa6c7512ca7aaeb30e596e2c247cb1fae7123a ]
    
    'struct thread' values hold onto references to mmaps, DSOs, etc. When a
    thread exits it is necessary to clean all of this memory up by removing
    the thread from the machine's threads. Some tools require this doesn't
    happen, such as auxtrace events, 'perf report' if offcpu events exist or
    if a task list is being generated, so add a 'struct symbol_conf' member
    to make the behavior optional. When an exited thread is left in the
    machine's threads, mark it as exited.
    
    This change relates to commit 40826c45eb0b8856 ("perf thread: Remove
    notion of dead threads") . Dead threads were removed as they had a
    reference count of 0 and were difficult to reason about with the
    reference count checker. Here a thread is removed from threads when it
    exits, unless via symbol_conf the exited thread isn't remove and is
    marked as exited. Reference counting behaves as it normally does.
    
    Reviewed-by: Adrian Hunter <adrian.hunter@xxxxxxxxx>
    Signed-off-by: Ian Rogers <irogers@xxxxxxxxxx>
    Cc: Alexander Shishkin <alexander.shishkin@xxxxxxxxxxxxxxx>
    Cc: Andi Kleen <ak@xxxxxxxxxxxxxxx>
    Cc: Athira Jajeev <atrajeev@xxxxxxxxxxxxxxxxxx>
    Cc: Changbin Du <changbin.du@xxxxxxxxxx>
    Cc: Colin Ian King <colin.i.king@xxxxxxxxx>
    Cc: Dmitrii Dolgov <9erthalion6@xxxxxxxxx>
    Cc: German Gomez <german.gomez@xxxxxxx>
    Cc: Huacai Chen <chenhuacai@xxxxxxxxxx>
    Cc: Ingo Molnar <mingo@xxxxxxxxxx>
    Cc: James Clark <james.clark@xxxxxxx>
    Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
    Cc: K Prateek Nayak <kprateek.nayak@xxxxxxx>
    Cc: Kajol Jain <kjain@xxxxxxxxxxxxx>
    Cc: Kan Liang <kan.liang@xxxxxxxxxxxxxxx>
    Cc: Leo Yan <leo.yan@xxxxxxxxxx>
    Cc: Li Dong <lidong@xxxxxxxx>
    Cc: Liam Howlett <liam.howlett@xxxxxxxxxx>
    Cc: Mark Rutland <mark.rutland@xxxxxxx>
    Cc: Masami Hiramatsu <mhiramat@xxxxxxxxxx>
    Cc: Miguel Ojeda <ojeda@xxxxxxxxxx>
    Cc: Ming Wang <wangming01@xxxxxxxxxxx>
    Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
    Cc: Nick Terrell <terrelln@xxxxxx>
    Cc: Paolo Bonzini <pbonzini@xxxxxxxxxx>
    Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
    Cc: Ravi Bangoria <ravi.bangoria@xxxxxxx>
    Cc: Sandipan Das <sandipan.das@xxxxxxx>
    Cc: Sean Christopherson <seanjc@xxxxxxxxxx>
    Cc: Steinar H. Gunderson <sesse@xxxxxxxxxx>
    Cc: Vincent Whitchurch <vincent.whitchurch@xxxxxxxx>
    Cc: Wenyu Liu <liuwenyu7@xxxxxxxxxx>
    Cc: Yang Jihong <yangjihong1@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20231102175735.2272696-6-irogers@xxxxxxxxxx
    Signed-off-by: Arnaldo Carvalho de Melo <acme@xxxxxxxxxx>
    Stable-dep-of: aaf494cf483a ("perf annotate: Fix annotation_calc_lines() to pass correct address to get_srcline()")
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index dcedfe00f04db..749246817aed3 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -1411,6 +1411,13 @@ int cmd_report(int argc, const char **argv)
 	if (ret < 0)
 		goto exit;
 
+	/*
+	 * tasks_mode require access to exited threads to list those that are in
+	 * the data file. Off-cpu events are synthesized after other events and
+	 * reference exited threads.
+	 */
+	symbol_conf.keep_exited_threads = true;
+
 	annotation_options__init(&report.annotation_opts);
 
 	ret = perf_config(report__config, &report);
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index e6a8d758f6fe4..7c6874804660e 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -2158,9 +2158,13 @@ int machine__process_exit_event(struct machine *machine, union perf_event *event
 	if (dump_trace)
 		perf_event__fprintf_task(event, stdout);
 
-	if (thread != NULL)
-		thread__put(thread);
-
+	if (thread != NULL) {
+		if (symbol_conf.keep_exited_threads)
+			thread__set_exited(thread, /*exited=*/true);
+		else
+			machine__remove_thread(machine, thread);
+	}
+	thread__put(thread);
 	return 0;
 }
 
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c
index 1e9aa8ed15b64..c6afba7ab1a51 100644
--- a/tools/perf/util/session.c
+++ b/tools/perf/util/session.c
@@ -115,6 +115,11 @@ static int perf_session__open(struct perf_session *session, int repipe_fd)
 		return -1;
 	}
 
+	if (perf_header__has_feat(&session->header, HEADER_AUXTRACE)) {
+		/* Auxiliary events may reference exited threads, hold onto dead ones. */
+		symbol_conf.keep_exited_threads = true;
+	}
+
 	if (perf_data__is_pipe(data))
 		return 0;
 
diff --git a/tools/perf/util/symbol_conf.h b/tools/perf/util/symbol_conf.h
index 2b2fb9e224b00..6040286e07a65 100644
--- a/tools/perf/util/symbol_conf.h
+++ b/tools/perf/util/symbol_conf.h
@@ -43,7 +43,8 @@ struct symbol_conf {
 			disable_add2line_warn,
 			buildid_mmap2,
 			guest_code,
-			lazy_load_kernel_maps;
+			lazy_load_kernel_maps,
+			keep_exited_threads;
 	const char	*vmlinux_name,
 			*kallsyms_name,
 			*source_prefix,
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index e79225a0ea46b..0df775b5c1105 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -36,13 +36,22 @@ struct thread_rb_node {
 };
 
 DECLARE_RC_STRUCT(thread) {
+	/** @maps: mmaps associated with this thread. */
 	struct maps		*maps;
 	pid_t			pid_; /* Not all tools update this */
+	/** @tid: thread ID number unique to a machine. */
 	pid_t			tid;
+	/** @ppid: parent process of the process this thread belongs to. */
 	pid_t			ppid;
 	int			cpu;
 	int			guest_cpu; /* For QEMU thread */
 	refcount_t		refcnt;
+	/**
+	 * @exited: Has the thread had an exit event. Such threads are usually
+	 * removed from the machine's threads but some events/tools require
+	 * access to dead threads.
+	 */
+	bool			exited;
 	bool			comm_set;
 	int			comm_len;
 	struct list_head	namespaces_list;
@@ -189,6 +198,11 @@ static inline refcount_t *thread__refcnt(struct thread *thread)
 	return &RC_CHK_ACCESS(thread)->refcnt;
 }
 
+static inline void thread__set_exited(struct thread *thread, bool exited)
+{
+	RC_CHK_ACCESS(thread)->exited = exited;
+}
+
 static inline bool thread__comm_set(const struct thread *thread)
 {
 	return RC_CHK_ACCESS(thread)->comm_set;




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux