From 8d51327090ac025d7f4ce6c059786b5e93513321 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Fri, 7 Aug 2009 13:55:24 +0200 Subject: perf report: Fix and improve the displaying of per-thread event counters Improve and fix the handling of per-thread counter stats recorded via perf record -s. Previously we only displayed it in debug printouts (-D) and even that output was hard to disambiguate. I moved everything to utils/values.[ch] so that we may reuse it in perf stat. We get something like this now: # PID TID cache-misses cache-references 4658 4659 495581 3238779 4658 4662 498246 3236823 4658 4663 499531 3243162 Then it'll be easy to add --pretty=raw to display a single line per thread/event. By the way, -S was also used for --symbol... So I used -T/--thread here. perf report: Add -T/--threads to display per-thread counter values We get something like this now: # PID TID cache-misses cache-references 4658 4659 495581 3238779 4658 4662 498246 3236823 4658 4663 499531 3243162 Per-thread arrays of counter values are managed in utils/values.[ch] Signed-off-by: Brice Goglin Cc: Peter Zijlstra Cc: paulus@samba.org Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 99274cec0adb..41639182fb3f 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -17,6 +17,7 @@ #include "util/string.h" #include "util/callchain.h" #include "util/strlist.h" +#include "util/values.h" #include "perf.h" #include "util/header.h" @@ -53,6 +54,9 @@ static int modules; static int full_paths; static int show_nr_samples; +static int show_threads; +static struct perf_read_values show_threads_values; + static unsigned long page_size; static unsigned long mmap_window = 32; @@ -1473,6 +1477,9 @@ print_entries: free(rem_sq_bracket); + if (show_threads) + perf_read_values_display(fp, &show_threads_values); + return ret; } @@ -1758,6 +1765,16 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head) { struct perf_counter_attr *attr = perf_header__find_attr(event->read.id); + if (show_threads) { + char *name = attr ? __event_name(attr->type, attr->config) + : "unknown"; + perf_read_values_add_value(&show_threads_values, + event->read.pid, event->read.tid, + event->read.id, + name, + event->read.value); + } + dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n", (void *)(offset + head), (void *)(long)(event->header.size), @@ -1839,6 +1856,9 @@ static int __cmd_report(void) register_idle_thread(); + if (show_threads) + perf_read_values_init(&show_threads_values); + input = open(input_name, O_RDONLY); if (input < 0) { fprintf(stderr, " failed to open file: %s", input_name); @@ -1993,6 +2013,9 @@ done: output__resort(total); output__fprintf(stdout, total); + if (show_threads) + perf_read_values_destroy(&show_threads_values); + return rc; } @@ -2066,6 +2089,8 @@ static const struct option options[] = { "load module symbols - WARNING: use only with -k and LIVE kernel"), OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples, "Show a column with the number of samples"), + OPT_BOOLEAN('T', "threads", &show_threads, + "Show per-thread event counters"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), OPT_BOOLEAN('P', "full-paths", &full_paths, -- cgit From 9f8666971185b86615a074bcac67c90fdf8af8bc Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 10 Aug 2009 15:26:32 +0200 Subject: perf report: Add raw displaying of per-thread counters If --pretty=raw is given to perf report -T, it now displays one line per-thread per-counter with the raw event id added. We get: # PID TID Name Raw Count 18608 18609 cache-misses 28e 416744 18608 18609 cache-references 28f 6456792 18608 18608 cache-misses 28e 448219 18608 18608 cache-references 28f 7270244 instead of: # PID TID cache-misses cache-references 18608 18609 416744 6456792 18608 18608 448219 7270244 Signed-off-by: Brice Goglin Acked-by: Peter Zijlstra LKML-Reference: <4A802008.5050409@inria.fr> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 41639182fb3f..2357c66fb91d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -57,6 +57,9 @@ static int show_nr_samples; static int show_threads; static struct perf_read_values show_threads_values; +static char default_pretty_printing_style[] = "normal"; +static char *pretty_printing_style = default_pretty_printing_style; + static unsigned long page_size; static unsigned long mmap_window = 32; @@ -1401,6 +1404,9 @@ static size_t output__fprintf(FILE *fp, u64 total_samples) size_t ret = 0; unsigned int width; char *col_width = col_width_list_str; + int raw_printing_style; + + raw_printing_style = !strcmp(pretty_printing_style, "raw"); init_rem_hits(); @@ -1478,7 +1484,8 @@ print_entries: free(rem_sq_bracket); if (show_threads) - perf_read_values_display(fp, &show_threads_values); + perf_read_values_display(fp, &show_threads_values, + raw_printing_style); return ret; } @@ -2091,6 +2098,8 @@ static const struct option options[] = { "Show a column with the number of samples"), OPT_BOOLEAN('T', "threads", &show_threads, "Show per-thread event counters"), + OPT_STRING(0, "pretty", &pretty_printing_style, "key", + "pretty printing style key: normal raw"), OPT_STRING('s', "sort", &sort_order, "key[,key2...]", "sort by key(s): pid, comm, dso, symbol, parent"), OPT_BOOLEAN('P', "full-paths", &full_paths, -- cgit From cd84c2ac6d6425dd4d1b80a2231e534b9b03df18 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 12 Aug 2009 10:03:49 +0200 Subject: perf tools: Factorize high level dso helpers Factorize multiple definitions of high level dso helpers into the symbol source file. The side effect is a general export of the verbose and eprintf debugging helpers into a new file dedicated to debugging purposes. Signed-off-by: Frederic Weisbecker Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Brice Goglin --- tools/perf/builtin-report.c | 97 --------------------------------------------- 1 file changed, 97 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 2357c66fb91d..827eab2edf4b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -30,7 +30,6 @@ #define SHOW_HV 4 static char const *input_name = "perf.data"; -static char *vmlinux = NULL; static char default_sort_order[] = "comm,dso,symbol"; static char *sort_order = default_sort_order; @@ -46,11 +45,6 @@ static int dump_trace = 0; #define dprintf(x...) do { if (dump_trace) printf(x); } while (0) #define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0) -static int verbose; -#define eprintf(x...) do { if (verbose) fprintf(stderr, x); } while (0) - -static int modules; - static int full_paths; static int show_nr_samples; @@ -161,98 +155,7 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...) return n; } -static LIST_HEAD(dsos); -static struct dso *kernel_dso; -static struct dso *vdso; -static struct dso *hypervisor_dso; - -static void dsos__add(struct dso *dso) -{ - list_add_tail(&dso->node, &dsos); -} - -static struct dso *dsos__find(const char *name) -{ - struct dso *pos; - - list_for_each_entry(pos, &dsos, node) - if (strcmp(pos->name, name) == 0) - return pos; - return NULL; -} - -static struct dso *dsos__findnew(const char *name) -{ - struct dso *dso = dsos__find(name); - int nr; - - if (dso) - return dso; - - dso = dso__new(name, 0); - if (!dso) - goto out_delete_dso; - - nr = dso__load(dso, NULL, verbose); - if (nr < 0) { - eprintf("Failed to open: %s\n", name); - goto out_delete_dso; - } - if (!nr) - eprintf("No symbols found in: %s, maybe install a debug package?\n", name); - - dsos__add(dso); - - return dso; - -out_delete_dso: - dso__delete(dso); - return NULL; -} - -static void dsos__fprintf(FILE *fp) -{ - struct dso *pos; - - list_for_each_entry(pos, &dsos, node) - dso__fprintf(pos, fp); -} - -static struct symbol *vdso__find_symbol(struct dso *dso, u64 ip) -{ - return dso__find_symbol(dso, ip); -} - -static int load_kernel(void) -{ - int err; - - kernel_dso = dso__new("[kernel]", 0); - if (!kernel_dso) - return -1; - - err = dso__load_kernel(kernel_dso, vmlinux, NULL, verbose, modules); - if (err <= 0) { - dso__delete(kernel_dso); - kernel_dso = NULL; - } else - dsos__add(kernel_dso); - - vdso = dso__new("[vdso]", 0); - if (!vdso) - return -1; - vdso->find_symbol = vdso__find_symbol; - - dsos__add(vdso); - - hypervisor_dso = dso__new("[hypervisor]", 0); - if (!hypervisor_dso) - return -1; - dsos__add(hypervisor_dso); - - return err; -} static char __cwd[PATH_MAX]; static char *cwd = __cwd; -- cgit From 1fe2c1066ce6a30bda7b27785ee3d9b8e62ffbbd Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 12 Aug 2009 10:19:53 +0200 Subject: perf tools: Factorize the event structure definitions in a single file Factorize the multiple definition of the events structures into a single util/event.h file. Signed-off-by: Frederic Weisbecker Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Brice Goglin --- tools/perf/builtin-report.c | 53 --------------------------------------------- 1 file changed, 53 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 827eab2edf4b..1efefcc2ffdf 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -75,59 +75,6 @@ struct callchain_param callchain_param = { static u64 sample_type; -struct ip_event { - struct perf_event_header header; - u64 ip; - u32 pid, tid; - unsigned char __more_data[]; -}; - -struct mmap_event { - struct perf_event_header header; - u32 pid, tid; - u64 start; - u64 len; - u64 pgoff; - char filename[PATH_MAX]; -}; - -struct comm_event { - struct perf_event_header header; - u32 pid, tid; - char comm[16]; -}; - -struct fork_event { - struct perf_event_header header; - u32 pid, ppid; - u32 tid, ptid; -}; - -struct lost_event { - struct perf_event_header header; - u64 id; - u64 lost; -}; - -struct read_event { - struct perf_event_header header; - u32 pid,tid; - u64 value; - u64 time_enabled; - u64 time_running; - u64 id; -}; - -typedef union event_union { - struct perf_event_header header; - struct ip_event ip; - struct mmap_event mmap; - struct comm_event comm; - struct fork_event fork; - struct lost_event lost; - struct read_event read; -} event_t; - static int repsep_fprintf(FILE *fp, const char *fmt, ...) { int n; -- cgit From 66e274f3b8d7fc89d38997e85b900e188f8d5cc0 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Wed, 12 Aug 2009 11:07:25 +0200 Subject: perf tools: Factorize the map helpers Factorize the dso mapping helpers into a single purpose common file "util/map.c" Signed-off-by: Frederic Weisbecker Cc: Arnaldo Carvalho de Melo Cc: Peter Zijlstra Cc: Mike Galbraith Cc: Brice Goglin --- tools/perf/builtin-report.c | 124 ++------------------------------------------ 1 file changed, 5 insertions(+), 119 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1efefcc2ffdf..93945ecdac86 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -67,6 +67,10 @@ static char callchain_default_opt[] = "fractal,0.5"; static int callchain; +static char __cwd[PATH_MAX]; +static char *cwd = __cwd; +static int cwdlen; + static struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, @@ -102,124 +106,6 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...) return n; } - - -static char __cwd[PATH_MAX]; -static char *cwd = __cwd; -static int cwdlen; - -static int strcommon(const char *pathname) -{ - int n = 0; - - while (n < cwdlen && pathname[n] == cwd[n]) - ++n; - - return n; -} - -struct map { - struct list_head node; - u64 start; - u64 end; - u64 pgoff; - u64 (*map_ip)(struct map *, u64); - struct dso *dso; -}; - -static u64 map__map_ip(struct map *map, u64 ip) -{ - return ip - map->start + map->pgoff; -} - -static u64 vdso__map_ip(struct map *map __used, u64 ip) -{ - return ip; -} - -static inline int is_anon_memory(const char *filename) -{ - return strcmp(filename, "//anon") == 0; -} - -static struct map *map__new(struct mmap_event *event) -{ - struct map *self = malloc(sizeof(*self)); - - if (self != NULL) { - const char *filename = event->filename; - char newfilename[PATH_MAX]; - int anon; - - if (cwd) { - int n = strcommon(filename); - - if (n == cwdlen) { - snprintf(newfilename, sizeof(newfilename), - ".%s", filename + n); - filename = newfilename; - } - } - - anon = is_anon_memory(filename); - - if (anon) { - snprintf(newfilename, sizeof(newfilename), "/tmp/perf-%d.map", event->pid); - filename = newfilename; - } - - self->start = event->start; - self->end = event->start + event->len; - self->pgoff = event->pgoff; - - self->dso = dsos__findnew(filename); - if (self->dso == NULL) - goto out_delete; - - if (self->dso == vdso || anon) - self->map_ip = vdso__map_ip; - else - self->map_ip = map__map_ip; - } - return self; -out_delete: - free(self); - return NULL; -} - -static struct map *map__clone(struct map *self) -{ - struct map *map = malloc(sizeof(*self)); - - if (!map) - return NULL; - - memcpy(map, self, sizeof(*self)); - - return map; -} - -static int map__overlap(struct map *l, struct map *r) -{ - if (l->start > r->start) { - struct map *t = l; - l = r; - r = t; - } - - if (l->end > r->start) - return 1; - - return 0; -} - -static size_t map__fprintf(struct map *self, FILE *fp) -{ - return fprintf(fp, " %Lx-%Lx %Lx %s\n", - self->start, self->end, self->pgoff, self->dso->name); -} - - struct thread { struct rb_node rb_node; struct list_head maps; @@ -1474,7 +1360,7 @@ static int process_mmap_event(event_t *event, unsigned long offset, unsigned long head) { struct thread *thread = threads__findnew(event->mmap.pid); - struct map *map = map__new(&event->mmap); + struct map *map = map__new(&event->mmap, cwd, cwdlen); dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n", (void *)(offset + head), -- cgit From 6baa0a5ae0954fb2486c480a20556a9f1aee0965 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Fri, 14 Aug 2009 12:21:53 +0200 Subject: perf tools: Factorize the thread code in a dedicated file Factorize the thread management code used by perf-annotate and perf-report in dedicated source and header files. v2: pass last_match by address so that it can actually be modified. Signed-off-by: Frederic Weisbecker Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250245313-6995-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 205 +++++--------------------------------------- 1 file changed, 21 insertions(+), 184 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 6321951fe1bf..298f26b8ac78 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -25,6 +25,8 @@ #include "util/parse-options.h" #include "util/parse-events.h" +#include "util/thread.h" + #define SHOW_KERNEL 1 #define SHOW_USER 2 #define SHOW_HV 4 @@ -71,6 +73,9 @@ static char __cwd[PATH_MAX]; static char *cwd = __cwd; static int cwdlen; +static struct rb_root threads; +static struct thread *last_match; + static struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, @@ -106,187 +111,10 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...) return n; } -struct thread { - struct rb_node rb_node; - struct list_head maps; - pid_t pid; - char *comm; -}; - -static struct thread *thread__new(pid_t pid) -{ - struct thread *self = malloc(sizeof(*self)); - - if (self != NULL) { - self->pid = pid; - self->comm = malloc(32); - if (self->comm) - snprintf(self->comm, 32, ":%d", self->pid); - INIT_LIST_HEAD(&self->maps); - } - - return self; -} - static unsigned int dsos__col_width, comms__col_width, threads__col_width; -static int thread__set_comm(struct thread *self, const char *comm) -{ - if (self->comm) - free(self->comm); - self->comm = strdup(comm); - if (!self->comm) - return -ENOMEM; - - if (!col_width_list_str && !field_sep && - (!comm_list || strlist__has_entry(comm_list, comm))) { - unsigned int slen = strlen(comm); - if (slen > comms__col_width) { - comms__col_width = slen; - threads__col_width = slen + 6; - } - } - - return 0; -} - -static size_t thread__fprintf(struct thread *self, FILE *fp) -{ - struct map *pos; - size_t ret = fprintf(fp, "Thread %d %s\n", self->pid, self->comm); - - list_for_each_entry(pos, &self->maps, node) - ret += map__fprintf(pos, fp); - - return ret; -} - - -static struct rb_root threads; -static struct thread *last_match; - -static struct thread *threads__findnew(pid_t pid) -{ - struct rb_node **p = &threads.rb_node; - struct rb_node *parent = NULL; - struct thread *th; - - /* - * Font-end cache - PID lookups come in blocks, - * so most of the time we dont have to look up - * the full rbtree: - */ - if (last_match && last_match->pid == pid) - return last_match; - - while (*p != NULL) { - parent = *p; - th = rb_entry(parent, struct thread, rb_node); - - if (th->pid == pid) { - last_match = th; - return th; - } - - if (pid < th->pid) - p = &(*p)->rb_left; - else - p = &(*p)->rb_right; - } - - th = thread__new(pid); - if (th != NULL) { - rb_link_node(&th->rb_node, parent, p); - rb_insert_color(&th->rb_node, &threads); - last_match = th; - } - - return th; -} - -static void thread__insert_map(struct thread *self, struct map *map) -{ - struct map *pos, *tmp; - - list_for_each_entry_safe(pos, tmp, &self->maps, node) { - if (map__overlap(pos, map)) { - if (verbose >= 2) { - printf("overlapping maps:\n"); - map__fprintf(map, stdout); - map__fprintf(pos, stdout); - } - - if (map->start <= pos->start && map->end > pos->start) - pos->start = map->end; - - if (map->end >= pos->end && map->start < pos->end) - pos->end = map->start; - - if (verbose >= 2) { - printf("after collision:\n"); - map__fprintf(pos, stdout); - } - - if (pos->start >= pos->end) { - list_del_init(&pos->node); - free(pos); - } - } - } - - list_add_tail(&map->node, &self->maps); -} - -static int thread__fork(struct thread *self, struct thread *parent) -{ - struct map *map; - - if (self->comm) - free(self->comm); - self->comm = strdup(parent->comm); - if (!self->comm) - return -ENOMEM; - - list_for_each_entry(map, &parent->maps, node) { - struct map *new = map__clone(map); - if (!new) - return -ENOMEM; - thread__insert_map(self, new); - } - - return 0; -} - -static struct map *thread__find_map(struct thread *self, u64 ip) -{ - struct map *pos; - - if (self == NULL) - return NULL; - - list_for_each_entry(pos, &self->maps, node) - if (ip >= pos->start && ip <= pos->end) - return pos; - - return NULL; -} - -static size_t threads__fprintf(FILE *fp) -{ - size_t ret = 0; - struct rb_node *nd; - - for (nd = rb_first(&threads); nd; nd = rb_next(nd)) { - struct thread *pos = rb_entry(nd, struct thread, rb_node); - - ret += thread__fprintf(pos, fp); - } - - return ret; -} - /* * histogram, sorted on item, collects counts */ @@ -1228,7 +1056,7 @@ print_entries: static void register_idle_thread(void) { - struct thread *thread = threads__findnew(0); + struct thread *thread = threads__findnew(0, &threads, &last_match); if (thread == NULL || thread__set_comm(thread, "[idle]")) { @@ -1263,7 +1091,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) char level; int show = 0; struct dso *dso = NULL; - struct thread *thread = threads__findnew(event->ip.pid); + struct thread *thread; u64 ip = event->ip.ip; u64 period = 1; struct map *map = NULL; @@ -1271,6 +1099,8 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) struct ip_callchain *chain = NULL; int cpumode; + thread = threads__findnew(event->ip.pid, &threads, &last_match); + if (sample_type & PERF_SAMPLE_PERIOD) { period = *(u64 *)more_data; more_data += sizeof(u64); @@ -1360,9 +1190,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) static int process_mmap_event(event_t *event, unsigned long offset, unsigned long head) { - struct thread *thread = threads__findnew(event->mmap.pid); + struct thread *thread; struct map *map = map__new(&event->mmap, cwd, cwdlen); + thread = threads__findnew(event->mmap.pid, &threads, &last_match); + dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n", (void *)(offset + head), (void *)(long)(event->header.size), @@ -1387,7 +1219,9 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head) static int process_comm_event(event_t *event, unsigned long offset, unsigned long head) { - struct thread *thread = threads__findnew(event->comm.pid); + struct thread *thread; + + thread = threads__findnew(event->comm.pid, &threads, &last_match); dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n", (void *)(offset + head), @@ -1407,8 +1241,11 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head) static int process_task_event(event_t *event, unsigned long offset, unsigned long head) { - struct thread *thread = threads__findnew(event->fork.pid); - struct thread *parent = threads__findnew(event->fork.ppid); + struct thread *thread; + struct thread *parent; + + thread = threads__findnew(event->fork.pid, &threads, &last_match); + parent = threads__findnew(event->fork.ppid, &threads, &last_match); dprintf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n", (void *)(offset + head), @@ -1749,7 +1586,7 @@ done: return 0; if (verbose >= 3) - threads__fprintf(stdout); + threads__fprintf(stdout, &threads); if (verbose >= 2) dsos__fprintf(stdout); -- cgit From 83a0944fa919fb2ebcfc1f8933d86e437b597ca6 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Sat, 15 Aug 2009 12:26:57 +0200 Subject: perf: Enable more compiler warnings Related to a shadowed variable bug fix Valdis Kletnieks noticed that perf does not get built with -Wshadow, which could have helped us avoid the bug. So enable -Wshadow and also enable the following warnings on perf builds, in addition to the already enabled -Wall -Wextra -std=gnu99 warnings: -Wcast-align -Wformat=2 -Wshadow -Winit-self -Wpacked -Wredundant-decls -Wstack-protector -Wstrict-aliasing=3 -Wswitch-default -Wswitch-enum -Wno-system-headers -Wundef -Wvolatile-register-var -Wwrite-strings -Wbad-function-cast -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wold-style-definition -Wstrict-prototypes -Wdeclaration-after-statement And change/fix the perf code to build cleanly under GCC 4.3.2. The list of warnings enablement is rather arbitrary: it's based on my (quick) reading of the GCC manpages and trying them on perf. I categorized the warnings based on individually enabling them and looking whether they trigger something in the perf build. If i liked those warnings (i.e. if they trigger for something that arguably could be improved) i enabled the warning. If the warnings seemed to come from language laywers spamming the build with tons of nuisance warnings i generally kept them off. Most of the sign conversion related warnings were in this category. (A second patch enabling some of the sign warnings might be welcome - sign bugs can be nasty.) I also kept warnings that seem to make sense from their manpage description and which produced no actual warnings on our code base. These warnings might still be turned off if they end up being a nuisance. I also left out a few warnings that are not supported in older compilers. [ Note that these changes might break the build on older compilers i did not test, or on non-x86 architectures that produce different warnings, so more testing would be welcome. ] Reported-by: Valdis.Kletnieks@vt.edu 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/builtin-report.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 298f26b8ac78..3b9d24dc0eda 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -97,6 +97,7 @@ static int repsep_fprintf(FILE *fp, const char *fmt, ...) n = vasprintf(&bf, fmt, ap); if (n > 0) { char *sep = bf; + while (1) { sep = strchr(sep, *field_sep); if (sep == NULL) @@ -144,7 +145,7 @@ struct hist_entry { struct sort_entry { struct list_head list; - char *header; + const char *header; int64_t (*cmp)(struct hist_entry *, struct hist_entry *); int64_t (*collapse)(struct hist_entry *, struct hist_entry *); @@ -328,7 +329,7 @@ static int sort__need_collapse = 0; static int sort__has_parent = 0; struct sort_dimension { - char *name; + const char *name; struct sort_entry *entry; int taken; }; @@ -343,7 +344,7 @@ static struct sort_dimension sort_dimensions[] = { static LIST_HEAD(hist_entry__sort_list); -static int sort_dimension__add(char *tok) +static int sort_dimension__add(const char *tok) { unsigned int i; @@ -602,6 +603,7 @@ hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, case CHAIN_GRAPH_REL: ret += callchain__fprintf_graph(fp, chain, total_samples, 1, 1); + case CHAIN_NONE: default: break; } @@ -1290,7 +1292,7 @@ process_lost_event(event_t *event, unsigned long offset, unsigned long head) static void trace_event(event_t *event) { unsigned char *raw_event = (void *)event; - char *color = PERF_COLOR_BLUE; + const char *color = PERF_COLOR_BLUE; int i, j; if (!dump_trace) @@ -1348,7 +1350,7 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head) struct perf_counter_attr *attr = perf_header__find_attr(event->read.id); if (show_threads) { - char *name = attr ? __event_name(attr->type, attr->config) + const char *name = attr ? __event_name(attr->type, attr->config) : "unknown"; perf_read_values_add_value(&show_threads_values, event->read.pid, event->read.tid, @@ -1411,19 +1413,19 @@ process_event(event_t *event, unsigned long offset, unsigned long head) static u64 perf_header__sample_type(void) { - u64 sample_type = 0; + u64 type = 0; int i; for (i = 0; i < header->attrs; i++) { struct perf_header_attr *attr = header->attr[i]; - if (!sample_type) - sample_type = attr->attr.sample_type; - else if (sample_type != attr->attr.sample_type) + if (!type) + type = attr->attr.sample_type; + else if (type != attr->attr.sample_type) die("non matching sample_type"); } - return sample_type; + return type; } static int __cmd_report(void) @@ -1431,7 +1433,7 @@ static int __cmd_report(void) int ret, rc = EXIT_FAILURE; unsigned long offset = 0; unsigned long head, shift; - struct stat stat; + struct stat input_stat; event_t *event; uint32_t size; char *buf; @@ -1450,13 +1452,13 @@ static int __cmd_report(void) exit(-1); } - ret = fstat(input, &stat); + ret = fstat(input, &input_stat); if (ret < 0) { perror("failed to stat file"); exit(-1); } - if (!stat.st_size) { + if (!input_stat.st_size) { fprintf(stderr, "zero-sized file, nothing to do!\n"); exit(0); } @@ -1524,12 +1526,12 @@ more: size = 8; if (head + event->header.size >= page_size * mmap_window) { - int ret; + int munmap_ret; shift = page_size * (head / page_size); - ret = munmap(buf, page_size * mmap_window); - assert(ret == 0); + munmap_ret = munmap(buf, page_size * mmap_window); + assert(munmap_ret == 0); offset += shift; head -= shift; @@ -1568,7 +1570,7 @@ more: if (offset + head >= header->data_offset + header->data_size) goto done; - if (offset + head < (unsigned long)stat.st_size) + if (offset + head < (unsigned long)input_stat.st_size) goto more; done: @@ -1666,7 +1668,7 @@ static const struct option options[] = { "be more verbose (show symbol address, etc)"), OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), - OPT_STRING('k', "vmlinux", &vmlinux, "file", "vmlinux pathname"), + OPT_STRING('k', "vmlinux", &vmlinux_name, "file", "vmlinux pathname"), OPT_BOOLEAN('m', "modules", &modules, "load module symbols - WARNING: use only with -k and LIVE kernel"), OPT_BOOLEAN('n', "show-nr-samples", &show_nr_samples, -- cgit From 2cec19d9d0716f8d68f1c5a87667d0387d4d252d Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 16 Aug 2009 19:24:21 +0200 Subject: perf tools: Factorize the dprintf definition We have two users of dprintf: report and annotate. Another one is coming with perf trace. Then factorize it into the debug file. While at it, rename dprintf() to dump_printf() so that it doesn't conflicts with its libc homograph. Signed-off-by: Frederic Weisbecker Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250443461-28130-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 56 ++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 29 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 3b9d24dc0eda..e104ed3c8418 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -43,8 +43,6 @@ static char *field_sep; static int input; static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV; -static int dump_trace = 0; -#define dprintf(x...) do { if (dump_trace) printf(x); } while (0) #define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0) static int full_paths; @@ -713,8 +711,8 @@ got_map: if ((long long)ip < 0) dso = kernel_dso; } - dprintf(" ...... dso: %s\n", dso ? dso->name : ""); - dprintf(" ...... map: %Lx -> %Lx\n", *ipp, ip); + dump_printf(" ...... dso: %s\n", dso ? dso->name : ""); + dump_printf(" ...... map: %Lx -> %Lx\n", *ipp, ip); *ipp = ip; if (dsop) @@ -1108,7 +1106,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) more_data += sizeof(u64); } - dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", + dump_printf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n", (void *)(offset + head), (void *)(long)(event->header.size), event->header.misc, @@ -1121,7 +1119,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) chain = (void *)more_data; - dprintf("... chain: nr:%Lu\n", chain->nr); + dump_printf("... chain: nr:%Lu\n", chain->nr); if (validate_chain(chain, event) < 0) { eprintf("call-chain problem with event, skipping it.\n"); @@ -1130,11 +1128,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) if (dump_trace) { for (i = 0; i < chain->nr; i++) - dprintf("..... %2d: %016Lx\n", i, chain->ips[i]); + dump_printf("..... %2d: %016Lx\n", i, chain->ips[i]); } } - dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid); + dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); if (thread == NULL) { eprintf("problem processing %d event, skipping it.\n", @@ -1153,7 +1151,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) dso = kernel_dso; - dprintf(" ...... dso: %s\n", dso->name); + dump_printf(" ...... dso: %s\n", dso->name); } else if (cpumode == PERF_EVENT_MISC_USER) { @@ -1166,7 +1164,7 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) dso = hypervisor_dso; - dprintf(" ...... dso: [hypervisor]\n"); + dump_printf(" ...... dso: [hypervisor]\n"); } if (show & show_mask) { @@ -1197,7 +1195,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head) thread = threads__findnew(event->mmap.pid, &threads, &last_match); - dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n", + dump_printf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n", (void *)(offset + head), (void *)(long)(event->header.size), event->mmap.pid, @@ -1208,7 +1206,7 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head) event->mmap.filename); if (thread == NULL || map == NULL) { - dprintf("problem processing PERF_EVENT_MMAP, skipping event.\n"); + dump_printf("problem processing PERF_EVENT_MMAP, skipping event.\n"); return 0; } @@ -1225,14 +1223,14 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head) thread = threads__findnew(event->comm.pid, &threads, &last_match); - dprintf("%p [%p]: PERF_EVENT_COMM: %s:%d\n", + dump_printf("%p [%p]: PERF_EVENT_COMM: %s:%d\n", (void *)(offset + head), (void *)(long)(event->header.size), event->comm.comm, event->comm.pid); if (thread == NULL || thread__set_comm(thread, event->comm.comm)) { - dprintf("problem processing PERF_EVENT_COMM, skipping event.\n"); + dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n"); return -1; } total_comm++; @@ -1249,7 +1247,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head) thread = threads__findnew(event->fork.pid, &threads, &last_match); parent = threads__findnew(event->fork.ppid, &threads, &last_match); - dprintf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n", + dump_printf("%p [%p]: PERF_EVENT_%s: (%d:%d):(%d:%d)\n", (void *)(offset + head), (void *)(long)(event->header.size), event->header.type == PERF_EVENT_FORK ? "FORK" : "EXIT", @@ -1267,7 +1265,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head) return 0; if (!thread || !parent || thread__fork(thread, parent)) { - dprintf("problem processing PERF_EVENT_FORK, skipping event.\n"); + dump_printf("problem processing PERF_EVENT_FORK, skipping event.\n"); return -1; } total_fork++; @@ -1278,7 +1276,7 @@ process_task_event(event_t *event, unsigned long offset, unsigned long head) static int process_lost_event(event_t *event, unsigned long offset, unsigned long head) { - dprintf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n", + dump_printf("%p [%p]: PERF_EVENT_LOST: id:%Ld: lost:%Ld\n", (void *)(offset + head), (void *)(long)(event->header.size), event->lost.id, @@ -1298,12 +1296,12 @@ static void trace_event(event_t *event) if (!dump_trace) return; - dprintf("."); + dump_printf("."); cdprintf("\n. ... raw event: size %d bytes\n", event->header.size); for (i = 0; i < event->header.size; i++) { if ((i & 15) == 0) { - dprintf("."); + dump_printf("."); cdprintf(" %04x: ", i); } @@ -1322,7 +1320,7 @@ static void trace_event(event_t *event) cdprintf("\n"); } } - dprintf(".\n"); + dump_printf(".\n"); } static struct perf_header *header; @@ -1359,7 +1357,7 @@ process_read_event(event_t *event, unsigned long offset, unsigned long head) event->read.value); } - dprintf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n", + dump_printf("%p [%p]: PERF_EVENT_READ: %d %d %s %Lu\n", (void *)(offset + head), (void *)(long)(event->header.size), event->read.pid, @@ -1540,14 +1538,14 @@ more: size = event->header.size; - dprintf("\n%p [%p]: event: %d\n", + dump_printf("\n%p [%p]: event: %d\n", (void *)(offset + head), (void *)(long)event->header.size, event->header.type); if (!size || process_event(event, offset, head) < 0) { - dprintf("%p [%p]: skipping unknown header type: %d\n", + dump_printf("%p [%p]: skipping unknown header type: %d\n", (void *)(offset + head), (void *)(long)(event->header.size), event->header.type); @@ -1577,12 +1575,12 @@ done: rc = EXIT_SUCCESS; close(input); - dprintf(" IP events: %10ld\n", total); - dprintf(" mmap events: %10ld\n", total_mmap); - dprintf(" comm events: %10ld\n", total_comm); - dprintf(" fork events: %10ld\n", total_fork); - dprintf(" lost events: %10ld\n", total_lost); - dprintf(" unknown events: %10ld\n", total_unknown); + dump_printf(" IP events: %10ld\n", total); + dump_printf(" mmap events: %10ld\n", total_mmap); + dump_printf(" comm events: %10ld\n", total_comm); + dump_printf(" fork events: %10ld\n", total_fork); + dump_printf(" lost events: %10ld\n", total_lost); + dump_printf(" unknown events: %10ld\n", total_unknown); if (dump_trace) return 0; -- cgit From 0f25bfc8d8b31a4ac8e4ff6cbc3911fb7092a4a7 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 16 Aug 2009 19:56:54 +0200 Subject: perf tools: Put the show mode into the event headers files Annotate and report share the same flags to filter events considering their context (kernel, user, hypervisor). Both tools have their own definitions of these flags. Factorize them out into the event headers file. Signed-off-by: Frederic Weisbecker Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250445414-29237-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index e104ed3c8418..05d52ff4c33d 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -27,10 +27,6 @@ #include "util/thread.h" -#define SHOW_KERNEL 1 -#define SHOW_USER 2 -#define SHOW_HV 4 - static char const *input_name = "perf.data"; static char default_sort_order[] = "comm,dso,symbol"; -- cgit From 0d3a5c885971de1e3124d85bfadf818abac9ba12 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 16 Aug 2009 20:56:37 +0200 Subject: perf tools: Librarize sample type and attr finding from headers Librarize the sample type and attr fetching from perf data file headers so that we can also use it from perf trace. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250448997-30715-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 44 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 38 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 05d52ff4c33d..c6326deb1636 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -70,6 +70,8 @@ static int cwdlen; static struct rb_root threads; static struct thread *last_match; +static struct perf_header *header; + static struct callchain_param callchain_param = { .mode = CHAIN_GRAPH_REL, @@ -1319,29 +1321,12 @@ static void trace_event(event_t *event) dump_printf(".\n"); } -static struct perf_header *header; - -static struct perf_counter_attr *perf_header__find_attr(u64 id) -{ - int i; - - for (i = 0; i < header->attrs; i++) { - struct perf_header_attr *attr = header->attr[i]; - int j; - - for (j = 0; j < attr->ids; j++) { - if (attr->id[j] == id) - return &attr->attr; - } - } - - return NULL; -} - static int process_read_event(event_t *event, unsigned long offset, unsigned long head) { - struct perf_counter_attr *attr = perf_header__find_attr(event->read.id); + struct perf_counter_attr *attr; + + attr = perf_header__find_attr(event->read.id, header); if (show_threads) { const char *name = attr ? __event_name(attr->type, attr->config) @@ -1405,23 +1390,6 @@ process_event(event_t *event, unsigned long offset, unsigned long head) return 0; } -static u64 perf_header__sample_type(void) -{ - u64 type = 0; - int i; - - for (i = 0; i < header->attrs; i++) { - struct perf_header_attr *attr = header->attr[i]; - - if (!type) - type = attr->attr.sample_type; - else if (type != attr->attr.sample_type) - die("non matching sample_type"); - } - - return type; -} - static int __cmd_report(void) { int ret, rc = EXIT_FAILURE; @@ -1460,7 +1428,7 @@ static int __cmd_report(void) header = perf_header__read(input); head = header->data_offset; - sample_type = perf_header__sample_type(); + sample_type = perf_header__sample_type(header); if (!(sample_type & PERF_SAMPLE_CALLCHAIN)) { if (sort__has_parent) { -- cgit From 8f28827a162fd1e8da4e96bed69b06d2606e8322 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Sun, 16 Aug 2009 22:05:48 +0200 Subject: perf tools: Librarize trace_event() helper Librarize trace_event() helper so that perf trace can use it too. Also clean up the debug.h includes a bit. It's not good to have it included in perf.h because it doesn't make it flexible against other headers it may need (headers that can also depend on perf.h and then create a recursive header dependency). Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250453149-664-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 39 +-------------------------------------- 1 file changed, 1 insertion(+), 38 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index c6326deb1636..1e3ad22d53dc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -20,6 +20,7 @@ #include "util/values.h" #include "perf.h" +#include "util/debug.h" #include "util/header.h" #include "util/parse-options.h" @@ -39,8 +40,6 @@ static char *field_sep; static int input; static int show_mask = SHOW_KERNEL | SHOW_USER | SHOW_HV; -#define cdprintf(x...) do { if (dump_trace) color_fprintf(stdout, color, x); } while (0) - static int full_paths; static int show_nr_samples; @@ -1285,42 +1284,6 @@ process_lost_event(event_t *event, unsigned long offset, unsigned long head) return 0; } -static void trace_event(event_t *event) -{ - unsigned char *raw_event = (void *)event; - const char *color = PERF_COLOR_BLUE; - int i, j; - - if (!dump_trace) - return; - - dump_printf("."); - cdprintf("\n. ... raw event: size %d bytes\n", event->header.size); - - for (i = 0; i < event->header.size; i++) { - if ((i & 15) == 0) { - dump_printf("."); - cdprintf(" %04x: ", i); - } - - cdprintf(" %02x", raw_event[i]); - - if (((i & 15) == 15) || i == event->header.size-1) { - cdprintf(" "); - for (j = 0; j < 15-(i & 15); j++) - cdprintf(" "); - for (j = 0; j < (i & 15); j++) { - if (isprint(raw_event[i-15+j])) - cdprintf("%c", raw_event[i-15+j]); - else - cdprintf("."); - } - cdprintf("\n"); - } - } - dump_printf(".\n"); -} - static int process_read_event(event_t *event, unsigned long offset, unsigned long head) { -- cgit From 6ede59c412579303a25c11f93d4d262e100fc7e6 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 17 Aug 2009 23:07:48 +0200 Subject: perf tools: Fix spelling mistake in callchain error While running perf report -g in a perf.data file that hasn't been recorded in callchain mode, the error reported has a spelling issue: ./perf report -g selected -c but no callchain data. Did you call perf record without -g? Fix it. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith Cc: Steven Rostedt LKML-Reference: <1250543271-8383-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1e3ad22d53dc..ed1fdab3a1f5 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1401,7 +1401,7 @@ static int __cmd_report(void) exit(-1); } if (callchain) { - fprintf(stderr, "selected -c but no callchain data." + fprintf(stderr, "selected -g but no callchain data." " Did you call perf record without" " -g?\n"); exit(-1); -- cgit From 4273b005875c34beda4a11c9d4a9132d80378036 Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Tue, 18 Aug 2009 16:03:46 +0200 Subject: perf tools: Fix comm column adjusting The librarization of the thread helpers between annotate and report lost some perf report specifics. This patch fixes the thread comm column adjusting that has been omitted during this export. Signed-off-by: Frederic Weisbecker Cc: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo Cc: Mike Galbraith LKML-Reference: <1250604226-6852-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 1e3ad22d53dc..3fc0d471b90b 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -665,6 +665,27 @@ static void dso__calc_col_width(struct dso *self) self->slen_calculated = 1; } +static int thread__set_comm_adjust(struct thread *self, const char *comm) +{ + int ret = thread__set_comm(self, comm); + + if (ret) + return ret; + + if (!col_width_list_str && !field_sep && + (!comm_list || strlist__has_entry(comm_list, comm))) { + unsigned int slen = strlen(comm); + + if (slen > comms__col_width) { + comms__col_width = slen; + threads__col_width = slen + 6; + } + } + + return 0; +} + + static struct symbol * resolve_symbol(struct thread *thread, struct map **mapp, struct dso **dsop, u64 *ipp) @@ -1056,7 +1077,7 @@ static void register_idle_thread(void) struct thread *thread = threads__findnew(0, &threads, &last_match); if (thread == NULL || - thread__set_comm(thread, "[idle]")) { + thread__set_comm_adjust(thread, "[idle]")) { fprintf(stderr, "problem inserting idle task.\n"); exit(-1); } @@ -1226,7 +1247,7 @@ process_comm_event(event_t *event, unsigned long offset, unsigned long head) event->comm.comm, event->comm.pid); if (thread == NULL || - thread__set_comm(thread, event->comm.comm)) { + thread__set_comm_adjust(thread, event->comm.comm)) { dump_printf("problem processing PERF_EVENT_COMM, skipping event.\n"); return -1; } -- cgit From 119e7a22bb70d84849384e5113792cd45afa4f85 Mon Sep 17 00:00:00 2001 From: Pierre Habouzit Date: Thu, 27 Aug 2009 09:59:02 +0200 Subject: perf tools: do not complain if root is owning perf.data This improves patch fa6963b24 so that perf.data stuff that has been dumped as root can be read (annotate/report) by a user without the use of the --force. Rationale is that root has plenty of ways to screw us (usually) that do not require twisted schemes involving specially crafting a perf.data. Signed-off-by: Pierre Habouzit Cc: Paul Mackerras Cc: Peter Zijlstra Cc: LKML-Reference: <20090827075902.GF19653@laphroaig.corp> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index d2e28820ee60..ea6328a893cc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -1405,8 +1405,8 @@ static int __cmd_report(void) exit(-1); } - if (!force && (input_stat.st_uid != geteuid())) { - fprintf(stderr, "file: %s not owned by current user\n", input_name); + if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) { + fprintf(stderr, "file: %s not owned by current user or root\n", input_name); exit(-1); } -- cgit From 5b447a6a13ea823b698bf4c01193654fd7ebf4ec Mon Sep 17 00:00:00 2001 From: Frederic Weisbecker Date: Mon, 31 Aug 2009 06:45:18 +0200 Subject: perf tools: Librarize idle thread registration Librarize register_idle_thread() used by annotate and report. Signed-off-by: Frederic Weisbecker Cc: Peter Zijlstra Cc: Arnaldo Carvalho de Melo LKML-Reference: <1251693921-6579-1-git-send-email-fweisbec@gmail.com> Signed-off-by: Ingo Molnar --- tools/perf/builtin-report.c | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) (limited to 'tools/perf/builtin-report.c') diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index cdd46ab11bd5..cdf9a8d27bb9 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c @@ -666,12 +666,9 @@ static void dso__calc_col_width(struct dso *self) self->slen_calculated = 1; } -static int thread__set_comm_adjust(struct thread *self, const char *comm) +static void thread__comm_adjust(struct thread *self) { - int ret = thread__set_comm(self, comm); - - if (ret) - return ret; + char *comm = self->comm; if (!col_width_list_str && !field_sep && (!comm_list || strlist__has_entry(comm_list, comm))) { @@ -682,6 +679,16 @@ static int thread__set_comm_adjust(struct thread *self, const char *comm) threads__col_width = slen + 6; } } +} + +static int thread__set_comm_adjust(struct thread *self, const char *comm) +{ + int ret = thread__set_comm(self, comm); + + if (ret) + return ret; + + thread__comm_adjust(self); return 0; } @@ -1073,17 +1080,6 @@ print_entries: return ret; } -static void register_idle_thread(void) -{ - struct thread *thread = threads__findnew(0, &threads, &last_match); - - if (thread == NULL || - thread__set_comm_adjust(thread, "[idle]")) { - fprintf(stderr, "problem inserting idle task.\n"); - exit(-1); - } -} - static unsigned long total = 0, total_mmap = 0, total_comm = 0, @@ -1381,11 +1377,13 @@ static int __cmd_report(void) unsigned long offset = 0; unsigned long head, shift; struct stat input_stat; + struct thread *idle; event_t *event; uint32_t size; char *buf; - register_idle_thread(); + idle = register_idle_thread(&threads, &last_match); + thread__comm_adjust(idle); if (show_threads) perf_read_values_init(&show_threads_values); -- cgit