lkml.org 
[lkml]   [2009]   [Jun]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 2/2] perfcounters: print a sorted summary of annotated overhead lines
    Date
    It's can be very annoying to scroll down perf annotated output
    until we find relevant overhead.

    Using the -l option, you can now have a small summary sorted per
    overhead in the beginning of the output.

    Example:

    ./perf annotate -l -k ../../vmlinux -s __lock_acquire

    Sorted summary for file ../../vmlinux
    ----------------------------------------------

    12.04 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
    4.61 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
    3.77 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1775
    3.56 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
    2.93 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
    2.83 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2545
    2.30 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
    2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2388
    2.20 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
    2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
    2.09 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:138
    1.88 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2548
    1.47 /home/fweisbec/linux/linux-2.6-tip/arch/x86/include/asm/irqflags.h:15
    1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2594
    1.36 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:730
    1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1654
    1.26 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1653
    1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:2592
    1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740
    1.15 /home/fweisbec/linux/linux-2.6-tip/kernel/lockdep.c:1740

    [...]

    Only overhead over 0.5% are summarized.

    Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com>
    ---
    tools/perf/builtin-annotate.c | 111 +++++++++++++++++++++++++++++++++--------
    1 files changed, 90 insertions(+), 21 deletions(-)

    diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
    index 15192a3..94cea67 100644
    --- a/tools/perf/builtin-annotate.c
    +++ b/tools/perf/builtin-annotate.c
    @@ -25,6 +25,10 @@
    #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";

    @@ -88,6 +92,7 @@ typedef union event_union {


    struct sym_ext {
    + struct rb_node node;
    double percent;
    char *path;
    };
    @@ -1038,6 +1043,24 @@ 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)
    {
    @@ -1086,7 +1109,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
    const char *path = NULL;
    unsigned int hits = 0;
    double percent = 0.0;
    - char *color = PERF_COLOR_NORMAL;
    + char *color;
    struct sym_ext *sym_ext = sym->priv;

    offset = line_ip - start;
    @@ -1099,17 +1122,7 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
    } else if (sym->hist_sum)
    percent = 100.0 * hits / sym->hist_sum;

    - /*
    - * 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;
    - }
    + color = get_color(percent);

    /*
    * Also color the filename and line if needed, with
    @@ -1138,6 +1151,28 @@ parse_line(FILE *file, struct symbol *sym, __u64 start, __u64 len)
    return 0;
    }

    +static struct rb_root root_sym_ext;
    +
    +static void insert_source_line(struct sym_ext *sym_ext)
    +{
    + struct sym_ext *iter;
    + struct rb_node **p = &root_sym_ext.rb_node;
    + struct rb_node *parent = NULL;
    +
    + while (*p != NULL) {
    + parent = *p;
    + iter = rb_entry(parent, struct sym_ext, node);
    +
    + if (sym_ext->percent > iter->percent)
    + p = &(*p)->rb_left;
    + else
    + p = &(*p)->rb_right;
    + }
    +
    + rb_link_node(&sym_ext->node, parent, p);
    + rb_insert_color(&sym_ext->node, &root_sym_ext);
    +}
    +
    static void free_source_line(struct symbol *sym, int len)
    {
    struct sym_ext *sym_ext = sym->priv;
    @@ -1151,6 +1186,7 @@ static void free_source_line(struct symbol *sym, int len)
    free(sym_ext);

    sym->priv = NULL;
    + root_sym_ext = RB_ROOT;
    }

    /* Get the filename:line for the colored entries */
    @@ -1194,12 +1230,42 @@ get_source_line(struct symbol *sym, __u64 start, int len, char *filename)
    goto next;

    strcpy(sym_ext[i].path, path);
    + insert_source_line(&sym_ext[i]);

    next:
    pclose(fp);
    }
    }

    +static void print_summary(char *filename)
    +{
    + struct sym_ext *sym_ext;
    + struct rb_node *node;
    +
    + printf("\nSorted summary for file %s\n", filename);
    + printf("----------------------------------------------\n\n");
    +
    + if (RB_EMPTY_ROOT(&root_sym_ext)) {
    + printf(" Nothing higher than %1.1f%%\n", MIN_GREEN);
    + return;
    + }
    +
    + node = rb_first(&root_sym_ext);
    + while (node) {
    + double percent;
    + char *color;
    + char *path;
    +
    + sym_ext = rb_entry(node, struct sym_ext, node);
    + percent = sym_ext->percent;
    + color = get_color(percent);
    + path = sym_ext->path;
    +
    + color_fprintf(stdout, color, " %7.2f %s", percent, path);
    + node = rb_next(node);
    + }
    +}
    +
    static void annotate_sym(struct dso *dso, struct symbol *sym)
    {
    char *filename = dso->name;
    @@ -1212,13 +1278,6 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
    if (dso == kernel_dso)
    filename = vmlinux;

    - printf("\n------------------------------------------------\n");
    - printf(" Percent | Source code & Disassembly of %s\n", filename);
    - printf("------------------------------------------------\n");
    -
    - if (verbose >= 2)
    - printf("annotating [%p] %30s : [%p] %30s\n", dso, dso->name, sym, sym->name);
    -
    start = sym->obj_start;
    if (!start)
    start = sym->start;
    @@ -1226,8 +1285,17 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
    end = start + sym->end - sym->start + 1;
    len = sym->end - sym->start;

    - if (print_line)
    + if (print_line) {
    get_source_line(sym, start, len, filename);
    + print_summary(filename);
    + }
    +
    + printf("\n\n------------------------------------------------\n");
    + printf(" Percent | Source code & Disassembly of %s\n", 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);

    @@ -1244,7 +1312,8 @@ static void annotate_sym(struct dso *dso, struct symbol *sym)
    }

    pclose(file);
    - free_source_line(sym, len);
    + if (print_line)
    + free_source_line(sym, len);
    }

    static void find_annotations(void)
    --
    1.6.2.3


    \
     
     \ /
      Last update: 2009-06-13 17:29    [W:0.055 / U:1.036 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site