]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - tools/perf/builtin-report.c
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[mv-sheeva.git] / tools / perf / builtin-report.c
index f053a7463dcf0cf6d99081bb98a07c9acd77217d..82fa93b4db9996d3af08d72b71934053107d70ef 100644 (file)
@@ -47,6 +47,7 @@ struct ip_event {
        struct perf_event_header header;
        __u64 ip;
        __u32 pid, tid;
+       __u64 period;
 };
 
 struct mmap_event {
@@ -145,7 +146,7 @@ static void dsos__fprintf(FILE *fp)
                dso__fprintf(pos, fp);
 }
 
-static struct symbol *vdso__find_symbol(struct dso *dso, uint64_t ip)
+static struct symbol *vdso__find_symbol(struct dso *dso, __u64 ip)
 {
        return dso__find_symbol(kernel_dso, ip);
 }
@@ -192,23 +193,28 @@ static int strcommon(const char *pathname)
 
 struct map {
        struct list_head node;
-       uint64_t         start;
-       uint64_t         end;
-       uint64_t         pgoff;
-       uint64_t         (*map_ip)(struct map *, uint64_t);
+       __u64    start;
+       __u64    end;
+       __u64    pgoff;
+       __u64    (*map_ip)(struct map *, __u64);
        struct dso       *dso;
 };
 
-static uint64_t map__map_ip(struct map *map, uint64_t ip)
+static __u64 map__map_ip(struct map *map, __u64 ip)
 {
        return ip - map->start + map->pgoff;
 }
 
-static uint64_t vdso__map_ip(struct map *map, uint64_t ip)
+static __u64 vdso__map_ip(struct map *map, __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));
@@ -216,6 +222,7 @@ static struct map *map__new(struct mmap_event *event)
        if (self != NULL) {
                const char *filename = event->filename;
                char newfilename[PATH_MAX];
+               int anon;
 
                if (cwd) {
                        int n = strcommon(filename);
@@ -227,6 +234,13 @@ static struct map *map__new(struct mmap_event *event)
                        }
                }
 
+               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;
@@ -235,7 +249,7 @@ static struct map *map__new(struct mmap_event *event)
                if (self->dso == NULL)
                        goto out_delete;
 
-               if (self->dso == vdso)
+               if (self->dso == vdso || anon)
                        self->map_ip = vdso__map_ip;
                else
                        self->map_ip = map__map_ip;
@@ -274,7 +288,7 @@ static int map__overlap(struct map *l, struct map *r)
 
 static size_t map__fprintf(struct map *self, FILE *fp)
 {
-       return fprintf(fp, " %"PRIx64"-%"PRIx64" %"PRIx64" %s\n",
+       return fprintf(fp, " %Lx-%Lx %Lx %s\n",
                       self->start, self->end, self->pgoff, self->dso->name);
 }
 
@@ -398,7 +412,7 @@ static int thread__fork(struct thread *self, struct thread *parent)
        return 0;
 }
 
