From 1f208ea67821703fd4de056ea6f0baa81f4ad4a5 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 1 Jul 2009 09:00:44 +1000 Subject: perf report: Fix -z option Fix a copy and paste error, -z was setting the group option. Signed-off-by: Anton Blanchard Cc: a.p.zijlstra@chello.nl Cc: paulus@samba.org LKML-Reference: <20090630230140.714204656@samba.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index cf0d21f1ae10..5c2965562c5d 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -675,7 +675,7 @@ static const struct option options[] = { "put the counters into a counter group"), OPT_STRING('s', "sym-filter", &sym_filter, "pattern", "only display symbols matchig this pattern"), - OPT_BOOLEAN('z', "zero", &group, + OPT_BOOLEAN('z', "zero", &zero, "zero history across updates"), OPT_INTEGER('F', "freq", &freq, "profile at this frequency"), -- cgit v1.2.3 From 2ab52083ffc057014e502cf3473adc41436922fa Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 1 Jul 2009 09:00:46 +1000 Subject: perf top: Move skip symbols to an array Move the list of symbols we skip into an array, making it easier to add new ones. Signed-off-by: Anton Blanchard Cc: a.p.zijlstra@chello.nl Cc: paulus@samba.org LKML-Reference: <20090630230140.904782938@samba.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-top.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5c2965562c5d..731ec6d79c1c 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -286,11 +286,22 @@ static void *display_thread(void *arg) return NULL; } +/* Tag samples to be skipped. */ +char *skip_symbols[] = { + "default_idle", + "cpu_idle", + "enter_idle", + "exit_idle", + "mwait_idle", + NULL +}; + static int symbol_filter(struct dso *self, struct symbol *sym) { static int filter_match; struct sym_entry *syme; const char *name = sym->name; + int i; if (!strcmp(name, "_text") || !strcmp(name, "_etext") || @@ -302,13 +313,12 @@ static int symbol_filter(struct dso *self, struct symbol *sym) return 1; syme = dso__sym_priv(self, sym); - /* Tag samples to be skipped. */ - if (!strcmp("default_idle", name) || - !strcmp("cpu_idle", name) || - !strcmp("enter_idle", name) || - !strcmp("exit_idle", name) || - !strcmp("mwait_idle", name)) - syme->skip = 1; + for (i = 0; skip_symbols[i]; i++) { + if (!strcmp(skip_symbols[i], name)) { + syme->skip = 1; + break; + } + } if (filter_match == 1) { filter_end = sym->start; -- cgit v1.2.3 From 3a3393ef75a14ae259a82f3f38624efa17884168 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 1 Jul 2009 09:00:47 +1000 Subject: perf top: Add ppc64 specific skip symbols and strip ppc64 . prefix Filter out some ppc64 specific idle loop functions and remove leading '.' on ppc64 text symbols. Signed-off-by: Anton Blanchard Cc: a.p.zijlstra@chello.nl Cc: paulus@samba.org LKML-Reference: <20090630230140.995643441@samba.org> Signed-off-by: Ingo Molnar --- tools/perf/builtin-top.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 731ec6d79c1c..0506cd6e04cc 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -293,6 +293,8 @@ char *skip_symbols[] = { "enter_idle", "exit_idle", "mwait_idle", + "ppc64_runlatch_off", + "pseries_dedicated_idle_sleep", NULL }; @@ -303,6 +305,13 @@ static int symbol_filter(struct dso *self, struct symbol *sym) const char *name = sym->name; int i; + /* + * ppc64 uses function descriptors and appends a '.' to the + * start of every instruction address. Remove it. + */ + if (name[0] == '.') + name++; + if (!strcmp(name, "_text") || !strcmp(name, "_etext") || !strcmp(name, "_sinittext") || -- cgit v1.2.3 From f37a291c527c954df4da568de718ebb36b8261c0 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Wed, 1 Jul 2009 12:37:06 +0200 Subject: perf_counter tools: Add more warnings and fix/annotate them Enable -Wextra. This found a few real bugs plus a number of signed/unsigned type mismatches/uncleanlinesses. It also required a few annotations All things considered it was still worth it so lets try with this enabled for now. Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker LKML-Reference: Signed-off-by: Ingo Molnar --- tools/perf/Makefile | 2 +- tools/perf/builtin-annotate.c | 12 +++++------ tools/perf/builtin-help.c | 6 ++++-- tools/perf/builtin-list.c | 2 +- tools/perf/builtin-record.c | 4 ++-- tools/perf/builtin-report.c | 22 ++++++++++---------- tools/perf/builtin-stat.c | 18 +++++++++------- tools/perf/builtin-top.c | 8 +++---- tools/perf/perf.c | 5 +---- tools/perf/perf.h | 2 ++ tools/perf/util/alias.c | 2 +- tools/perf/util/cache.h | 1 + tools/perf/util/callchain.c | 15 +++++++------- tools/perf/util/callchain.h | 10 ++++----- tools/perf/util/color.c | 10 ++++++--- tools/perf/util/config.c | 18 +++++++++------- tools/perf/util/exec_cmd.c | 5 ++++- tools/perf/util/help.c | 26 +++++++++++++---------- tools/perf/util/help.h | 6 +++--- tools/perf/util/parse-events.c | 2 +- tools/perf/util/parse-options.c | 2 +- tools/perf/util/parse-options.h | 25 +++++++++++----------- tools/perf/util/quote.c | 46 ++++++++++++++++++++++------------------- tools/perf/util/quote.h | 2 +- tools/perf/util/strbuf.c | 13 ++++++------ tools/perf/util/strbuf.h | 10 ++++----- tools/perf/util/wrapper.c | 5 +++-- 27 files changed, 151 insertions(+), 128 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index f572c90f610e..eddf076b19d7 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -164,7 +164,7 @@ endif # CFLAGS and LDFLAGS are for the users to override from the command line. -CFLAGS = $(M64) -ggdb3 -Wall -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6 +CFLAGS = $(M64) -ggdb3 -Wall -Wextra -Wstrict-prototypes -Wmissing-declarations -Wmissing-prototypes -std=gnu99 -Wdeclaration-after-statement -Werror -O6 LDFLAGS = -lpthread -lrt -lelf -lm ALL_CFLAGS = $(CFLAGS) ALL_LDFLAGS = $(LDFLAGS) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 722c0f54e549..6cba70daf121 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -160,7 +160,7 @@ static void dsos__fprintf(FILE *fp) static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) { - return dso__find_symbol(kernel_dso, ip); + return dso__find_symbol(dso, ip); } static int load_kernel(void) @@ -203,7 +203,7 @@ static u64 map__map_ip(struct map *map, u64 ip) return ip - map->start + map->pgoff; } -static u64 vdso__map_ip(struct map *map, u64 ip) +static u64 vdso__map_ip(struct map *map __used, u64 ip) { return ip; } @@ -600,7 +600,7 @@ static LIST_HEAD(hist_entry__sort_list); static int sort_dimension__add(char *tok) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { struct sort_dimension *sd = &sort_dimensions[i]; @@ -1069,7 +1069,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) static const char *prev_color; unsigned int offset; size_t line_len; - u64 line_ip; + s64 line_ip; int ret; char *c; @@ -1428,7 +1428,7 @@ more: head += size; - if (offset + head < stat.st_size) + if (offset + head < (unsigned long)stat.st_size) goto more; rc = EXIT_SUCCESS; @@ -1492,7 +1492,7 @@ static void setup_sorting(void) free(str); } -int cmd_annotate(int argc, const char **argv, const char *prefix) +int cmd_annotate(int argc, const char **argv, const char *prefix __used) { symbol__init(); diff --git a/tools/perf/builtin-help.c b/tools/perf/builtin-help.c index 0f32dc3f3c4c..2599d86a733b 100644 --- a/tools/perf/builtin-help.c +++ b/tools/perf/builtin-help.c @@ -3,6 +3,7 @@ * * Builtin help command */ +#include "perf.h" #include "util/cache.h" #include "builtin.h" #include "util/exec_cmd.h" @@ -277,7 +278,7 @@ static struct cmdnames main_cmds, other_cmds; void list_common_cmds_help(void) { - int i, longest = 0; + unsigned int i, longest = 0; for (i = 0; i < ARRAY_SIZE(common_cmds); i++) { if (longest < strlen(common_cmds[i].name)) @@ -415,9 +416,10 @@ static void show_html_page(const char *perf_cmd) open_html(page_path.buf); } -int cmd_help(int argc, const char **argv, const char *prefix) +int cmd_help(int argc, const char **argv, const char *prefix __used) { const char *alias; + load_command_list("perf-", &main_cmds, &other_cmds); perf_config(perf_help_config, NULL); diff --git a/tools/perf/builtin-list.c b/tools/perf/builtin-list.c index fe60e37c96ef..f990fa8a35c9 100644 --- a/tools/perf/builtin-list.c +++ b/tools/perf/builtin-list.c @@ -13,7 +13,7 @@ #include "util/parse-options.h" #include "util/parse-events.h" -int cmd_list(int argc, const char **argv, const char *prefix) +int cmd_list(int argc __used, const char **argv __used, const char *prefix __used) { print_events(); return 0; diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d18546f37d7c..4ef78a5e6f32 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c @@ -294,7 +294,7 @@ static void pid_synthesize_mmap_samples(pid_t pid) while (1) { char bf[BUFSIZ], *pbf = bf; struct mmap_event mmap_ev = { - .header.type = PERF_EVENT_MMAP, + .header = { .type = PERF_EVENT_MMAP }, }; int n; size_t size; @@ -650,7 +650,7 @@ static const struct option options[] = { OPT_END() }; -int cmd_record(int argc, const char **argv, const char *prefix) +int cmd_record(int argc, const char **argv, const char *prefix __used) { int counter; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 7d2b49adcdc5..007363db3b16 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -177,7 +177,7 @@ static void dsos__fprintf(FILE *fp) static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) { - return dso__find_symbol(kernel_dso, ip); + return dso__find_symbol(dso, ip); } static int load_kernel(void) @@ -239,7 +239,7 @@ static u64 map__map_ip(struct map *map, u64 ip) return ip - map->start + map->pgoff; } -static u64 vdso__map_ip(struct map *map, u64 ip) +static u64 vdso__map_ip(struct map *map __used, u64 ip) { return ip; } @@ -712,7 +712,7 @@ static LIST_HEAD(hist_entry__sort_list); static int sort_dimension__add(char *tok) { - int i; + unsigned int i; for (i = 0; i < ARRAY_SIZE(sort_dimensions); i++) { struct sort_dimension *sd = &sort_dimensions[i]; @@ -801,7 +801,7 @@ callchain__fprintf(FILE *fp, struct callchain_node *self, u64 total_samples) ret += fprintf(fp, " %s\n", chain->sym->name); else ret += fprintf(fp, " %p\n", - (void *)chain->ip); + (void *)(long)chain->ip); } return ret; @@ -938,12 +938,12 @@ static int call__match(struct symbol *sym) } static struct symbol ** -resolve_callchain(struct thread *thread, struct map *map, +resolve_callchain(struct thread *thread, struct map *map __used, struct ip_callchain *chain, struct hist_entry *entry) { - int i; - struct symbol **syms; u64 context = PERF_CONTEXT_MAX; + struct symbol **syms; + unsigned int i; if (callchain) { syms = calloc(chain->nr, sizeof(*syms)); @@ -1183,7 +1183,7 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) fprintf(fp, "# ........"); list_for_each_entry(se, &hist_entry__sort_list, list) { - int i; + unsigned int i; if (exclude_other && (se == &sort_parent)) continue; @@ -1271,7 +1271,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) (long long)period); if (sample_type & PERF_SAMPLE_CALLCHAIN) { - int i; + unsigned int i; chain = (void *)more_data; @@ -1667,7 +1667,7 @@ more: if (offset + head >= header->data_offset + header->data_size) goto done; - if (offset + head < stat.st_size) + if (offset + head < (unsigned long)stat.st_size) goto more; done: @@ -1756,7 +1756,7 @@ static void setup_list(struct strlist **list, const char *list_str, } } -int cmd_report(int argc, const char **argv, const char *prefix) +int cmd_report(int argc, const char **argv, const char *prefix __used) { symbol__init(); diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 2e03524a1de0..095a90e012a1 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c @@ -64,7 +64,7 @@ static struct perf_counter_attr default_attrs[] = { static int system_wide = 0; static int verbose = 0; -static int nr_cpus = 0; +static unsigned int nr_cpus = 0; static int run_idx = 0; static int run_count = 1; @@ -108,7 +108,8 @@ static void create_perf_stat_counter(int counter, int pid) PERF_FORMAT_TOTAL_TIME_RUNNING; if (system_wide) { - int cpu; + unsigned int cpu; + for (cpu = 0; cpu < nr_cpus; cpu++) { fd[cpu][counter] = sys_perf_counter_open(attr, -1, cpu, -1, 0); if (fd[cpu][counter] < 0 && verbose) @@ -150,8 +151,8 @@ static inline int nsec_counter(int counter) static void read_counter(int counter) { u64 *count, single_count[3]; - ssize_t res; - int cpu, nv; + unsigned int cpu; + size_t res, nv; int scaled; count = event_res[run_idx][counter]; @@ -165,6 +166,7 @@ static void read_counter(int counter) res = read(fd[cpu][counter], single_count, nv * sizeof(u64)); assert(res == nv * sizeof(u64)); + close(fd[cpu][counter]); fd[cpu][counter] = -1; @@ -200,7 +202,7 @@ static void read_counter(int counter) runtime_cycles[run_idx] = count[0]; } -static int run_perf_stat(int argc, const char **argv) +static int run_perf_stat(int argc __used, const char **argv) { unsigned long long t0, t1; int status = 0; @@ -390,7 +392,7 @@ static void calc_avg(void) event_res_avg[j]+1, event_res[i][j]+1); update_avg("counter/2", j, event_res_avg[j]+2, event_res[i][j]+2); - if (event_scaled[i][j] != -1) + if (event_scaled[i][j] != (u64)-1) update_avg("scaled", j, event_scaled_avg + j, event_scaled[i]+j); else @@ -510,7 +512,7 @@ static const struct option options[] = { OPT_END() }; -int cmd_stat(int argc, const char **argv, const char *prefix) +int cmd_stat(int argc, const char **argv, const char *prefix __used) { int status; @@ -528,7 +530,7 @@ int cmd_stat(int argc, const char **argv, const char *prefix) nr_cpus = sysconf(_SC_NPROCESSORS_ONLN); assert(nr_cpus <= MAX_NR_CPUS); - assert(nr_cpus >= 0); + assert((int)nr_cpus >= 0); /* * We dont want to block the signals - that would cause diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 0506cd6e04cc..5f5e7df8302d 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -269,7 +269,7 @@ static void print_sym_table(void) } } -static void *display_thread(void *arg) +static void *display_thread(void *arg __used) { struct pollfd stdin_poll = { .fd = 0, .events = POLLIN }; int delay_msecs = delay_secs * 1000; @@ -287,7 +287,7 @@ static void *display_thread(void *arg) } /* Tag samples to be skipped. */ -char *skip_symbols[] = { +static const char *skip_symbols[] = { "default_idle", "cpu_idle", "enter_idle", @@ -426,7 +426,7 @@ static void process_event(u64 ip, int counter, int user) struct mmap_data { int counter; void *base; - unsigned int mask; + int mask; unsigned int prev; }; @@ -705,7 +705,7 @@ static const struct option options[] = { OPT_END() }; -int cmd_top(int argc, const char **argv, const char *prefix) +int cmd_top(int argc, const char **argv, const char *prefix __used) { int counter; diff --git a/tools/perf/perf.c b/tools/perf/perf.c index 4eb725933703..c5656784c61d 100644 --- a/tools/perf/perf.c +++ b/tools/perf/perf.c @@ -229,9 +229,6 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) use_pager = 1; commit_pager_choice(); - if (p->option & NEED_WORK_TREE) - /* setup_work_tree() */; - status = p->fn(argc, argv, prefix); if (status) return status & 0xff; @@ -266,7 +263,7 @@ static void handle_internal_command(int argc, const char **argv) { "annotate", cmd_annotate, 0 }, { "version", cmd_version, 0 }, }; - int i; + unsigned int i; static const char ext[] = STRIP_EXTENSION; if (sizeof(ext) > 1) { diff --git a/tools/perf/perf.h b/tools/perf/perf.h index ce394192c85a..27887c916439 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h @@ -52,6 +52,8 @@ static inline unsigned long long rdclock(void) #define __user #define asmlinkage +#define __used __attribute__((__unused__)) + #define unlikely(x) __builtin_expect(!!(x), 0) #define min(x, y) ({ \ typeof(x) _min1 = (x); \ diff --git a/tools/perf/util/alias.c b/tools/perf/util/alias.c index 9b3dd2b428df..b8144e80bb1e 100644 --- a/tools/perf/util/alias.c +++ b/tools/perf/util/alias.c @@ -3,7 +3,7 @@ static const char *alias_key; static char *alias_val; -static int alias_lookup_cb(const char *k, const char *v, void *cb) +static int alias_lookup_cb(const char *k, const char *v, void *cb __used) { if (!prefixcmp(k, "alias.") && !strcmp(k+6, alias_key)) { if (!v) diff --git a/tools/perf/util/cache.h b/tools/perf/util/cache.h index 393d6146d13b..161d5f413e28 100644 --- a/tools/perf/util/cache.h +++ b/tools/perf/util/cache.h @@ -3,6 +3,7 @@ #include "util.h" #include "strbuf.h" +#include "../perf.h" #define PERF_DIR_ENVIRONMENT "PERF_DIR" #define PERF_WORK_TREE_ENVIRONMENT "PERF_WORK_TREE" diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 440db12c6359..3dceabd9b5ef 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -92,7 +92,7 @@ static void fill_node(struct callchain_node *node, struct ip_callchain *chain, int start, struct symbol **syms) { - int i; + unsigned int i; for (i = start; i < chain->nr; i++) { struct callchain_list *call; @@ -135,7 +135,7 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, { struct callchain_node *new; struct list_head *old_tail; - int idx_total = idx_parents + idx_local; + unsigned int idx_total = idx_parents + idx_local; /* split */ new = create_child(parent, true); @@ -164,17 +164,18 @@ split_add_child(struct callchain_node *parent, struct ip_callchain *chain, static int __append_chain(struct callchain_node *root, struct ip_callchain *chain, - int start, struct symbol **syms); + unsigned int start, struct symbol **syms); static void __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, - struct symbol **syms, int start) + struct symbol **syms, unsigned int start) { struct callchain_node *rnode; /* lookup in childrens */ list_for_each_entry(rnode, &root->children, brothers) { - int ret = __append_chain(rnode, chain, start, syms); + unsigned int ret = __append_chain(rnode, chain, start, syms); + if (!ret) return; } @@ -184,10 +185,10 @@ __append_chain_children(struct callchain_node *root, struct ip_callchain *chain, static int __append_chain(struct callchain_node *root, struct ip_callchain *chain, - int start, struct symbol **syms) + unsigned int start, struct symbol **syms) { struct callchain_list *cnode; - int i = start; + unsigned int i = start; bool found = false; /* diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index c942daa712e6..251d99ecd225 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -10,15 +10,15 @@ struct callchain_node { struct callchain_node *parent; struct list_head brothers; - struct list_head children; - struct list_head val; + struct list_head children; + struct list_head val; struct rb_node rb_node; - int val_nr; - int hit; + unsigned int val_nr; + u64 hit; }; struct callchain_list { - unsigned long ip; + u64 ip; struct symbol *sym; struct list_head list; }; diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 9a8c20ccc53e..26f82318b86b 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -11,7 +11,8 @@ static int parse_color(const char *name, int len) }; char *end; int i; - for (i = 0; i < ARRAY_SIZE(color_names); i++) { + + for (i = 0; i < (int)ARRAY_SIZE(color_names); i++) { const char *str = color_names[i]; if (!strncasecmp(name, str, len) && !str[len]) return i - 1; @@ -28,7 +29,8 @@ static int parse_attr(const char *name, int len) static const char * const attr_names[] = { "bold", "dim", "ul", "blink", "reverse" }; - int i; + unsigned int i; + for (i = 0; i < ARRAY_SIZE(attr_names); i++) { const char *str = attr_names[i]; if (!strncasecmp(name, str, len) && !str[len]) @@ -222,10 +224,12 @@ int color_fwrite_lines(FILE *fp, const char *color, { if (!*color) return fwrite(buf, count, 1, fp) != 1; + while (count) { char *p = memchr(buf, '\n', count); + if (p != buf && (fputs(color, fp) < 0 || - fwrite(buf, p ? p - buf : count, 1, fp) != 1 || + fwrite(buf, p ? (size_t)(p - buf) : count, 1, fp) != 1 || fputs(PERF_COLOR_RESET, fp) < 0)) return -1; if (!p) diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c index 3dd13faa6a27..780df541006d 100644 --- a/tools/perf/util/config.c +++ b/tools/perf/util/config.c @@ -47,10 +47,12 @@ static int get_next_char(void) static char *parse_value(void) { static char value[1024]; - int quote = 0, comment = 0, len = 0, space = 0; + int quote = 0, comment = 0, space = 0; + size_t len = 0; for (;;) { int c = get_next_char(); + if (len >= sizeof(value) - 1) return NULL; if (c == '\n') { @@ -353,13 +355,13 @@ int perf_config_string(const char **dest, const char *var, const char *value) return 0; } -static int perf_default_core_config(const char *var, const char *value) +static int perf_default_core_config(const char *var __used, const char *value __used) { /* Add other config variables here and to Documentation/config.txt. */ return 0; } -int perf_default_config(const char *var, const char *value, void *dummy) +int perf_default_config(const char *var, const char *value, void *dummy __used) { if (!prefixcmp(var, "core.")) return perf_default_core_config(var, value); @@ -471,10 +473,10 @@ static int matches(const char* key, const char* value) !regexec(store.value_regex, value, 0, NULL, 0))); } -static int store_aux(const char* key, const char* value, void *cb) +static int store_aux(const char* key, const char* value, void *cb __used) { + int section_len; const char *ep; - size_t section_len; switch (store.state) { case KEY_SEEN: @@ -551,7 +553,7 @@ static int store_write_section(int fd, const char* key) strbuf_addf(&sb, "[%.*s]\n", store.baselen, key); } - success = write_in_full(fd, sb.buf, sb.len) == sb.len; + success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); strbuf_release(&sb); return success; @@ -599,7 +601,7 @@ static int store_write_pair(int fd, const char* key, const char* value) } strbuf_addf(&sb, "%s\n", quote); - success = write_in_full(fd, sb.buf, sb.len) == sb.len; + success = (write_in_full(fd, sb.buf, sb.len) == (ssize_t)sb.len); strbuf_release(&sb); return success; @@ -741,7 +743,7 @@ int perf_config_set_multivar(const char* key, const char* value, } else { struct stat st; char* contents; - size_t contents_sz, copy_begin, copy_end; + ssize_t contents_sz, copy_begin, copy_end; int i, new_line = 0; if (value_regex == NULL) diff --git a/tools/perf/util/exec_cmd.c b/tools/perf/util/exec_cmd.c index d39292263153..34a352867382 100644 --- a/tools/perf/util/exec_cmd.c +++ b/tools/perf/util/exec_cmd.c @@ -1,6 +1,9 @@ #include "cache.h" #include "exec_cmd.h" #include "quote.h" + +#include + #define MAX_ARGS 32 extern char **environ; @@ -51,7 +54,7 @@ const char *perf_extract_argv0_path(const char *argv0) slash--; if (slash >= argv0) { - argv0_path = strndup(argv0, slash - argv0); + argv0_path = xstrndup(argv0, slash - argv0); return slash + 1; } diff --git a/tools/perf/util/help.c b/tools/perf/util/help.c index 17a00e0df2c4..fbb00978b2e2 100644 --- a/tools/perf/util/help.c +++ b/tools/perf/util/help.c @@ -26,7 +26,7 @@ static int term_columns(void) return 80; } -void add_cmdname(struct cmdnames *cmds, const char *name, int len) +void add_cmdname(struct cmdnames *cmds, const char *name, size_t len) { struct cmdname *ent = malloc(sizeof(*ent) + len + 1); @@ -40,7 +40,8 @@ void add_cmdname(struct cmdnames *cmds, const char *name, int len) static void clean_cmdnames(struct cmdnames *cmds) { - int i; + unsigned int i; + for (i = 0; i < cmds->cnt; ++i) free(cmds->names[i]); free(cmds->names); @@ -57,7 +58,7 @@ static int cmdname_compare(const void *a_, const void *b_) static void uniq(struct cmdnames *cmds) { - int i, j; + unsigned int i, j; if (!cmds->cnt) return; @@ -71,7 +72,7 @@ static void uniq(struct cmdnames *cmds) void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes) { - int ci, cj, ei; + size_t ci, cj, ei; int cmp; ci = cj = ei = 0; @@ -106,8 +107,9 @@ static void pretty_print_string_list(struct cmdnames *cmds, int longest) printf(" "); for (j = 0; j < cols; j++) { - int n = j * rows + i; - int size = space; + unsigned int n = j * rows + i; + unsigned int size = space; + if (n >= cmds->cnt) break; if (j == cols-1 || n + rows >= cmds->cnt) @@ -208,7 +210,7 @@ void load_command_list(const char *prefix, void list_commands(const char *title, struct cmdnames *main_cmds, struct cmdnames *other_cmds) { - int i, longest = 0; + unsigned int i, longest = 0; for (i = 0; i < main_cmds->cnt; i++) if (longest < main_cmds->names[i]->len) @@ -239,7 +241,8 @@ void list_commands(const char *title, struct cmdnames *main_cmds, int is_in_cmdlist(struct cmdnames *c, const char *s) { - int i; + unsigned int i; + for (i = 0; i < c->cnt; i++) if (!strcmp(s, c->names[i]->name)) return 1; @@ -271,7 +274,8 @@ static int levenshtein_compare(const void *p1, const void *p2) static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) { - int i; + unsigned int i; + ALLOC_GROW(cmds->names, cmds->cnt + old->cnt, cmds->alloc); for (i = 0; i < old->cnt; i++) @@ -283,7 +287,7 @@ static void add_cmd_list(struct cmdnames *cmds, struct cmdnames *old) const char *help_unknown_cmd(const char *cmd) { - int i, n = 0, best_similarity = 0; + unsigned int i, n = 0, best_similarity = 0; struct cmdnames main_cmds, other_cmds; memset(&main_cmds, 0, sizeof(main_cmds)); @@ -345,7 +349,7 @@ const char *help_unknown_cmd(const char *cmd) exit(1); } -int cmd_version(int argc, const char **argv, const char *prefix) +int cmd_version(int argc __used, const char **argv __used, const char *prefix __used) { printf("perf version %s\n", perf_version_string); return 0; diff --git a/tools/perf/util/help.h b/tools/perf/util/help.h index 56bc15406ffc..7128783637b4 100644 --- a/tools/perf/util/help.h +++ b/tools/perf/util/help.h @@ -2,8 +2,8 @@ #define HELP_H struct cmdnames { - int alloc; - int cnt; + size_t alloc; + size_t cnt; struct cmdname { size_t len; /* also used for similarity index in help.c */ char name[FLEX_ARRAY]; @@ -19,7 +19,7 @@ static inline void mput_char(char c, unsigned int num) void load_command_list(const char *prefix, struct cmdnames *main_cmds, struct cmdnames *other_cmds); -void add_cmdname(struct cmdnames *cmds, const char *name, int len); +void add_cmdname(struct cmdnames *cmds, const char *name, size_t len); /* Here we require that excludes is a sorted list. */ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes); int is_in_cmdlist(struct cmdnames *c, const char *s); diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index e6b83a3311a5..aed70901df24 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c @@ -385,7 +385,7 @@ static int parse_event_symbols(const char **str, struct perf_counter_attr *attr) return 1; } -int parse_events(const struct option *opt, const char *str, int unset) +int parse_events(const struct option *opt __used, const char *str, int unset __used) { struct perf_counter_attr attr; diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index b3affb1658d2..9a897b7cce79 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c @@ -485,7 +485,7 @@ int parse_options_usage(const char * const *usagestr, } -int parse_opt_verbosity_cb(const struct option *opt, const char *arg, +int parse_opt_verbosity_cb(const struct option *opt, const char *arg __used, int unset) { int *target = opt->value; diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h index a1039a6ce0eb..15c8aba9c62e 100644 --- a/tools/perf/util/parse-options.h +++ b/tools/perf/util/parse-options.h @@ -90,21 +90,20 @@ struct option { intptr_t defval; }; -#define OPT_END() { OPTION_END } -#define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, (h) } -#define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } -#define OPT_BIT(s, l, v, h, b) { OPTION_BIT, (s), (l), (v), NULL, (h), 0, NULL, (b) } -#define OPT_BOOLEAN(s, l, v, h) { OPTION_BOOLEAN, (s), (l), (v), NULL, (h) } -#define OPT_SET_INT(s, l, v, h, i) { OPTION_SET_INT, (s), (l), (v), NULL, (h), 0, NULL, (i) } -#define OPT_SET_PTR(s, l, v, h, p) { OPTION_SET_PTR, (s), (l), (v), NULL, (h), 0, NULL, (p) } -#define OPT_INTEGER(s, l, v, h) { OPTION_INTEGER, (s), (l), (v), NULL, (h) } -#define OPT_LONG(s, l, v, h) { OPTION_LONG, (s), (l), (v), NULL, (h) } -#define OPT_STRING(s, l, v, a, h) { OPTION_STRING, (s), (l), (v), (a), (h) } +#define OPT_END() { .type = OPTION_END } +#define OPT_ARGUMENT(l, h) { .type = OPTION_ARGUMENT, .long_name = (l), .help = (h) } +#define OPT_GROUP(h) { .type = OPTION_GROUP, .help = (h) } +#define OPT_BIT(s, l, v, h, b) { .type = OPTION_BIT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (b) } +#define OPT_BOOLEAN(s, l, v, h) { .type = OPTION_BOOLEAN, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } +#define OPT_SET_INT(s, l, v, h, i) { .type = OPTION_SET_INT, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (i) } +#define OPT_SET_PTR(s, l, v, h, p) { .type = OPTION_SET_PTR, .short_name = (s), .long_name = (l), .value = (v), .help = (h), .defval = (p) } +#define OPT_INTEGER(s, l, v, h) { .type = OPTION_INTEGER, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } +#define OPT_LONG(s, l, v, h) { .type = OPTION_LONG, .short_name = (s), .long_name = (l), .value = (v), .help = (h) } +#define OPT_STRING(s, l, v, a, h) { .type = OPTION_STRING, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h) } #define OPT_DATE(s, l, v, h) \ - { OPTION_CALLBACK, (s), (l), (v), "time",(h), 0, \ - parse_opt_approxidate_cb } + { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), .argh = "time", .help = (h), .callback = parse_opt_approxidate_cb } #define OPT_CALLBACK(s, l, v, a, h, f) \ - { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } + { .type = OPTION_CALLBACK, .short_name = (s), .long_name = (l), .value = (v), (a), .help = (h), .callback = (f) } /* parse_options() will filter out the processed options and leave the * non-option argments in argv[]. diff --git a/tools/perf/util/quote.c b/tools/perf/util/quote.c index f18c5212bc92..c6e5dc0dc82f 100644 --- a/tools/perf/util/quote.c +++ b/tools/perf/util/quote.c @@ -162,12 +162,16 @@ static inline int sq_must_quote(char c) return sq_lookup[(unsigned char)c] + quote_path_fully > 0; } -/* returns the longest prefix not needing a quote up to maxlen if positive. - This stops at the first \0 because it's marked as a character needing an - escape */ -static size_t next_quote_pos(const char *s, ssize_t maxlen) +/* + * Returns the longest prefix not needing a quote up to maxlen if + * positive. + * This stops at the first \0 because it's marked as a character + * needing an escape. + */ +static ssize_t next_quote_pos(const char *s, ssize_t maxlen) { - size_t len; + ssize_t len; + if (maxlen < 0) { for (len = 0; !sq_must_quote(s[len]); len++); } else { @@ -192,22 +196,22 @@ static size_t next_quote_pos(const char *s, ssize_t maxlen) static size_t quote_c_style_counted(const char *name, ssize_t maxlen, struct strbuf *sb, FILE *fp, int no_dq) { -#undef EMIT -#define EMIT(c) \ - do { \ - if (sb) strbuf_addch(sb, (c)); \ - if (fp) fputc((c), fp); \ - count++; \ +#define EMIT(c) \ + do { \ + if (sb) strbuf_addch(sb, (c)); \ + if (fp) fputc((c), fp); \ + count++; \ } while (0) -#define EMITBUF(s, l) \ - do { \ - int __ret; \ - if (sb) strbuf_add(sb, (s), (l)); \ - if (fp) __ret = fwrite((s), (l), 1, fp); \ - count += (l); \ + +#define EMITBUF(s, l) \ + do { \ + int __ret; \ + if (sb) strbuf_add(sb, (s), (l)); \ + if (fp) __ret = fwrite((s), (l), 1, fp); \ + count += (l); \ } while (0) - size_t len, count = 0; + ssize_t len, count = 0; const char *p = name; for (;;) { @@ -273,8 +277,8 @@ void write_name_quoted(const char *name, FILE *fp, int terminator) fputc(terminator, fp); } -extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, - const char *name, FILE *fp, int terminator) +void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, + const char *name, FILE *fp, int terminator) { int needquote = 0; @@ -306,7 +310,7 @@ char *quote_path_relative(const char *in, int len, len = strlen(in); /* "../" prefix itself does not need quoting, but "in" might. */ - needquote = next_quote_pos(in, len) < len; + needquote = (next_quote_pos(in, len) < len); strbuf_setlen(out, 0); strbuf_grow(out, len); diff --git a/tools/perf/util/quote.h b/tools/perf/util/quote.h index 5dfad89816db..a5454a1d1c13 100644 --- a/tools/perf/util/quote.h +++ b/tools/perf/util/quote.h @@ -53,7 +53,7 @@ extern size_t quote_c_style(const char *name, struct strbuf *, FILE *, int no_dq extern void quote_two_c_style(struct strbuf *, const char *, const char *, int); extern void write_name_quoted(const char *name, FILE *, int terminator); -extern void write_name_quotedpfx(const char *pfx, size_t pfxlen, +extern void write_name_quotedpfx(const char *pfx, ssize_t pfxlen, const char *name, FILE *, int terminator); /* quote path as relative to the given prefix */ diff --git a/tools/perf/util/strbuf.c b/tools/perf/util/strbuf.c index 464e7ca898cf..5249d5a1b0c2 100644 --- a/tools/perf/util/strbuf.c +++ b/tools/perf/util/strbuf.c @@ -16,7 +16,7 @@ int prefixcmp(const char *str, const char *prefix) */ char strbuf_slopbuf[1]; -void strbuf_init(struct strbuf *sb, size_t hint) +void strbuf_init(struct strbuf *sb, ssize_t hint) { sb->alloc = sb->len = 0; sb->buf = strbuf_slopbuf; @@ -92,7 +92,8 @@ void strbuf_ltrim(struct strbuf *sb) void strbuf_tolower(struct strbuf *sb) { - int i; + unsigned int i; + for (i = 0; i < sb->len; i++) sb->buf[i] = tolower(sb->buf[i]); } @@ -264,7 +265,7 @@ size_t strbuf_fread(struct strbuf *sb, size_t size, FILE *f) return res; } -ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) +ssize_t strbuf_read(struct strbuf *sb, int fd, ssize_t hint) { size_t oldlen = sb->len; size_t oldalloc = sb->alloc; @@ -293,7 +294,7 @@ ssize_t strbuf_read(struct strbuf *sb, int fd, size_t hint) #define STRBUF_MAXLINK (2*PATH_MAX) -int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) +int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint) { size_t oldalloc = sb->alloc; @@ -301,7 +302,7 @@ int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint) hint = 32; while (hint < STRBUF_MAXLINK) { - int len; + ssize_t len; strbuf_grow(sb, hint); len = readlink(path, sb->buf, hint); @@ -343,7 +344,7 @@ int strbuf_getline(struct strbuf *sb, FILE *fp, int term) return 0; } -int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint) +int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint) { int fd, len; diff --git a/tools/perf/util/strbuf.h b/tools/perf/util/strbuf.h index 9ee908a3ec5d..d2aa86c014c1 100644 --- a/tools/perf/util/strbuf.h +++ b/tools/perf/util/strbuf.h @@ -50,7 +50,7 @@ struct strbuf { #define STRBUF_INIT { 0, 0, strbuf_slopbuf } /*----- strbuf life cycle -----*/ -extern void strbuf_init(struct strbuf *, size_t); +extern void strbuf_init(struct strbuf *buf, ssize_t hint); extern void strbuf_release(struct strbuf *); extern char *strbuf_detach(struct strbuf *, size_t *); extern void strbuf_attach(struct strbuf *, void *, size_t, size_t); @@ -61,7 +61,7 @@ static inline void strbuf_swap(struct strbuf *a, struct strbuf *b) { } /*----- strbuf size related -----*/ -static inline size_t strbuf_avail(const struct strbuf *sb) { +static inline ssize_t strbuf_avail(const struct strbuf *sb) { return sb->alloc ? sb->alloc - sb->len - 1 : 0; } @@ -122,9 +122,9 @@ extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); extern size_t strbuf_fread(struct strbuf *, size_t, FILE *); /* XXX: if read fails, any partial read is undone */ -extern ssize_t strbuf_read(struct strbuf *, int fd, size_t hint); -extern int strbuf_read_file(struct strbuf *sb, const char *path, size_t hint); -extern int strbuf_readlink(struct strbuf *sb, const char *path, size_t hint); +extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); +extern int strbuf_read_file(struct strbuf *sb, const char *path, ssize_t hint); +extern int strbuf_readlink(struct strbuf *sb, const char *path, ssize_t hint); extern int strbuf_getline(struct strbuf *, FILE *, int); diff --git a/tools/perf/util/wrapper.c b/tools/perf/util/wrapper.c index 6350d65f6d9e..4574ac28396f 100644 --- a/tools/perf/util/wrapper.c +++ b/tools/perf/util/wrapper.c @@ -7,7 +7,7 @@ * There's no pack memory to release - but stay close to the Git * version so wrap this away: */ -static inline void release_pack_memory(size_t size, int flag) +static inline void release_pack_memory(size_t size __used, int flag __used) { } @@ -59,7 +59,8 @@ void *xmemdupz(const void *data, size_t len) char *xstrndup(const char *str, size_t len) { char *p = memchr(str, '\0', len); - return xmemdupz(str, p ? p - str : len); + + return xmemdupz(str, p ? (size_t)(p - str) : len); } void *xrealloc(void *ptr, size_t size) -- cgit v1.2.3 From 43cbcd8acb4c992cbd22d1ec8a08c0591be5d719 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Wed, 1 Jul 2009 12:28:37 -0300 Subject: perf_counter tools: Share rbtree.with the kernel The tools/perf/util/rbtree.c copy already drifted by three csets: 4b324126e0c6c3a5080ca3ec0981e8766ed6f1ee 4c60117811171d867d4f27f17ea07d7419d45dae 16c047add3ceaf0ab882e3e094d1ec904d02312d So remove the copy and use the lib/rbtree.c directly, sharing the source code while still generating a separate object file, since tools/perf uses a far more agressive -O6 switch. Signed-off-by: Arnaldo Carvalho de Melo Cc: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Frederic Weisbecker LKML-Reference: <20090701152837.GG15682@ghostprotocols.net> Signed-off-by: Ingo Molnar --- tools/perf/Makefile | 7 +- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/util/callchain.h | 2 +- tools/perf/util/include/linux/kernel.h | 21 ++ tools/perf/util/include/linux/module.h | 6 + tools/perf/util/include/linux/rbtree.h | 1 + tools/perf/util/rbtree.c | 383 --------------------------------- tools/perf/util/rbtree.h | 171 --------------- tools/perf/util/strlist.h | 2 +- tools/perf/util/symbol.h | 2 +- 12 files changed, 39 insertions(+), 562 deletions(-) create mode 100644 tools/perf/util/include/linux/kernel.h create mode 100644 tools/perf/util/include/linux/module.h create mode 100644 tools/perf/util/include/linux/rbtree.h delete mode 100644 tools/perf/util/rbtree.c delete mode 100644 tools/perf/util/rbtree.h (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/Makefile b/tools/perf/Makefile index eddf076b19d7..c4f48825a6eb 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile @@ -223,7 +223,7 @@ SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ # Those must not be GNU-specific; they are shared with perl/ which may # be built by a different compiler. (Note that this is an artifact now # but it still might be nice to keep that distinction.) -BASIC_CFLAGS = +BASIC_CFLAGS = -Iutil/include BASIC_LDFLAGS = # Guard against environment variables @@ -289,10 +289,10 @@ export PERL_PATH LIB_FILE=libperf.a LIB_H += ../../include/linux/perf_counter.h +LIB_H += ../../include/linux/rbtree.h LIB_H += perf.h LIB_H += util/types.h LIB_H += util/list.h -LIB_H += util/rbtree.h LIB_H += util/levenshtein.h LIB_H += util/parse-options.h LIB_H += util/parse-events.h @@ -691,6 +691,9 @@ builtin-init-db.o: builtin-init-db.c PERF-CFLAGS util/config.o: util/config.c PERF-CFLAGS $(QUIET_CC)$(CC) -o $*.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< +util/rbtree.o: ../../lib/rbtree.c PERF-CFLAGS + $(QUIET_CC)$(CC) -o util/rbtree.o -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< + perf-%$X: %.o $(PERFLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 6cba70daf121..1960c22b816c 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -12,7 +12,7 @@ #include "util/color.h" #include "util/list.h" #include "util/cache.h" -#include "util/rbtree.h" +#include #include "util/symbol.h" #include "util/string.h" diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 007363db3b16..0d35e2b8881f 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -12,7 +12,7 @@ #include "util/color.h" #include "util/list.h" #include "util/cache.h" -#include "util/rbtree.h" +#include #include "util/symbol.h" #include "util/string.h" #include "util/callchain.h" diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 5f5e7df8302d..cdc74cfb1517 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -23,7 +23,7 @@ #include "util/symbol.h" #include "util/color.h" #include "util/util.h" -#include "util/rbtree.h" +#include #include "util/parse-options.h" #include "util/parse-events.h" diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 251d99ecd225..0606b8fd05a1 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -3,7 +3,7 @@ #include "../perf.h" #include "list.h" -#include "rbtree.h" +#include #include "symbol.h" diff --git a/tools/perf/util/include/linux/kernel.h b/tools/perf/util/include/linux/kernel.h new file mode 100644 index 000000000000..99c1b3d1edd9 --- /dev/null +++ b/tools/perf/util/include/linux/kernel.h @@ -0,0 +1,21 @@ +#ifndef PERF_LINUX_KERNEL_H_ +#define PERF_LINUX_KERNEL_H_ + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +#endif + +#ifndef container_of +/** + * container_of - cast a member of a structure out to the containing structure + * @ptr: the pointer to the member. + * @type: the type of the container struct this is embedded in. + * @member: the name of the member within the struct. + * + */ +#define container_of(ptr, type, member) ({ \ + const typeof(((type *)0)->member) * __mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) +#endif + +#endif diff --git a/tools/perf/util/include/linux/module.h b/tools/perf/util/include/linux/module.h new file mode 100644 index 000000000000..b43e2dc21e04 --- /dev/null +++ b/tools/perf/util/include/linux/module.h @@ -0,0 +1,6 @@ +#ifndef PERF_LINUX_MODULE_H +#define PERF_LINUX_MODULE_H + +#define EXPORT_SYMBOL(name) + +#endif diff --git a/tools/perf/util/include/linux/rbtree.h b/tools/perf/util/include/linux/rbtree.h new file mode 100644 index 000000000000..7a243a143037 --- /dev/null +++ b/tools/perf/util/include/linux/rbtree.h @@ -0,0 +1 @@ +#include "../../../../include/linux/rbtree.h" diff --git a/tools/perf/util/rbtree.c b/tools/perf/util/rbtree.c deleted file mode 100644 index b15ba9c7cb3f..000000000000 --- a/tools/perf/util/rbtree.c +++ /dev/null @@ -1,383 +0,0 @@ -/* - Red Black Trees - (C) 1999 Andrea Arcangeli - (C) 2002 David Woodhouse - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - linux/lib/rbtree.c -*/ - -#include "rbtree.h" - -static void __rb_rotate_left(struct rb_node *node, struct rb_root *root) -{ - struct rb_node *right = node->rb_right; - struct rb_node *parent = rb_parent(node); - - if ((node->rb_right = right->rb_left)) - rb_set_parent(right->rb_left, node); - right->rb_left = node; - - rb_set_parent(right, parent); - - if (parent) - { - if (node == parent->rb_left) - parent->rb_left = right; - else - parent->rb_right = right; - } - else - root->rb_node = right; - rb_set_parent(node, right); -} - -static void __rb_rotate_right(struct rb_node *node, struct rb_root *root) -{ - struct rb_node *left = node->rb_left; - struct rb_node *parent = rb_parent(node); - - if ((node->rb_left = left->rb_right)) - rb_set_parent(left->rb_right, node); - left->rb_right = node; - - rb_set_parent(left, parent); - - if (parent) - { - if (node == parent->rb_right) - parent->rb_right = left; - else - parent->rb_left = left; - } - else - root->rb_node = left; - rb_set_parent(node, left); -} - -void rb_insert_color(struct rb_node *node, struct rb_root *root) -{ - struct rb_node *parent, *gparent; - - while ((parent = rb_parent(node)) && rb_is_red(parent)) - { - gparent = rb_parent(parent); - - if (parent == gparent->rb_left) - { - { - register struct rb_node *uncle = gparent->rb_right; - if (uncle && rb_is_red(uncle)) - { - rb_set_black(uncle); - rb_set_black(parent); - rb_set_red(gparent); - node = gparent; - continue; - } - } - - if (parent->rb_right == node) - { - register struct rb_node *tmp; - __rb_rotate_left(parent, root); - tmp = parent; - parent = node; - node = tmp; - } - - rb_set_black(parent); - rb_set_red(gparent); - __rb_rotate_right(gparent, root); - } else { - { - register struct rb_node *uncle = gparent->rb_left; - if (uncle && rb_is_red(uncle)) - { - rb_set_black(uncle); - rb_set_black(parent); - rb_set_red(gparent); - node = gparent; - continue; - } - } - - if (parent->rb_left == node) - { - register struct rb_node *tmp; - __rb_rotate_right(parent, root); - tmp = parent; - parent = node; - node = tmp; - } - - rb_set_black(parent); - rb_set_red(gparent); - __rb_rotate_left(gparent, root); - } - } - - rb_set_black(root->rb_node); -} - -static void __rb_erase_color(struct rb_node *node, struct rb_node *parent, - struct rb_root *root) -{ - struct rb_node *other; - - while ((!node || rb_is_black(node)) && node != root->rb_node) - { - if (parent->rb_left == node) - { - other = parent->rb_right; - if (rb_is_red(other)) - { - rb_set_black(other); - rb_set_red(parent); - __rb_rotate_left(parent, root); - other = parent->rb_right; - } - if ((!other->rb_left || rb_is_black(other->rb_left)) && - (!other->rb_right || rb_is_black(other->rb_right))) - { - rb_set_red(other); - node = parent; - parent = rb_parent(node); - } - else - { - if (!other->rb_right || rb_is_black(other->rb_right)) - { - rb_set_black(other->rb_left); - rb_set_red(other); - __rb_rotate_right(other, root); - other = parent->rb_right; - } - rb_set_color(other, rb_color(parent)); - rb_set_black(parent); - rb_set_black(other->rb_right); - __rb_rotate_left(parent, root); - node = root->rb_node; - break; - } - } - else - { - other = parent->rb_left; - if (rb_is_red(other)) - { - rb_set_black(other); - rb_set_red(parent); - __rb_rotate_right(parent, root); - other = parent->rb_left; - } - if ((!other->rb_left || rb_is_black(other->rb_left)) && - (!other->rb_right || rb_is_black(other->rb_right))) - { - rb_set_red(other); - node = parent; - parent = rb_parent(node); - } - else - { - if (!other->rb_left || rb_is_black(other->rb_left)) - { - rb_set_black(other->rb_right); - rb_set_red(other); - __rb_rotate_left(other, root); - other = parent->rb_left; - } - rb_set_color(other, rb_color(parent)); - rb_set_black(parent); - rb_set_black(other->rb_left); - __rb_rotate_right(parent, root); - node = root->rb_node; - break; - } - } - } - if (node) - rb_set_black(node); -} - -void rb_erase(struct rb_node *node, struct rb_root *root) -{ - struct rb_node *child, *parent; - int color; - - if (!node->rb_left) - child = node->rb_right; - else if (!node->rb_right) - child = node->rb_left; - else - { - struct rb_node *old = node, *left; - - node = node->rb_right; - while ((left = node->rb_left) != NULL) - node = left; - child = node->rb_right; - parent = rb_parent(node); - color = rb_color(node); - - if (child) - rb_set_parent(child, parent); - if (parent == old) { - parent->rb_right = child; - parent = node; - } else - parent->rb_left = child; - - node->rb_parent_color = old->rb_parent_color; - node->rb_right = old->rb_right; - node->rb_left = old->rb_left; - - if (rb_parent(old)) - { - if (rb_parent(old)->rb_left == old) - rb_parent(old)->rb_left = node; - else - rb_parent(old)->rb_right = node; - } else - root->rb_node = node; - - rb_set_parent(old->rb_left, node); - if (old->rb_right) - rb_set_parent(old->rb_right, node); - goto color; - } - - parent = rb_parent(node); - color = rb_color(node); - - if (child) - rb_set_parent(child, parent); - if (parent) - { - if (parent->rb_left == node) - parent->rb_left = child; - else - parent->rb_right = child; - } - else - root->rb_node = child; - - color: - if (color == RB_BLACK) - __rb_erase_color(child, parent, root); -} - -/* - * This function returns the first node (in sort order) of the tree. - */ -struct rb_node *rb_first(const struct rb_root *root) -{ - struct rb_node *n; - - n = root->rb_node; - if (!n) - return NULL; - while (n->rb_left) - n = n->rb_left; - return n; -} - -struct rb_node *rb_last(const struct rb_root *root) -{ - struct rb_node *n; - - n = root->rb_node; - if (!n) - return NULL; - while (n->rb_right) - n = n->rb_right; - return n; -} - -struct rb_node *rb_next(const struct rb_node *node) -{ - struct rb_node *parent; - - if (rb_parent(node) == node) - return NULL; - - /* If we have a right-hand child, go down and then left as far - as we can. */ - if (node->rb_right) { - node = node->rb_right; - while (node->rb_left) - node=node->rb_left; - return (struct rb_node *)node; - } - - /* No right-hand children. Everything down and left is - smaller than us, so any 'next' node must be in the general - direction of our parent. Go up the tree; any time the - ancestor is a right-hand child of its parent, keep going - up. First time it's a left-hand child of its parent, said - parent is our 'next' node. */ - while ((parent = rb_parent(node)) && node == parent->rb_right) - node = parent; - - return parent; -} - -struct rb_node *rb_prev(const struct rb_node *node) -{ - struct rb_node *parent; - - if (rb_parent(node) == node) - return NULL; - - /* If we have a left-hand child, go down and then right as far - as we can. */ - if (node->rb_left) { - node = node->rb_left; - while (node->rb_right) - node=node->rb_right; - return (struct rb_node *)node; - } - - /* No left-hand children. Go up till we find an ancestor which - is a right-hand child of its parent */ - while ((parent = rb_parent(node)) && node == parent->rb_left) - node = parent; - - return parent; -} - -void rb_replace_node(struct rb_node *victim, struct rb_node *new, - struct rb_root *root) -{ - struct rb_node *parent = rb_parent(victim); - - /* Set the surrounding nodes to point to the replacement */ - if (parent) { - if (victim == parent->rb_left) - parent->rb_left = new; - else - parent->rb_right = new; - } else { - root->rb_node = new; - } - if (victim->rb_left) - rb_set_parent(victim->rb_left, new); - if (victim->rb_right) - rb_set_parent(victim->rb_right, new); - - /* Copy the pointers/colour from the victim to the replacement */ - *new = *victim; -} diff --git a/tools/perf/util/rbtree.h b/tools/perf/util/rbtree.h deleted file mode 100644 index 6bdc488a47fb..000000000000 --- a/tools/perf/util/rbtree.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - Red Black Trees - (C) 1999 Andrea Arcangeli - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - linux/include/linux/rbtree.h - - To use rbtrees you'll have to implement your own insert and search cores. - This will avoid us to use callbacks and to drop drammatically performances. - I know it's not the cleaner way, but in C (not in C++) to get - performances and genericity... - - Some example of insert and search follows here. The search is a plain - normal search over an ordered tree. The insert instead must be implemented - int two steps: as first thing the code must insert the element in - order as a red leaf in the tree, then the support library function - rb_insert_color() must be called. Such function will do the - not trivial work to rebalance the rbtree if necessary. - ------------------------------------------------------------------------ -static inline struct page * rb_search_page_cache(struct inode * inode, - unsigned long offset) -{ - struct rb_node * n = inode->i_rb_page_cache.rb_node; - struct page * page; - - while (n) - { - page = rb_entry(n, struct page, rb_page_cache); - - if (offset < page->offset) - n = n->rb_left; - else if (offset > page->offset) - n = n->rb_right; - else - return page; - } - return NULL; -} - -static inline struct page * __rb_insert_page_cache(struct inode * inode, - unsigned long offset, - struct rb_node * node) -{ - struct rb_node ** p = &inode->i_rb_page_cache.rb_node; - struct rb_node * parent = NULL; - struct page * page; - - while (*p) - { - parent = *p; - page = rb_entry(parent, struct page, rb_page_cache); - - if (offset < page->offset) - p = &(*p)->rb_left; - else if (offset > page->offset) - p = &(*p)->rb_right; - else - return page; - } - - rb_link_node(node, parent, p); - - return NULL; -} - -static inline struct page * rb_insert_page_cache(struct inode * inode, - unsigned long offset, - struct rb_node * node) -{ - struct page * ret; - if ((ret = __rb_insert_page_cache(inode, offset, node))) - goto out; - rb_insert_color(node, &inode->i_rb_page_cache); - out: - return ret; -} ------------------------------------------------------------------------ -*/ - -#ifndef _LINUX_RBTREE_H -#define _LINUX_RBTREE_H - -#include - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -struct rb_node -{ - unsigned long rb_parent_color; -#define RB_RED 0 -#define RB_BLACK 1 - struct rb_node *rb_right; - struct rb_node *rb_left; -} __attribute__((aligned(sizeof(long)))); - /* The alignment might seem pointless, but allegedly CRIS needs it */ - -struct rb_root -{ - struct rb_node *rb_node; -}; - - -#define rb_parent(r) ((struct rb_node *)((r)->rb_parent_color & ~3)) -#define rb_color(r) ((r)->rb_parent_color & 1) -#define rb_is_red(r) (!rb_color(r)) -#define rb_is_black(r) rb_color(r) -#define rb_set_red(r) do { (r)->rb_parent_color &= ~1; } while (0) -#define rb_set_black(r) do { (r)->rb_parent_color |= 1; } while (0) - -static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p) -{ - rb->rb_parent_color = (rb->rb_parent_color & 3) | (unsigned long)p; -} -static inline void rb_set_color(struct rb_node *rb, int color) -{ - rb->rb_parent_color = (rb->rb_parent_color & ~1) | color; -} - -#define RB_ROOT (struct rb_root) { NULL, } -#define rb_entry(ptr, type, member) container_of(ptr, type, member) - -#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) -#define RB_EMPTY_NODE(node) (rb_parent(node) == node) -#define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) - -extern void rb_insert_color(struct rb_node *, struct rb_root *); -extern void rb_erase(struct rb_node *, struct rb_root *); - -/* Find logical next and previous nodes in a tree */ -extern struct rb_node *rb_next(const struct rb_node *); -extern struct rb_node *rb_prev(const struct rb_node *); -extern struct rb_node *rb_first(const struct rb_root *); -extern struct rb_node *rb_last(const struct rb_root *); - -/* Fast replacement of a single node without remove/rebalance/add/rebalance */ -extern void rb_replace_node(struct rb_node *victim, struct rb_node *new, - struct rb_root *root); - -static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, - struct rb_node ** rb_link) -{ - node->rb_parent_color = (unsigned long )parent; - node->rb_left = node->rb_right = NULL; - - *rb_link = node; -} - -#endif /* _LINUX_RBTREE_H */ diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 2fb117fb4b67..2fdcfee87586 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h @@ -1,7 +1,7 @@ #ifndef STRLIST_H_ #define STRLIST_H_ -#include "rbtree.h" +#include #include struct str_node { diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 2c48ace8203b..3a275db1fa64 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -4,7 +4,7 @@ #include #include "types.h" #include "list.h" -#include "rbtree.h" +#include struct symbol { struct rb_node rb_node; -- cgit v1.2.3 From 9974f496782b7612e36a143bedda858f1cb953d4 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 2 Jul 2009 08:05:58 +0200 Subject: perf_counter tools: Make symbol loading consistently return number of loaded symbols perf_counter tools: Make symbol loading consistently return number of loaded symbols. Signed-off-by: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: <1246514758.13293.42.camel@marge.simson.net> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/util/symbol.c | 9 ++++++--- 4 files changed, 9 insertions(+), 6 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 132de8b28dbb..3becc8a35bee 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -172,7 +172,7 @@ static int load_kernel(void) return -1; err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); - if (err) { + if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; } else diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index be1b7584796d..58d1612894ff 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -189,7 +189,7 @@ static int load_kernel(void) return -1; err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); - if (err) { + if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; } else diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index cdc74cfb1517..97fde1d84365 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -364,7 +364,7 @@ static int parse_symbols(void) if (kernel_dso == NULL) return -1; - if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1) != 0) + if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1) <= 0) goto out_delete_dso; node = rb_first(&kernel_dso->syms); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 78c2efde01b7..c077b6a14690 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -146,6 +146,7 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb char *line = NULL; size_t n; FILE *file = fopen("/proc/kallsyms", "r"); + int count = 0; if (file == NULL) goto out_failure; @@ -188,8 +189,10 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb if (filter && filter(self, sym)) symbol__delete(sym, self->sym_priv_size); - else + else { dso__insert_symbol(self, sym); + count++; + } } /* @@ -212,7 +215,7 @@ static int dso__load_kallsyms(struct dso *self, symbol_filter_t filter, int verb free(line); fclose(file); - return 0; + return count; out_delete_line: free(line); @@ -639,7 +642,7 @@ int dso__load_kernel(struct dso *self, const char *vmlinux, if (vmlinux) err = dso__load_vmlinux(self, vmlinux, filter, verbose); - if (err < 0) + if (err <= 0) err = dso__load_kallsyms(self, filter, verbose); return err; -- cgit v1.2.3 From 6cfcc53ed4f3ecb9319e73a03f34f1eddcb644dd Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 2 Jul 2009 08:08:36 +0200 Subject: perf_counter tools: Connect module support infrastructure to symbol loading infrastructure Signed-off-by: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: <1246514916.13293.46.camel@marge.simson.net> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 2 +- tools/perf/builtin-report.c | 2 +- tools/perf/builtin-top.c | 2 +- tools/perf/util/symbol.c | 159 +++++++++++++++++++++++++++++++++++++++--- tools/perf/util/symbol.h | 5 +- 5 files changed, 156 insertions(+), 14 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 3becc8a35bee..88205686eb6e 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -171,7 +171,7 @@ static int load_kernel(void) if (!kernel_dso) return -1; - err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); + err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, 0); if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 58d1612894ff..38d136fedfb9 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -188,7 +188,7 @@ static int load_kernel(void) if (!kernel_dso) return -1; - err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose); + err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, 0); if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 97fde1d84365..9bb25fc3d4ce 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -364,7 +364,7 @@ static int parse_symbols(void) if (kernel_dso == NULL) return -1; - if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1) <= 0) + if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1, 0) <= 0) goto out_delete_dso; node = rb_first(&kernel_dso->syms); diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index c077b6a14690..98a13114de70 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -35,7 +35,7 @@ static struct symbol *symbol__new(u64 start, u64 len, self = ((void *)self) + priv_size; } self->start = start; - self->end = start + len - 1; + self->end = len ? start + len - 1 : start; memcpy(self->name, name, namelen); return self; @@ -48,8 +48,12 @@ static void symbol__delete(struct symbol *self, unsigned int priv_size) static size_t symbol__fprintf(struct symbol *self, FILE *fp) { - return fprintf(fp, " %llx-%llx %s\n", + if (!self->module) + return fprintf(fp, " %llx-%llx %s\n", self->start, self->end, self->name); + else + return fprintf(fp, " %llx-%llx %s \t[%s]\n", + self->start, self->end, self->name, self->module->name); } struct dso *dso__new(const char *name, unsigned int sym_priv_size) @@ -310,6 +314,26 @@ static inline int elf_sym__is_function(const GElf_Sym *sym) sym->st_size != 0; } +static inline int elf_sym__is_label(const GElf_Sym *sym) +{ + return elf_sym__type(sym) == STT_NOTYPE && + sym->st_name != 0 && + sym->st_shndx != SHN_UNDEF && + sym->st_shndx != SHN_ABS; +} + +static inline const char *elf_sec__name(const GElf_Shdr *shdr, + const Elf_Data *secstrs) +{ + return secstrs->d_buf + shdr->sh_name; +} + +static inline int elf_sec__is_text(const GElf_Shdr *shdr, + const Elf_Data *secstrs) +{ + return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; +} + static inline const char *elf_sym__name(const GElf_Sym *sym, const Elf_Data *symstrs) { @@ -451,9 +475,9 @@ static int dso__synthesize_plt_symbols(struct dso *self, Elf *elf, } static int dso__load_sym(struct dso *self, int fd, const char *name, - symbol_filter_t filter, int verbose) + symbol_filter_t filter, int verbose, struct module *mod) { - Elf_Data *symstrs; + Elf_Data *symstrs, *secstrs; uint32_t nr_syms; int err = -1; uint32_t index; @@ -461,7 +485,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, GElf_Shdr shdr; Elf_Data *syms; GElf_Sym sym; - Elf_Scn *sec, *sec_dynsym; + Elf_Scn *sec, *sec_dynsym, *sec_strndx; Elf *elf; size_t dynsym_idx; int nr = 0; @@ -520,6 +544,14 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, if (symstrs == NULL) goto out_elf_end; + sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); + if (sec_strndx == NULL) + goto out_elf_end; + + secstrs = elf_getdata(sec_strndx, NULL); + if (symstrs == NULL) + goto out_elf_end; + nr_syms = shdr.sh_size / shdr.sh_entsize; memset(&sym, 0, sizeof(sym)); @@ -529,8 +561,11 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, elf_symtab__for_each_symbol(syms, nr_syms, index, sym) { struct symbol *f; u64 obj_start; + struct section *section = NULL; + int is_label = elf_sym__is_label(&sym); + const char *section_name; - if (!elf_sym__is_function(&sym)) + if (!is_label && !elf_sym__is_function(&sym)) continue; sec = elf_getscn(elf, sym.st_shndx); @@ -538,6 +573,11 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, goto out_elf_end; gelf_getshdr(sec, &shdr); + + if (is_label && !elf_sec__is_text(&shdr, secstrs)) + continue; + + section_name = elf_sec__name(&shdr, secstrs); obj_start = sym.st_value; if (self->prelinked) { @@ -548,6 +588,17 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, sym.st_value -= shdr.sh_addr - shdr.sh_offset; } + if (mod) { + section = mod->sections->find_section(mod->sections, section_name); + if (section) + sym.st_value += section->vma; + else { + fprintf(stderr, "dso__load_sym() module %s lookup of %s failed\n", + mod->name, section_name); + goto out_elf_end; + } + } + f = symbol__new(sym.st_value, sym.st_size, elf_sym__name(&sym, symstrs), self->sym_priv_size, obj_start, verbose); @@ -557,6 +608,7 @@ static int dso__load_sym(struct dso *self, int fd, const char *name, if (filter && filter(self, f)) symbol__delete(f, self->sym_priv_size); else { + f->module = mod; dso__insert_symbol(self, f); nr++; } @@ -606,7 +658,7 @@ more: fd = open(name, O_RDONLY); } while (fd < 0); - ret = dso__load_sym(self, fd, name, filter, verbose); + ret = dso__load_sym(self, fd, name, filter, verbose, NULL); close(fd); /* @@ -620,6 +672,86 @@ out: return ret; } +static int dso__load_module(struct dso *self, struct mod_dso *mods, const char *name, + symbol_filter_t filter, int verbose) +{ + struct module *mod = mod_dso__find_module(mods, name); + int err = 0, fd; + + if (mod == NULL || !mod->active) + return err; + + fd = open(mod->path, O_RDONLY); + + if (fd < 0) + return err; + + err = dso__load_sym(self, fd, name, filter, verbose, mod); + close(fd); + + return err; +} + +int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose) +{ + struct mod_dso *mods = mod_dso__new_dso("modules"); + struct module *pos; + struct rb_node *next; + int err; + + err = mod_dso__load_modules(mods); + + if (err <= 0) + return err; + + /* + * Iterate over modules, and load active symbols. + */ + next = rb_first(&mods->mods); + while (next) { + pos = rb_entry(next, struct module, rb_node); + err = dso__load_module(self, mods, pos->name, filter, verbose); + + if (err < 0) + break; + + next = rb_next(&pos->rb_node); + } + + if (err < 0) { + mod_dso__delete_modules(mods); + mod_dso__delete_self(mods); + } + + return err; +} + +static inline void dso__fill_symbol_holes(struct dso *self) +{ + struct symbol *prev = NULL; + struct rb_node *nd; + + for (nd = rb_last(&self->syms); nd; nd = rb_prev(nd)) { + struct symbol *pos = rb_entry(nd, struct symbol, rb_node); + + if (prev) { + u64 hole = 0; + int alias = pos->start == prev->start; + + if (!alias) + hole = prev->start - pos->end - 1; + + if (hole || alias) { + if (alias) + pos->end = prev->end; + else if (hole) + pos->end = prev->start - 1; + } + } + prev = pos; + } +} + static int dso__load_vmlinux(struct dso *self, const char *vmlinux, symbol_filter_t filter, int verbose) { @@ -628,19 +760,26 @@ static int dso__load_vmlinux(struct dso *self, const char *vmlinux, if (fd < 0) return -1; - err = dso__load_sym(self, fd, vmlinux, filter, verbose); + err = dso__load_sym(self, fd, vmlinux, filter, verbose, NULL); + + if (err > 0) + dso__fill_symbol_holes(self); + close(fd); return err; } int dso__load_kernel(struct dso *self, const char *vmlinux, - symbol_filter_t filter, int verbose) + symbol_filter_t filter, int verbose, int modules) { int err = -1; - if (vmlinux) + if (vmlinux) { err = dso__load_vmlinux(self, vmlinux, filter, verbose); + if (err > 0 && modules) + err = dso__load_modules(self, filter, verbose); + } if (err <= 0) err = dso__load_kallsyms(self, filter, verbose); diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 65a8449b91f5..4e141a30911e 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -5,6 +5,7 @@ #include "types.h" #include #include +#include "module.h" struct symbol { struct rb_node rb_node; @@ -13,6 +14,7 @@ struct symbol { u64 obj_start; u64 hist_sum; u64 *hist; + struct module *module; void *priv; char name[0]; }; @@ -41,7 +43,8 @@ static inline void *dso__sym_priv(struct dso *self, struct symbol *sym) struct symbol *dso__find_symbol(struct dso *self, u64 ip); int dso__load_kernel(struct dso *self, const char *vmlinux, - symbol_filter_t filter, int verbose); + symbol_filter_t filter, int verbose, int modules); +int dso__load_modules(struct dso *self, symbol_filter_t filter, int verbose); int dso__load(struct dso *self, symbol_filter_t filter, int verbose); size_t dso__fprintf(struct dso *self, FILE *fp); -- cgit v1.2.3 From 429764873cf3fc3e73142872a674bb27cda589c1 Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Thu, 2 Jul 2009 08:09:46 +0200 Subject: perf_counter tools: Enable kernel module symbol loading in tools Add the -m/--modules option to perf report and perf annotate, which enables live module symbol/image loading. To be used with -k/--vmlinux. (Also give perf annotate a -P/--full-paths option.) Signed-off-by: Mike Galbraith Cc: Peter Zijlstra Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo LKML-Reference: <1246514986.13293.48.camel@marge.simson.net> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 25 ++++++++++++++++++++----- tools/perf/builtin-report.c | 9 ++++++++- tools/perf/builtin-top.c | 12 ++++++++++-- 3 files changed, 38 insertions(+), 8 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 88205686eb6e..08ea6c5329d9 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -43,6 +43,10 @@ static int dump_trace = 0; static int verbose; +static int modules; + +static int full_paths; + static int print_line; static unsigned long page_size; @@ -171,7 +175,7 @@ static int load_kernel(void) if (!kernel_dso) return -1; - err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, 0); + err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; @@ -1268,19 +1272,25 @@ static void print_summary(char *filename) static void annotate_sym(struct dso *dso, struct symbol *sym) { - char *filename = dso->name; + char *filename = dso->name, *d_filename; u64 start, end, len; char command[PATH_MAX*2]; FILE *file; if (!filename) return; - if (dso == kernel_dso) + if (sym->module) + filename = sym->module->path; + else if (dso == kernel_dso) filename = vmlinux; start = sym->obj_start; if (!start) start = sym->start; + if (full_paths) + d_filename = filename; + else + d_filename = basename(filename); end = start + sym->end - sym->start + 1; len = sym->end - sym->start; @@ -1291,13 +1301,14 @@ static void annotate_sym(struct dso *dso, struct symbol *sym) } printf("\n\n------------------------------------------------\n"); - printf(" Percent | Source code & Disassembly of %s\n", filename); + printf(" Percent | Source code & Disassembly of %s\n", d_filename); printf("------------------------------------------------\n"); if (verbose >= 2) printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name); - sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s", (u64)start, (u64)end, filename); + sprintf(command, "objdump --start-address=0x%016Lx --stop-address=0x%016Lx -dS %s|grep -v %s", + (u64)start, (u64)end, filename, filename); if (verbose >= 3) printf("doing: %s\n", command); @@ -1472,8 +1483,12 @@ static const struct option options[] = { OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), + OPT_BOOLEAN('m', "modules", &modules, + "load module symbols - WARNING: use only with -k and LIVE kernel"), OPT_BOOLEAN('l', "print-line", &print_line, "print matching source lines (may be slow)"), + OPT_BOOLEAN('P', "full-paths", &full_paths, + "Don't shorten the displayed pathnames"), OPT_END() }; diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 38d136fedfb9..b44476ca2398 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -46,6 +46,8 @@ static int dump_trace = 0; static int verbose; #define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0) +static int modules; + static int full_paths; static unsigned long page_size; @@ -188,7 +190,7 @@ static int load_kernel(void) if (!kernel_dso) return -1; - err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, 0); + err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); if (err <= 0) { dso__delete(kernel_dso); kernel_dso = NULL; @@ -648,6 +650,9 @@ sort__sym_print(FILE *fp, struct hist_entry *self) ret += fprintf(fp, "[%c] %s", self->dso == kernel_dso ? 'k' : self->dso == hypervisor_dso ? 'h' : '.', self->sym->name); + + if (self->sym->module) + ret += fprintf(fp, "\t[%s]", self->sym->module->name); } else { ret += fprintf(fp, "%#016llx", (u64)self->ip); } @@ -1710,6 +1715,8 @@ static const struct option options[] = { OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), + OPT_BOOLEAN('m', "modules", &modules, + "load module symbols - WARNING: use only with -k and LIVE kernel"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), OPT_BOOLEAN('P', "full-paths", &full_paths, diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 9bb25fc3d4ce..aa044ea1482b 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -66,6 +66,7 @@ static unsigned int page_size; static unsigned int mmap_pages = 16; static int freq = 0; static int verbose = 0; +static char *vmlinux = NULL; static char *sym_filter; static unsigned long filter_start; @@ -265,7 +266,10 @@ static void print_sym_table(void) printf("%9.1f %10ld - ", syme->weight, syme->snap_count); color_fprintf(stdout, color, "%4.1f%%", pcnt); - printf(" - %016llx : %s\n", sym->start, sym->name); + printf(" - %016llx : %s", sym->start, sym->name); + if (sym->module) + printf("\t[%s]", sym->module->name); + printf("\n"); } } @@ -359,12 +363,13 @@ static int parse_symbols(void) { struct rb_node *node; struct symbol *sym; + int modules = vmlinux ? 1 : 0; kernel_dso = dso__new("[kernel]", sizeof(struct sym_entry)); if (kernel_dso == NULL) return -1; - if (dso__load_kernel(kernel_dso, NULL, symbol_filter, 1, 0) <= 0) + if (dso__load_kernel(kernel_dso, vmlinux, symbol_filter, verbose, modules) <= 0) goto out_delete_dso; node = rb_first(&kernel_dso->syms); @@ -680,6 +685,7 @@ static const struct option options[] = { "system-wide collection from all CPUs"), OPT_INTEGER('C', "CPU", &profile_cpu, "CPU to profile on"), + OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), OPT_INTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), OPT_INTEGER('r', "realtime", &realtime_prio, @@ -709,6 +715,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) { int counter; + symbol__init(); + page_size = sysconf(_SC_PAGE_SIZE); argc = parse_options(argc, argv, options, top_usage, 0); -- cgit v1.2.3 From 1e11fd82d247e4e48a1d6c49402214434538d3fd Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Thu, 2 Jul 2009 20:14:34 +0200 Subject: perf_counter tools: Provide helper to print percents color Among perf annotate, perf report and perf top, we can find the common colored printing of percents according to the following rules: High overhead = > 5%, colored in red Mid overhead = > 0.5%, colored in green Low overhead = < 0.5%, default color Factorize these multiple checks in a single function named percent_color_fprintf() and also provide a get_percent_color() for sites which print percentages and other things at the same time. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Paul Mackerras Cc: Anton Blanchard Cc: Arnaldo Carvalho de Melo LKML-Reference: <1246558475-10624-2-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-annotate.c | 26 ++------------------------ tools/perf/builtin-report.c | 21 +++------------------ tools/perf/builtin-top.c | 15 +-------------- tools/perf/util/color.c | 27 +++++++++++++++++++++++++++ tools/perf/util/color.h | 5 +++++ 5 files changed, 38 insertions(+), 56 deletions(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 08ea6c5329d9..5f9eefecc574 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c @@ -25,10 +25,6 @@ #define SHOW_USER 2 #define SHOW_HV 4 -#define MIN_GREEN 0.5 -#define MIN_RED 5.0 - - static char const *input_name = "perf.data"; static char *vmlinux = "vmlinux"; @@ -1047,24 +1043,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head) return 0; } -static char *get_color(double percent) -{ - char *color = PERF_COLOR_NORMAL; - - /* - * We color high-overhead entries in red, mid-overhead - * entries in green - and keep the low overhead places - * normal: - */ - if (percent >= MIN_RED) - color = PERF_COLOR_RED; - else { - if (percent > MIN_GREEN) - color = PERF_COLOR_GREEN; - } - return color; -} - static int parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) { @@ -1126,7 +1104,7 @@ parse_line(FILE *file, struct symbol *sym, u64 start, u64 len) } else if (sym->hist_sum) percent = 100.0 * hits / sym->hist_sum; - color = get_color(percent); + color = get_percent_color(percent); /* * Also color the filename and line if needed, with @@ -1262,7 +1240,7 @@ static void print_summary(char *filename) sym_ext = rb_entry(node, struct sym_ext, node); percent = sym_ext->percent; - color = get_color(percent); + color = get_percent_color(percent); path = sym_ext->path; color_fprintf(stdout, color, " %7.2f %s", percent, path); diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e8c98179fe45..c9dbe3315497 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -947,25 +947,10 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, u64 total_samples) if (exclude_other && !self->parent) return 0; - if (total_samples) { - double percent = self->count * 100.0 / total_samples; - char *color = PERF_COLOR_NORMAL; - - /* - * We color high-overhead entries in red, mid-overhead - * entries in green - and keep the low overhead places - * normal: - */ - if (percent >= 5.0) { - color = PERF_COLOR_RED; - } else { - if (percent >= 0.5) - color = PERF_COLOR_GREEN; - } - - ret = color_fprintf(fp, color, " %6.2f%%", + if (total_samples) + ret = percent_color_fprintf(fp, " %6.2f%%", (self->count * 100.0) / total_samples); - } else + else ret = fprintf(fp, "%12Ld ", self->count); list_for_each_entry(se, &hist_entry__sort_list, list) { diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index aa044ea1482b..95d5c0ae375a 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -239,7 +239,6 @@ static void print_sym_table(void) for (nd = rb_first(&tmp); nd; nd = rb_next(nd)) { struct sym_entry *syme = rb_entry(nd, struct sym_entry, rb_node); struct symbol *sym = (struct symbol *)(syme + 1); - char *color = PERF_COLOR_NORMAL; double pcnt; if (++printed > print_entries || syme->snap_count < count_filter) @@ -248,24 +247,12 @@ static void print_sym_table(void) pcnt = 100.0 - (100.0 * ((sum_ksamples - syme->snap_count) / sum_ksamples)); - /* - * We color high-overhead entries in red, mid-overhead - * entries in green - and keep the low overhead places - * normal: - */ - if (pcnt >= 5.0) { - color = PERF_COLOR_RED; - } else { - if (pcnt >= 0.5) - color = PERF_COLOR_GREEN; - } - if (nr_counters == 1) printf("%20.2f - ", syme->weight); else printf("%9.1f %10ld - ", syme->weight, syme->snap_count); - color_fprintf(stdout, color, "%4.1f%%", pcnt); + percent_color_fprintf(stdout, "%4.1f%%", pcnt); printf(" - %016llx : %s", sym->start, sym->name); if (sym->module) printf("\t[%s]", sym->module->name); diff --git a/tools/perf/util/color.c b/tools/perf/util/color.c index 26f82318b86b..90a044d1fe7d 100644 --- a/tools/perf/util/color.c +++ b/tools/perf/util/color.c @@ -242,4 +242,31 @@ int color_fwrite_lines(FILE *fp, const char *color, return 0; } +char *get_percent_color(double percent) +{ + char *color = PERF_COLOR_NORMAL; + + /* + * We color high-overhead entries in red, mid-overhead + * entries in green - and keep the low overhead places + * normal: + */ + if (percent >= MIN_RED) + color = PERF_COLOR_RED; + else { + if (percent > MIN_GREEN) + color = PERF_COLOR_GREEN; + } + return color; +} +int percent_color_fprintf(FILE *fp, const char *fmt, double percent) +{ + int r; + char *color; + + color = get_percent_color(percent); + r = color_fprintf(fp, color, fmt, percent); + + return r; +} diff --git a/tools/perf/util/color.h b/tools/perf/util/color.h index 5abfd379582b..706cec50bd25 100644 --- a/tools/perf/util/color.h +++ b/tools/perf/util/color.h @@ -15,6 +15,9 @@ #define PERF_COLOR_CYAN "\033[36m" #define PERF_COLOR_BG_RED "\033[41m" +#define MIN_GREEN 0.5 +#define MIN_RED 5.0 + /* * This variable stores the value of color.ui */ @@ -32,5 +35,7 @@ void color_parse_mem(const char *value, int len, const char *var, char *dst); int color_fprintf(FILE *fp, const char *color, const char *fmt, ...); int color_fprintf_ln(FILE *fp, const char *color, const char *fmt, ...); int color_fwrite_lines(FILE *fp, const char *color, size_t count, const char *buf); +int percent_color_fprintf(FILE *fp, const char *fmt, double percent); +char *get_percent_color(double percent); #endif /* COLOR_H */ -- cgit v1.2.3 From 0fdc7e67dd312986e30b861adff48732bd33eb3f Mon Sep 17 00:00:00 2001 From: Mike Galbraith Date: Tue, 21 Jul 2009 10:30:36 +0200 Subject: perf_counter tools: Give perf top inherit option Currently, perf top -p only tracks the pid provided, which isn't very useful for watching forky loads, so give it an inherit option. Signed-off-by: Mike Galbraith Cc: Ingo Molnar Signed-off-by: Peter Zijlstra LKML-Reference: <1248165036.9795.10.camel@marge.simson.net> --- tools/perf/builtin-top.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 95d5c0ae375a..c0a423004e15 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -58,6 +58,7 @@ static u64 count_filter = 5; static int print_entries = 15; static int target_pid = -1; +static int inherit = 0; static int profile_cpu = -1; static int nr_cpus = 0; static unsigned int realtime_prio = 0; @@ -549,7 +550,7 @@ int group_fd; static void start_counter(int i, int counter) { struct perf_counter_attr *attr; - unsigned int cpu; + int cpu; cpu = profile_cpu; if (target_pid == -1 && profile_cpu == -1) @@ -559,6 +560,7 @@ static void start_counter(int i, int counter) attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; attr->freq = freq; + attr->inherit = (cpu < 0) && inherit; try_again: fd[i][counter] = sys_perf_counter_open(attr, target_pid, cpu, group_fd, 0); @@ -685,6 +687,8 @@ static const struct option options[] = { "only display functions with more events than this"), OPT_BOOLEAN('g', "group", &group, "put the counters into a counter group"), + OPT_BOOLEAN('i', "inherit", &inherit, + "child tasks inherit counters"), OPT_STRING('s', "sym-filter", &sym_filter, "pattern", "only display symbols matchig this pattern"), OPT_BOOLEAN('z', "zero", &zero, -- cgit v1.2.3 From 59b9005692d4c8b5d73cfc41aa7229f47be163a9 Mon Sep 17 00:00:00 2001 From: Arnaldo Carvalho de Melo Date: Sun, 26 Jul 2009 19:06:19 -0300 Subject: perf top: Add mwait_idle_with_hints to skip_symbols[] We skip the display of idle routine related symbols because they are typically rather erratic and confusing: they depend on the IRQ rate or sometimes they dominate the profile if they are polling based. Add mwait_idle_with_hints too, this is one of the idle routines on x86. Signed-off-by: Arnaldo Carvalho de Melo Signed-off-by: Ingo Molnar --- tools/perf/builtin-top.c | 1 + 1 file changed, 1 insertion(+) (limited to 'tools/perf/builtin-top.c') diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index c0a423004e15..f139f1ab9333 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c @@ -285,6 +285,7 @@ static const char *skip_symbols[] = { "enter_idle", "exit_idle", "mwait_idle", + "mwait_idle_with_hints", "ppc64_runlatch_off", "pseries_dedicated_idle_sleep", NULL -- cgit v1.2.3