[PATCH 06/19] perf symbol: Add optimization for idle kernel symbols

From: David Ahern
Date: Wed Aug 07 2013 - 22:51:31 EST


Avoid walking the list of idle symbols more than once by setting a
flag in the symbol struct.

Signed-off-by: David Ahern <dsahern@xxxxxxxxx>
Cc: Ingo Molnar <mingo@xxxxxxxxxx>
Cc: Jiri Olsa <jolsa@xxxxxxxxxx>
Cc: Namhyung Kim <namhyung@xxxxxxxxxx>
Cc: Frederic Weisbecker <fweisbec@xxxxxxxxx>
Cc: Peter Zijlstra <peterz@xxxxxxxxxxxxx>
Cc: Stephane Eranian <eranian@xxxxxxxxxx>
---
tools/perf/util/symbol.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
tools/perf/util/symbol.h | 5 ++++-
2 files changed, 48 insertions(+), 1 deletion(-)

diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 77f3b95..c655b9e 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -509,6 +509,46 @@ static u8 kallsyms2elf_type(char type)
return isupper(type) ? STB_GLOBAL : STB_LOCAL;
}

+static bool is_idle_sym(const char *name)
+{
+ static const char * const idle_symbols[] = {
+ "cpu_idle",
+ "intel_idle",
+ "default_idle",
+ "native_safe_halt",
+ "enter_idle",
+ "exit_idle",
+ "mwait_idle",
+ "mwait_idle_with_hints",
+ "poll_idle",
+ "ppc64_runlatch_off",
+ "pseries_dedicated_idle_sleep",
+ NULL
+ };
+
+ int i;
+
+ for (i = 0; idle_symbols[i]; i++) {
+ if (!strcmp(idle_symbols[i], name))
+ return true;
+ }
+
+ return false;
+}
+
+bool symbol__is_idle(struct symbol *sym)
+{
+ if (!sym)
+ return false;
+
+ if (!sym->idle_checked) {
+ sym->is_idle = is_idle_sym(sym->name);
+ sym->idle_checked = true;
+ }
+
+ return sym->is_idle;
+}
+
static int map__process_kallsym_symbol(void *arg, const char *name,
char type, u64 start)
{
@@ -527,6 +567,10 @@ static int map__process_kallsym_symbol(void *arg, const char *name,
sym = symbol__new(start, 0, kallsyms2elf_type(type), name);
if (sym == NULL)
return -ENOMEM;
+
+ sym->is_idle = is_idle_sym(name);
+ sym->idle_checked = true;
+
/*
* We will pass the symbols to the filter later, in
* map__split_kallsyms, when we have split the maps per module
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h
index fd5b70e..c163ba9 100644
--- a/tools/perf/util/symbol.h
+++ b/tools/perf/util/symbol.h
@@ -59,7 +59,7 @@ static inline char *bfd_demangle(void __maybe_unused *v,

/** struct symbol - symtab entry
*
- * @ignore - resolvable but tools ignore it (e.g. idle routines)
+ * @ignore - resolvable but perf-top ignores it (e.g. idle routines)
*/
struct symbol {
struct rb_node rb_node;
@@ -68,6 +68,8 @@ struct symbol {
u16 namelen;
u8 binding;
bool ignore;
+ bool is_idle; /* pertains to kernel symbols only */
+ bool idle_checked;
char name[0];
};

@@ -236,6 +238,7 @@ size_t symbol__fprintf(struct symbol *sym, FILE *fp);
bool symbol_type__is_a(char symbol_type, enum map_type map_type);
bool symbol__restricted_filename(const char *filename,
const char *restricted_filename);
+bool symbol__is_idle(struct symbol *sym);

int dso__load_sym(struct dso *dso, struct map *map, struct symsrc *syms_ss,
struct symsrc *runtime_ss, symbol_filter_t filter,
--
1.7.10.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/