-static struct map *thread__find_map(struct thread *self, uint64_t ip)
+static struct map *thread__find_map(struct thread *self, __u64 ip)
 {
        struct map *pos;
 
@@ -439,10 +453,10 @@ struct hist_entry {
        struct map       *map;
        struct dso       *dso;
        struct symbol    *sym;
-       uint64_t         ip;
+       __u64            ip;
        char             level;
 
-       uint32_t         count;
+       __u64            count;
 };
 
 /*
@@ -558,7 +572,7 @@ static struct sort_entry sort_dso = {
 static int64_t
 sort__sym_cmp(struct hist_entry *left, struct hist_entry *right)
 {
-       uint64_t ip_l, ip_r;
+       __u64 ip_l, ip_r;
 
        if (left->sym == right->sym)
                return 0;
@@ -670,7 +684,7 @@ hist_entry__collapse(struct hist_entry *left, struct hist_entry *right)
 }
 
 static size_t
-hist_entry__fprintf(FILE *fp, struct hist_entry *self, uint64_t total_samples)
+hist_entry__fprintf(FILE *fp, struct hist_entry *self, __u64 total_samples)
 {
        struct sort_entry *se;
        size_t ret;
@@ -680,18 +694,21 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, uint64_t total_samples)
                char *color = PERF_COLOR_NORMAL;
 
                /*
-                * We color high-overhead entries in red, low-overhead
-                * entries in green - and keep the middle ground normal:
+                * We color high-overhead entries in red, mid-overhead
+                * entries in green - and keep the low overhead places
+                * normal:
                 */
-               if (percent >= 5.0)
+               if (percent >= 5.0) {
                        color = PERF_COLOR_RED;
-               if (percent < 0.5)
-                       color = PERF_COLOR_GREEN;
+               } else {
+                       if (percent >= 0.5)
+                               color = PERF_COLOR_GREEN;
+               }
 
                ret = color_fprintf(fp, color, "   %6.2f%%",
                                (self->count * 100.0) / total_samples);
        } else
-               ret = fprintf(fp, "%12d ", self->count);
+               ret = fprintf(fp, "%12Ld ", self->count);
 
        list_for_each_entry(se, &hist_entry__sort_list, list) {
                fprintf(fp, "  ");
@@ -709,7 +726,7 @@ hist_entry__fprintf(FILE *fp, struct hist_entry *self, uint64_t total_samples)
 
 static int
 hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
-               struct symbol *sym, uint64_t ip, char level)
+               struct symbol *sym, __u64 ip, char level, __u64 count)
 {
        struct rb_node **p = &hist.rb_node;
        struct rb_node *parent = NULL;
@@ -721,7 +738,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
                .sym    = sym,
                .ip     = ip,
                .level  = level,
-               .count  = 1,
+               .count  = count,
        };
        int cmp;
 
@@ -732,7 +749,7 @@ hist_entry__add(struct thread *thread, struct map *map, struct dso *dso,
                cmp = hist_entry__cmp(&entry, he);
 
                if (!cmp) {
-                       he->count++;
+                       he->count += count;
                        return 0;
                }
 
@@ -856,7 +873,7 @@ static void output__resort(void)
        }
 }
 
-static size_t output__fprintf(FILE *fp, uint64_t total_samples)
+static size_t output__fprintf(FILE *fp, __u64 total_samples)
 {
        struct hist_entry *pos;
        struct sort_entry *se;
@@ -924,15 +941,20 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
        int show = 0;
        struct dso *dso = NULL;
        struct thread *thread = threads__findnew(event->ip.pid);
-       uint64_t ip = event->ip.ip;
+       __u64 ip = event->ip.ip;
+       __u64 period = 1;
        struct map *map = NULL;
 
-       dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p\n",
+       if (event->header.type & PERF_SAMPLE_PERIOD)
+               period = event->ip.period;
+
+       dprintf("%p [%p]: PERF_EVENT (IP, %d): %d: %p period: %Ld\n",
                (void *)(offset + head),
                (void *)(long)(event->header.size),
                event->header.misc,
                event->ip.pid,
-               (void *)(long)ip);
+               (void *)(long)ip,
+               (long long)period);
 
        dprintf(" ... thread: %s:%d\n", thread->comm, thread->pid);
 
@@ -983,13 +1005,13 @@ process_overflow_event(event_t *event, unsigned long offset, unsigned long head)
                if (dso)
                        sym = dso->find_symbol(dso, ip);
 
-               if (hist_entry__add(thread, map, dso, sym, ip, level)) {
+               if (hist_entry__add(thread, map, dso, sym, ip, level, period)) {
                        fprintf(stderr,
                "problem incrementing symbol count, skipping event\n");
                        return -1;
                }
        }
-       total++;
+       total += period;
 
        return 0;
 }