Messages in this thread | | | Date | Mon, 6 Nov 2023 13:28:43 +0200 | Subject | Re: [PATCH v4 05/53] perf machine thread: Remove exited threads by default | From | Adrian Hunter <> |
| |
On 2/11/23 19:56, Ian Rogers wrote: > 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 > symbol_conf value 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 40826c45eb0b ("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. > > Signed-off-by: Ian Rogers <irogers@google.com>
For auxtrace:
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
> --- > tools/perf/builtin-report.c | 7 +++++++ > tools/perf/util/machine.c | 10 +++++++--- > tools/perf/util/session.c | 5 +++++ > tools/perf/util/symbol_conf.h | 3 ++- > tools/perf/util/thread.h | 14 ++++++++++++++ > 5 files changed, 35 insertions(+), 4 deletions(-) > > diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c > index 9cb1da2dc0c0..121a2781323c 100644 > --- a/tools/perf/builtin-report.c > +++ b/tools/perf/builtin-report.c > @@ -1426,6 +1426,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 90c750150b19..a985d004aa8d 100644 > --- a/tools/perf/util/machine.c > +++ b/tools/perf/util/machine.c > @@ -2157,9 +2157,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 1e9aa8ed15b6..c6afba7ab1a5 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 2b2fb9e224b0..6040286e07a6 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 e79225a0ea46..0df775b5c110 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;
| |