All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Rogers <irogers@google.com>
To: acme@kernel.org, namhyung@kernel.org
Cc: irogers@google.com, agordeev@linux.ibm.com, gor@linux.ibm.com,
	 hca@linux.ibm.com, jameshongleiwang@126.com, japo@linux.ibm.com,
	 linux-kernel@vger.kernel.org, linux-perf-users@vger.kernel.org,
	 linux-s390@vger.kernel.org, sumanthk@linux.ibm.com,
	tmricht@linux.ibm.com
Subject: [PATCH v5 3/3] perf symbol: Lazily compute idle and use the perf_env
Date: Mon,  6 Apr 2026 10:09:05 -0700	[thread overview]
Message-ID: <20260406170905.2614260-4-irogers@google.com> (raw)
In-Reply-To: <20260406170905.2614260-1-irogers@google.com>

Move the idle boolean to a helper symbol__is_idle function. In the
function lazily compute whether a symbol is an idle function taking
into consideration the kernel version and architecture of the
machine. As symbols__insert no longer needs to know if a symbol is for
the kernel, remove the argument.

This change is inspired by mailing list discussion, particularly from
Thomas Richter <tmricht@linux.ibm.com> and Heiko Carstens
<hca@linux.ibm.com>:
https://lore.kernel.org/lkml/20260219113850.354271-1-tmricht@linux.ibm.com/

The change switches x86 matches to use strstarts which means
intel_idle_irq is matched as part of strstarts(name, "intel_idle"), a
change suggested by Honglei Wang <jameshongleiwang@126.com> in:
https://lore.kernel.org/lkml/20260323085255.98173-1-jameshongleiwang@126.com/

Signed-off-by: Ian Rogers <irogers@google.com>
---
 tools/perf/builtin-top.c     |   6 +-
 tools/perf/util/symbol-elf.c |   2 +-
 tools/perf/util/symbol.c     | 103 ++++++++++++++++++++++-------------
 tools/perf/util/symbol.h     |  15 +++--
 4 files changed, 82 insertions(+), 44 deletions(-)

diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 37950efb28ac..bdc1c761cd61 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -751,6 +751,7 @@ static void perf_event__process_sample(const struct perf_tool *tool,
 {
 	struct perf_top *top = container_of(tool, struct perf_top, tool);
 	struct addr_location al;
+	struct dso *dso = NULL;
 
 	if (!machine && perf_guest) {
 		static struct intlist *seen;
@@ -830,7 +831,10 @@ static void perf_event__process_sample(const struct perf_tool *tool,
 		}
 	}
 
-	if (al.sym == NULL || !al.sym->idle) {
+	if (al.map)
+		dso = map__dso(al.map);
+
+	if (al.sym == NULL || !symbol__is_idle(al.sym, dso, machine->env)) {
 		struct hists *hists = evsel__hists(evsel);
 		struct hist_entry_iter iter = {
 			.evsel		= evsel,
diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c
index 7afa8a117139..e8f7fe3f19fc 100644
--- a/tools/perf/util/symbol-elf.c
+++ b/tools/perf/util/symbol-elf.c
@@ -1727,7 +1727,7 @@ dso__load_sym_internal(struct dso *dso, struct map *map, struct symsrc *syms_ss,
 
 		arch__sym_update(f, &sym);
 
-		__symbols__insert(dso__symbols(curr_dso), f, dso__kernel(dso));
+		__symbols__insert(dso__symbols(curr_dso), f);
 		nr++;
 	}
 	dso__put(curr_dso);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index ea7d2f2dbcb7..8c23802b39ad 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -25,6 +25,8 @@
 #include "demangle-ocaml.h"
 #include "demangle-rust-v0.h"
 #include "dso.h"
+#include "dwarf-regs.h"
+#include "env.h"
 #include "util.h" // lsdir()
 #include "event.h"
 #include "machine.h"
@@ -50,7 +52,6 @@
 
 static int dso__load_kernel_sym(struct dso *dso, struct map *map);
 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map);
-static bool symbol__is_idle(const char *name);
 
 int vmlinux_path__nr_entries;
 char **vmlinux_path;
@@ -357,8 +358,7 @@ void symbols__delete(struct rb_root_cached *symbols)
 	}
 }
 
-void __symbols__insert(struct rb_root_cached *symbols,
-		       struct symbol *sym, bool kernel)
+void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym)
 {
 	struct rb_node **p = &symbols->rb_root.rb_node;
 	struct rb_node *parent = NULL;
@@ -366,17 +366,6 @@ void __symbols__insert(struct rb_root_cached *symbols,
 	struct symbol *s;
 	bool leftmost = true;
 
-	if (kernel) {
-		const char *name = sym->name;
-		/*
-		 * ppc64 uses function descriptors and appends a '.' to the
-		 * start of every instruction address. Remove it.
-		 */
-		if (name[0] == '.')
-			name++;
-		sym->idle = symbol__is_idle(name);
-	}
-
 	while (*p != NULL) {
 		parent = *p;
 		s = rb_entry(parent, struct symbol, rb_node);
@@ -393,7 +382,7 @@ void __symbols__insert(struct rb_root_cached *symbols,
 
 void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym)
 {
-	__symbols__insert(symbols, sym, false);
+	__symbols__insert(symbols, sym);
 }
 
 static struct symbol *symbols__find(struct rb_root_cached *symbols, u64 ip)
@@ -554,7 +543,7 @@ void dso__reset_find_symbol_cache(struct dso *dso)
 
 void dso__insert_symbol(struct dso *dso, struct symbol *sym)
 {
-	__symbols__insert(dso__symbols(dso), sym, dso__kernel(dso));
+	__symbols__insert(dso__symbols(dso), sym);
 
 	/* update the symbol cache if necessary */
 	if (dso__last_find_result_addr(dso) >= sym->start &&
@@ -716,47 +705,85 @@ int modules__parse(const char *filename, void *arg,
 	return err;
 }
 
+static int sym_name_cmp(const void *a, const void *b)
+{
+	const char *name = a;
+	const char *const *sym = b;
+
+	return strcmp(name, *sym);
+}
+
 /*
  * These are symbols in the kernel image, so make sure that
  * sym is from a kernel DSO.
  */
-static bool symbol__is_idle(const char *name)
+bool symbol__is_idle(struct symbol *sym, const struct dso *dso, struct perf_env *env)
 {
-	const char * const idle_symbols[] = {
+	static const char * const idle_symbols[] = {
 		"acpi_idle_do_entry",
 		"acpi_processor_ffh_cstate_enter",
 		"arch_cpu_idle",
 		"cpu_idle",
 		"cpu_startup_entry",
-		"idle_cpu",
-		"intel_idle",
-		"intel_idle_ibrs",
 		"default_idle",
-		"native_safe_halt",
 		"enter_idle",
 		"exit_idle",
-		"mwait_idle",
-		"mwait_idle_with_hints",
-		"mwait_idle_with_hints.constprop.0",
+		"idle_cpu",
+		"native_safe_halt",
 		"poll_idle",
-		"ppc64_runlatch_off",
 		"pseries_dedicated_idle_sleep",
-		"psw_idle",
-		"psw_idle_exit",
-		NULL
 	};
-	int i;
-	static struct strlist *idle_symbols_list;
+	const char *name = sym->name;
+	uint16_t e_machine = perf_env__e_machine(env, /*e_flags=*/NULL);
+
+	if (sym->idle)
+		return sym->idle == SYMBOL_IDLE__IDLE;
+
+	if (!dso || dso__kernel(dso) == DSO_SPACE__USER) {
+		sym->idle = SYMBOL_IDLE__NOT_IDLE;
+		return false;
+	}
 
-	if (idle_symbols_list)
-		return strlist__has_entry(idle_symbols_list, name);
+	/*
+	 * ppc64 uses function descriptors and appends a '.' to the
+	 * start of every instruction address. Remove it.
+	 */
+	if (name[0] == '.')
+		name++;
 
-	idle_symbols_list = strlist__new(NULL, NULL);
+	if (bsearch(name, idle_symbols, ARRAY_SIZE(idle_symbols),
+		    sizeof(idle_symbols[0]), sym_name_cmp)) {
+		sym->idle = SYMBOL_IDLE__IDLE;
+		return true;
+	}
 
-	for (i = 0; idle_symbols[i]; i++)
-		strlist__add(idle_symbols_list, idle_symbols[i]);
+	if (e_machine == EM_386 || e_machine == EM_X86_64) {
+		if (strstarts(name, "mwait_idle") ||
+		    strstarts(name, "intel_idle")) {
+			sym->idle = SYMBOL_IDLE__IDLE;
+			return true;
+		}
+	}
 
-	return strlist__has_entry(idle_symbols_list, name);
+	if (e_machine == EM_PPC64 && !strcmp(name, "ppc64_runlatch_off")) {
+		sym->idle = SYMBOL_IDLE__IDLE;
+		return true;
+	}
+
+	if (e_machine == EM_S390 && strstarts(name, "psw_idle")) {
+		int major = 0, minor = 0;
+		const char *release = perf_env__os_release(env);
+
+		/* Before v6.10, s390 used psw_idle. */
+		if (sscanf(release, "%d.%d", &major, &minor) != 2 ||
+		    major < 6 || (major == 6 && minor < 10)) {
+			sym->idle = SYMBOL_IDLE__IDLE;
+			return true;
+		}
+	}
+
+	sym->idle = SYMBOL_IDLE__NOT_IDLE;
+	return false;
 }
 
 static int map__process_kallsym_symbol(void *arg, const char *name,
@@ -785,7 +812,7 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
 	 * We will pass the symbols to the filter later, in
 	 * map__split_kallsyms, when we have split the maps per module
 	 */
-	__symbols__insert(root, sym, !strchr(name, '['));
+	__symbols__insert(root, sym);
 
 	return 0;
 }
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index c67814d6d6d6..2f5f90f547aa 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -25,6 +25,7 @@ struct dso;
 struct map;
 struct maps;
 struct option;
+struct perf_env;
 struct build_id;
 
 /*
@@ -42,6 +43,12 @@ Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
 			     GElf_Shdr *shp, const char *name, size_t *idx);
 #endif
 
+enum symbol_idle_kind {
+	SYMBOL_IDLE__UNKNOWN = 0,
+	SYMBOL_IDLE__NOT_IDLE = 1,
+	SYMBOL_IDLE__IDLE = 2,
+};
+
 /**
  * A symtab entry. When allocated this may be preceded by an annotation (see
  * symbol__annotation) and/or a browser_index (see symbol__browser_index).
@@ -57,8 +64,8 @@ struct symbol {
 	u8		type:4;
 	/** ELF binding type as defined for st_info. E.g. STB_WEAK or STB_GLOBAL. */
 	u8		binding:4;
-	/** Set true for kernel symbols of idle routines. */
-	u8		idle:1;
+	/** Cache for symbol__is_idle holding enum symbol_idle_kind values. */
+	u8		idle:2;
 	/** Resolvable but tools ignore it (e.g. idle routines). */
 	u8		ignore:1;
 	/** Symbol for an inlined function. */
@@ -202,8 +209,7 @@ int dso__synthesize_plt_symbols(struct dso *dso, struct symsrc *ss);
 
 char *dso__demangle_sym(struct dso *dso, int kmodule, const char *elf_name);
 
-void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym,
-		       bool kernel);
+void __symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
 void symbols__insert(struct rb_root_cached *symbols, struct symbol *sym);
 void symbols__fixup_duplicate(struct rb_root_cached *symbols);
 void symbols__fixup_end(struct rb_root_cached *symbols, bool is_kallsyms);
@@ -286,5 +292,6 @@ enum {
 };
 
 int symbol__validate_sym_arguments(void);
+bool symbol__is_idle(struct symbol *sym, const struct dso *dso, struct perf_env *env);
 
 #endif /* __PERF_SYMBOL */
-- 
2.53.0.1213.gd9a14994de-goog


  parent reply	other threads:[~2026-04-06 17:09 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-19 11:38 [PATCH v2] perf symbol: Remove psw_idle() from list of idle symbols Thomas Richter
2026-02-19 11:55 ` Jan Polensky
2026-02-23 21:46 ` Namhyung Kim
2026-02-23 23:14   ` Arnaldo Melo
2026-03-02 18:43   ` Arnaldo Carvalho de Melo
2026-03-02 19:44     ` Ian Rogers
2026-03-04 14:34       ` Arnaldo Carvalho de Melo
2026-03-02 23:43 ` [PATCH v1] perf symbol: Lazily compute idle and use the perf_env Ian Rogers
2026-03-24 17:14   ` Ian Rogers
2026-03-25  6:58     ` Namhyung Kim
2026-03-25 15:58       ` Ian Rogers
2026-03-25 16:18   ` [PATCH v2] " Ian Rogers
2026-03-26  7:20     ` Honglei Wang
2026-03-26 15:11       ` Ian Rogers
2026-03-26 17:45         ` [PATCH v3 0/2] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-03-26 17:45           ` [PATCH v3 1/2] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-03-26 17:45           ` [PATCH v3 2/2] perf symbol: Lazily compute idle and use the perf_env Ian Rogers
2026-03-27  6:56             ` Honglei Wang
2026-03-27  4:50           ` [PATCH v4 0/2] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-03-27  4:50             ` [PATCH v4 1/2] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-04-06  5:05               ` Namhyung Kim
2026-04-06 15:36                 ` Ian Rogers
2026-03-27  4:50             ` [PATCH v4 2/2] perf symbol: Lazily compute idle and use the perf_env Ian Rogers
2026-04-06  5:10               ` Namhyung Kim
2026-04-06 16:11                 ` Ian Rogers
2026-04-06 17:09                   ` [PATCH v5 0/3] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-04-06 17:09                     ` [PATCH v5 1/3] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-04-06 17:09                     ` [PATCH v5 2/3] perf env: Add helper to lazily compute the os_release Ian Rogers
2026-04-06 17:09                     ` Ian Rogers [this message]
2026-04-09 23:06                     ` [PATCH v6 0/3] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-04-09 23:06                       ` [PATCH v6 1/3] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-04-09 23:37                         ` sashiko-bot
2026-05-01 18:20                         ` [PATCH v7 0/4] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-05-01 18:20                           ` [PATCH v7 1/4] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-05-01 18:56                             ` sashiko-bot
2026-05-01 18:20                           ` [PATCH v7 2/4] perf env: Add helper to lazily compute the os_release Ian Rogers
2026-05-01 19:20                             ` sashiko-bot
2026-05-01 18:20                           ` [PATCH v7 3/4] perf symbol: Add setters for bitfields sharing a byte to avoid concurrent update issues Ian Rogers
2026-05-01 19:42                             ` sashiko-bot
2026-05-01 18:20                           ` [PATCH v7 4/4] perf symbol: Lazily compute idle and use a global lock for updates Ian Rogers
2026-05-01 20:13                             ` sashiko-bot
2026-05-02  6:59                         ` [PATCH v8 00/17] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 01/17] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-05-02  7:56                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 02/17] perf tests topology: Switch env->arch use to env->e_machine Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 03/17] perf capstone: Determine architecture from e_machine Ian Rogers
2026-05-02  7:58                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 04/17] perf print_insn: Use e_machine for fallback IP length check Ian Rogers
2026-05-02  7:55                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 05/17] perf machine: Use perf_env e_machine rather than arch Ian Rogers
2026-05-02  7:11                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 06/17] perf sample-raw: " Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 07/17] perf sort: " Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 08/17] perf symbol: Avoid use of machine__is Ian Rogers
2026-05-02  7:17                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 09/17] perf arch common: Use perf_env e_machine rather than arch Ian Rogers
2026-05-02  7:59                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 10/17] perf header: In print_pmu_caps use perf_env e_machine Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 11/17] perf c2c: Use perf_env e_machine rather than arch Ian Rogers
2026-05-02  7:44                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 12/17] perf lock-contention: " Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 13/17] perf env: Refactor perf_env__arch_strerrno Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 14/17] perf env: Remove unused perf_env__raw_arch Ian Rogers
2026-05-02  6:59                           ` [PATCH v8 15/17] perf env: Add helper to lazily compute the os_release Ian Rogers
2026-05-02  7:53                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 16/17] perf symbol: Add setters for bitfields sharing a byte to avoid concurrent update issues Ian Rogers
2026-05-02  7:55                             ` sashiko-bot
2026-05-02  6:59                           ` [PATCH v8 17/17] perf symbol: Lazily compute idle and use a global lock for updates Ian Rogers
2026-05-03  0:22                           ` [PATCH v9 00/18] perf symbol/env: ELF machine clean up and lazy idle computation Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 01/18] perf env: Add perf_env__e_machine helper and use in perf_env__arch Ian Rogers
2026-05-03  0:52                               ` sashiko-bot
2026-05-04  1:35                               ` Namhyung Kim
2026-05-03  0:22                             ` [PATCH v9 02/18] perf tests topology: Switch env->arch use to env->e_machine Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 03/18] perf env, dso, thread: Add _endian variants for e_machine helpers Ian Rogers
2026-05-03  0:39                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 04/18] perf capstone: Determine architecture from e_machine Ian Rogers
2026-05-03  0:50                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 05/18] perf print_insn: Use e_machine for fallback IP length check Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 06/18] perf symbol: Avoid use of machine__is Ian Rogers
2026-05-03  0:51                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 07/18] perf machine: Use perf_env e_machine rather than arch Ian Rogers
2026-05-03  1:00                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 08/18] perf sample-raw: " Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 09/18] perf sort: " Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 10/18] perf arch common: " Ian Rogers
2026-05-03  0:38                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 11/18] perf header: In print_pmu_caps use perf_env e_machine Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 12/18] perf c2c: Use perf_env e_machine rather than arch Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 13/18] perf lock-contention: " Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 14/18] perf env: Refactor perf_env__arch_strerrno Ian Rogers
2026-05-03  1:11                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 15/18] perf env: Remove unused perf_env__raw_arch Ian Rogers
2026-05-03  0:22                             ` [PATCH v9 16/18] perf env: Add helper to lazily compute the os_release Ian Rogers
2026-05-03  1:00                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 17/18] perf symbol: Add setters for bitfields sharing a byte to avoid concurrent update issues Ian Rogers
2026-05-03  0:59                               ` sashiko-bot
2026-05-03  0:22                             ` [PATCH v9 18/18] perf symbol: Lazily compute idle Ian Rogers
2026-05-03  1:11                               ` sashiko-bot
2026-04-09 23:06                       ` [PATCH v6 2/3] perf env: Add helper to lazily compute the os_release Ian Rogers
2026-04-09 23:50                         ` sashiko-bot
2026-04-09 23:06                       ` [PATCH v6 3/3] perf symbol: Lazily compute idle and use the perf_env Ian Rogers
2026-04-10  0:11                         ` sashiko-bot
2026-03-27  6:00           ` [PATCH v2] perf tests task-analyzer: Write test files to tmpdir Ian Rogers
2026-03-31  7:22             ` Namhyung Kim
2026-03-31 17:58               ` Ian Rogers
2026-04-01  3:41                 ` Namhyung Kim

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=20260406170905.2614260-4-irogers@google.com \
    --to=irogers@google.com \
    --cc=acme@kernel.org \
    --cc=agordeev@linux.ibm.com \
    --cc=gor@linux.ibm.com \
    --cc=hca@linux.ibm.com \
    --cc=jameshongleiwang@126.com \
    --cc=japo@linux.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-s390@vger.kernel.org \
    --cc=namhyung@kernel.org \
    --cc=sumanthk@linux.ibm.com \
    --cc=tmricht@linux.ibm.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.