Message ID | 20231102175735.2272696-6-irogers@google.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:8f47:0:b0:403:3b70:6f57 with SMTP id j7csp533204vqu; Thu, 2 Nov 2023 10:58:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGQrHUDu75BOiTxyiIYW04eVdBilPN7x7IRfPaVeqyU1OnFXKWJjut6g96M/j+Kz/w8hPC6 X-Received: by 2002:a17:90a:d994:b0:27d:669e:5a10 with SMTP id d20-20020a17090ad99400b0027d669e5a10mr15808731pjv.13.1698947934380; Thu, 02 Nov 2023 10:58:54 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1698947934; cv=none; d=google.com; s=arc-20160816; b=UQuAPtFCuOqg7bzZfV6CGTKpqi+9LmLoTkZYRiFyGMX4NgHb2wdSlW58pMgBvoWT4a r+6bzFQ/wlepFcBnUURpDEjyd+EmNjsrcEU36ieFFrYMECszMGOsnW6xOX/s9M+uVfWi Gkte6Ooiz2QAw5ug6rBF2EgHP3sgc/btVp3rlVd8QXo29pVqxzwGKYCYG7ifUhPhOwox dGDgDwvB5WhY1gHMkt9Z29iwEum9NLO/4g95I6R4xuekQ0IlazXnGVz4TlVtABxmdTqB 1SOyi1+uyY62J9mb1igaPV/gS9oLk0jtDAYBDgpZxktqo7sBnvJR+2qFSY+K76HrwRzV Qm6A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:from:subject:references:mime-version :message-id:in-reply-to:date:dkim-signature; bh=a6Vci0mC9udGUYdKEDx73CiSn3PyEtlzA+5ahyQMAZ4=; fh=z1KcSqUpYQ9oC4uLSeIkhAYTnJ2bvP0QbNW2xqV5NqA=; b=D4CDqv6ZbSE5kK8G5XfhMzMexhadLuur8hgKtdYctdUE0mBUEZg81ic7/ASP7ZKmWC xbhGWfMnYrA27gQJz6GJD0dS5vTvJ0yAdaYZGXslmSq5jRfEqT5UsUsEbBXSpn1lF3ZH Qo9r1r8M2P2dzQ4TMMod8mTz+HatAyJmzjwO+bHFltM7FPpPZMRlaSE1yKgZsZN+PLLC ZH1jC2GC9VfAsMOp3RaRDz8xYk21zfQol8RkdV4UN5Y0cFFTJPEdIVTEMUTG0V5Fviyf UnnZ91Z4wA1sFjMtPIy2Isb5nlGhZx8aSCX6ul6pwd9RKTuCXj9Yg2JuHcBkgIqMAznT dpfw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=qWsvgZeR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id nh23-20020a17090b365700b00279020d1fb0si87932pjb.129.2023.11.02.10.58.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 02 Nov 2023 10:58:54 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20230601 header.b=qWsvgZeR; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 8F255813566A; Thu, 2 Nov 2023 10:58:48 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345929AbjKBR61 (ORCPT <rfc822;heyuhang3455@gmail.com> + 35 others); Thu, 2 Nov 2023 13:58:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43696 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345416AbjKBR6P (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Thu, 2 Nov 2023 13:58:15 -0400 Received: from mail-yw1-x114a.google.com (mail-yw1-x114a.google.com [IPv6:2607:f8b0:4864:20::114a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 17222D41 for <linux-kernel@vger.kernel.org>; Thu, 2 Nov 2023 10:58:08 -0700 (PDT) Received: by mail-yw1-x114a.google.com with SMTP id 00721157ae682-5a9012ab0adso16607047b3.1 for <linux-kernel@vger.kernel.org>; Thu, 02 Nov 2023 10:58:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1698947887; x=1699552687; darn=vger.kernel.org; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :from:to:cc:subject:date:message-id:reply-to; bh=a6Vci0mC9udGUYdKEDx73CiSn3PyEtlzA+5ahyQMAZ4=; b=qWsvgZeRlRNWXJmobuMA8ozRIqJP5yfEypLT/BvgSn4T4NLhuMnAH1u1wCgCXM722X NMFw7a6XOMHAofd5D3VU2fCG27fU/cPn99EnI6O1svwyYtkknBWj8egFQ1ohOh3DBGLQ qDaZryoM4893mfcOThNNrx4R7/SlJ0cIwju7giWiIMBXCk8a+ldBX3/8lpDUz3F6l3qJ 1bLsVQ6A3csxVGnkJYvMak6oMYg4JQAd8PvUefJPv1aE90k6gBeMC8O/PfRoj1fKsYE4 UiWp6DBHczlVOeR+P1FVBikMv0NsYmWc61PlPbs3R7ZCG75fBJYHvxmoh8PO0lkARUKA bG3A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1698947887; x=1699552687; h=to:from:subject:references:mime-version:message-id:in-reply-to:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=a6Vci0mC9udGUYdKEDx73CiSn3PyEtlzA+5ahyQMAZ4=; b=t1QDKPT3H68FzMes6nUMo1MKayTtUywL9rtQODZVtQwJX5m03xiVox3wnglanSIKEe INlO37ZT2IxNP/iQordCgGQmKA/sH1fegKo35gVI+91EFXO6HDO/qMbUUULF90nk+o5K 9BJuEiaxYfdWx1gnWIAvNqBfEeWi8838Oh44wx9WUYqZGH3ivTuDxHZnjMsdSixVKgBi wbZBagKE19cETLn3rLChrzAVNhMFHZO34tDJ2SOfh0+ja+UHq2VWvfQglck0HZRmshJ9 ugxjT1BrlkCjayHatOLsRumaPoBvLi2HcDwkhY0UmoVgu3ySZ1c5BsN52ywZ84LkMmuA 1bUg== X-Gm-Message-State: AOJu0Yyhh6qazMrAdjWz2JXmt5oSmyxaK7Ei0lj6j01K9Rjabf+73v4t z6oFiAYJww3B3gOcb+a3Qa5VA54ze2uE X-Received: from irogers.svl.corp.google.com ([2620:15c:2a3:200:bb34:df9c:836c:afca]) (user=irogers job=sendgmr) by 2002:a81:4855:0:b0:592:83d2:1f86 with SMTP id v82-20020a814855000000b0059283d21f86mr8582ywa.4.1698947887136; Thu, 02 Nov 2023 10:58:07 -0700 (PDT) Date: Thu, 2 Nov 2023 10:56:47 -0700 In-Reply-To: <20231102175735.2272696-1-irogers@google.com> Message-Id: <20231102175735.2272696-6-irogers@google.com> Mime-Version: 1.0 References: <20231102175735.2272696-1-irogers@google.com> X-Mailer: git-send-email 2.42.0.869.gea05f2083d-goog Subject: [PATCH v4 05/53] perf machine thread: Remove exited threads by default From: Ian Rogers <irogers@google.com> To: 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>, Nick Terrell <terrelln@fb.com>, Kan Liang <kan.liang@linux.intel.com>, Andi Kleen <ak@linux.intel.com>, Kajol Jain <kjain@linux.ibm.com>, Athira Rajeev <atrajeev@linux.vnet.ibm.com>, Huacai Chen <chenhuacai@kernel.org>, Masami Hiramatsu <mhiramat@kernel.org>, Vincent Whitchurch <vincent.whitchurch@axis.com>, "Steinar H. Gunderson" <sesse@google.com>, Liam Howlett <liam.howlett@oracle.com>, Miguel Ojeda <ojeda@kernel.org>, Colin Ian King <colin.i.king@gmail.com>, Dmitrii Dolgov <9erthalion6@gmail.com>, Yang Jihong <yangjihong1@huawei.com>, Ming Wang <wangming01@loongson.cn>, James Clark <james.clark@arm.com>, K Prateek Nayak <kprateek.nayak@amd.com>, Sean Christopherson <seanjc@google.com>, Leo Yan <leo.yan@linaro.org>, Ravi Bangoria <ravi.bangoria@amd.com>, German Gomez <german.gomez@arm.com>, Changbin Du <changbin.du@huawei.com>, Paolo Bonzini <pbonzini@redhat.com>, Li Dong <lidong@vivo.com>, Sandipan Das <sandipan.das@amd.com>, liuwenyu <liuwenyu7@huawei.com>, linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org Content-Type: text/plain; charset="UTF-8" X-Spam-Status: No, score=-8.4 required=5.0 tests=DKIMWL_WL_MED,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE, USER_IN_DEF_DKIM_WL autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Thu, 02 Nov 2023 10:58:48 -0700 (PDT) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1781476029090615440 X-GMAIL-MSGID: 1781476029090615440 |
Series |
Improvements to memory use
|
|
Commit Message
Ian Rogers
Nov. 2, 2023, 5:56 p.m. UTC
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>
---
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(-)
Comments
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;
Em Mon, Nov 06, 2023 at 01:28:43PM +0200, Adrian Hunter escreveu: > 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> Thanks, applied to perf-tools-next. - Arnaldo
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;