Skip to content

Commit

Permalink
Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kern…
Browse files Browse the repository at this point in the history
…el/git/acme/linux into perf/urgent
  • Loading branch information
Ingo Molnar committed Mar 31, 2012
2 parents 12b5da3 + 65f3e56 commit 8ebfdf2
Show file tree
Hide file tree
Showing 15 changed files with 135 additions and 8,546 deletions.
47 changes: 30 additions & 17 deletions tools/perf/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,6 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \

CC = $(CROSS_COMPILE)gcc
AR = $(CROSS_COMPILE)ar
FLEX = $(CROSS_COMPILE)flex
BISON= $(CROSS_COMPILE)bison

# Additional ARCH settings for x86
ifeq ($(ARCH),i386)
Expand Down Expand Up @@ -184,7 +182,7 @@ endif

### --- END CONFIGURATION SECTION ---

BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
BASIC_LDFLAGS =

# Guard against environment variables
Expand Down Expand Up @@ -236,6 +234,25 @@ endif

export PERL_PATH

FLEX = $(CROSS_COMPILE)flex
BISON= $(CROSS_COMPILE)bison

event-parser:
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c

$(OUTPUT)util/parse-events-flex.c: event-parser
$(OUTPUT)util/parse-events-bison.c: event-parser

pmu-parser:
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c

$(OUTPUT)util/pmu-flex.c: pmu-parser
$(OUTPUT)util/pmu-bison.c: pmu-parser

$(OUTPUT)util/parse-events.o: event-parser pmu-parser

LIB_FILE=$(OUTPUT)libperf.a

LIB_H += ../../include/linux/perf_event.h
Expand Down Expand Up @@ -754,6 +771,15 @@ $(OUTPUT)perf.o perf.spec \
.SUFFIXES:
.SUFFIXES: .o .c .S .s

# These two need to be here so that when O= is not used they take precedence
# over the general rule for .o

$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<

$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<

$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
Expand Down Expand Up @@ -790,12 +816,6 @@ $(OUTPUT)util/ui/browsers/map.o: util/ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<

$(OUTPUT)util/parse-events-flex.o: util/parse-events-flex.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<

$(OUTPUT)util/pmu-flex.o: util/pmu-flex.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<

$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<

Expand Down Expand Up @@ -883,14 +903,6 @@ cscope:
$(RM) cscope*
$(FIND) . -name '*.[hcS]' -print | xargs cscope -b

event-parser:
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o util/parse-events-bison.c
$(QUIET_FLEX)$(FLEX) --header-file=util/parse-events-flex.h -t util/parse-events.l > util/parse-events-flex.c

pmu-parser:
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o util/pmu-bison.c
$(QUIET_FLEX)$(FLEX) --header-file=util/pmu-flex.h -t util/pmu.l > util/pmu-flex.c

### Detect prefix changes
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
Expand Down Expand Up @@ -978,6 +990,7 @@ clean:
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
$(MAKE) -C Documentation/ clean
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
$(RM) $(OUTPUT)util/*-{bison,flex}*
$(python-clean)

.PHONY: all install clean strip
Expand Down
8 changes: 4 additions & 4 deletions tools/perf/util/annotate.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ int symbol__annotate_init(struct map *map __used, struct symbol *sym)
int symbol__alloc_hist(struct symbol *sym)
{
struct annotation *notes = symbol__annotation(sym);
size_t sizeof_sym_hist = (sizeof(struct sym_hist) +
(sym->end - sym->start) * sizeof(u64));
const size_t size = sym->end - sym->start + 1;
size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));

notes->src = zalloc(sizeof(*notes->src) + symbol_conf.nr_events * sizeof_sym_hist);
if (notes->src == NULL)
Expand Down Expand Up @@ -64,7 +64,7 @@ int symbol__inc_addr_samples(struct symbol *sym, struct map *map,

pr_debug3("%s: addr=%#" PRIx64 "\n", __func__, map->unmap_ip(map, addr));

if (addr >= sym->end)
if (addr > sym->end)
return 0;

offset = addr - sym->start;
Expand Down Expand Up @@ -408,7 +408,7 @@ static int symbol__get_source_line(struct symbol *sym, struct map *map,
if (!notes->src->lines)
return -1;

start = map->unmap_ip(map, sym->start);
start = map__rip_2objdump(map, sym->start);

for (i = 0; i < len; i++) {
char *path = NULL;
Expand Down
2 changes: 2 additions & 0 deletions tools/perf/util/evsel.c
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,8 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
return -EFAULT;

data->raw_data = (void *) pdata;

array = (void *)array + data->raw_size + sizeof(u32);
}

if (type & PERF_SAMPLE_BRANCH_STACK) {
Expand Down
157 changes: 93 additions & 64 deletions tools/perf/util/hist.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,29 +607,24 @@ static void init_rem_hits(void)
rem_hits.ms.sym = rem_sq_bracket;
}

static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
u64 total_samples, int depth,
int depth_mask, int left_margin)
{
struct rb_node *node, *next;
struct callchain_node *child;
struct callchain_list *chain;
int new_depth_mask = depth_mask;
u64 new_total;
u64 remaining;
size_t ret = 0;
int i;
uint entries_printed = 0;

if (callchain_param.mode == CHAIN_GRAPH_REL)
new_total = self->children_hit;
else
new_total = total_samples;

remaining = new_total;
remaining = total_samples;

node = rb_first(&self->rb_root);
node = rb_first(root);
while (node) {
u64 new_total;
u64 cumul;

child = rb_entry(node, struct callchain_node, rb_node);
Expand Down Expand Up @@ -657,11 +652,17 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
list_for_each_entry(chain, &child->val, list) {
ret += ipchain__fprintf_graph(fp, chain, depth,
new_depth_mask, i++,
new_total,
total_samples,
cumul,
left_margin);
}
ret += __callchain__fprintf_graph(fp, child, new_total,

if (callchain_param.mode == CHAIN_GRAPH_REL)
new_total = child->children_hit;
else
new_total = total_samples;

ret += __callchain__fprintf_graph(fp, &child->rb_root, new_total,
depth + 1,
new_depth_mask | (1 << depth),
left_margin);
Expand All @@ -671,69 +672,83 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
}

if (callchain_param.mode == CHAIN_GRAPH_REL &&
remaining && remaining != new_total) {
remaining && remaining != total_samples) {

if (!rem_sq_bracket)
return ret;

new_depth_mask &= ~(1 << (depth - 1));

ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
new_depth_mask, 0, new_total,
new_depth_mask, 0, total_samples,
remaining, left_margin);
}

return ret;
}

static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
u64 total_samples, int left_margin)
{
struct callchain_node *cnode;
struct callchain_list *chain;
u32 entries_printed = 0;
bool printed = false;
struct rb_node *node;
int i = 0;
int ret = 0;
u32 entries_printed = 0;

list_for_each_entry(chain, &self->val, list) {
if (!i++ && sort__first_dimension == SORT_SYM)
continue;

if (!printed) {
ret += callchain__fprintf_left_margin(fp, left_margin);
ret += fprintf(fp, "|\n");
ret += callchain__fprintf_left_margin(fp, left_margin);
ret += fprintf(fp, "---");

left_margin += 3;
printed = true;
} else
ret += callchain__fprintf_left_margin(fp, left_margin);
int ret;

if (chain->ms.sym)
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
else
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
/*
* If have one single callchain root, don't bother printing
* its percentage (100 % in fractal mode and the same percentage
* than the hist in graph mode). This also avoid one level of column.
*/
node = rb_first(root);
if (node && !rb_next(node)) {
cnode = rb_entry(node, struct callchain_node, rb_node);
list_for_each_entry(chain, &cnode->val, list) {
/*
* If we sort by symbol, the first entry is the same than
* the symbol. No need to print it otherwise it appears as
* displayed twice.
*/
if (!i++ && sort__first_dimension == SORT_SYM)
continue;
if (!printed) {
ret += callchain__fprintf_left_margin(fp, left_margin);
ret += fprintf(fp, "|\n");
ret += callchain__fprintf_left_margin(fp, left_margin);
ret += fprintf(fp, "---");
left_margin += 3;
printed = true;
} else
ret += callchain__fprintf_left_margin(fp, left_margin);

if (chain->ms.sym)
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
else
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);

if (++entries_printed == callchain_param.print_limit)
break;
if (++entries_printed == callchain_param.print_limit)
break;
}
root = &cnode->rb_root;
}

ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);

return ret;
return __callchain__fprintf_graph(fp, root, total_samples,
1, 1, left_margin);
}

static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
u64 total_samples)
static size_t __callchain__fprintf_flat(FILE *fp,
struct callchain_node *self,
u64 total_samples)
{
struct callchain_list *chain;
size_t ret = 0;

if (!self)
return 0;

ret += callchain__fprintf_flat(fp, self->parent, total_samples);
ret += __callchain__fprintf_flat(fp, self->parent, total_samples);


list_for_each_entry(chain, &self->val, list) {
Expand All @@ -749,44 +764,58 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
return ret;
}

static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
u64 total_samples, int left_margin,
FILE *fp)
static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *self,
u64 total_samples)
{
struct rb_node *rb_node;
struct callchain_node *chain;
size_t ret = 0;
u32 entries_printed = 0;
struct rb_node *rb_node;
struct callchain_node *chain;

rb_node = rb_first(&he->sorted_chain);
rb_node = rb_first(self);
while (rb_node) {
double percent;

chain = rb_entry(rb_node, struct callchain_node, rb_node);
percent = chain->hit * 100.0 / total_samples;
switch (callchain_param.mode) {
case CHAIN_FLAT:
ret += percent_color_fprintf(fp, " %6.2f%%\n",
percent);
ret += callchain__fprintf_flat(fp, chain, total_samples);
break;
case CHAIN_GRAPH_ABS: /* Falldown */
case CHAIN_GRAPH_REL:
ret += callchain__fprintf_graph(fp, chain, total_samples,
left_margin);
case CHAIN_NONE:
default:
break;
}

ret = percent_color_fprintf(fp, " %6.2f%%\n", percent);
ret += __callchain__fprintf_flat(fp, chain, total_samples);
ret += fprintf(fp, "\n");
if (++entries_printed == callchain_param.print_limit)
break;

rb_node = rb_next(rb_node);
}

return ret;
}

static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
u64 total_samples, int left_margin,
FILE *fp)
{
switch (callchain_param.mode) {
case CHAIN_GRAPH_REL:
return callchain__fprintf_graph(fp, &he->sorted_chain, he->period,
left_margin);
break;
case CHAIN_GRAPH_ABS:
return callchain__fprintf_graph(fp, &he->sorted_chain, total_samples,
left_margin);
break;
case CHAIN_FLAT:
return callchain__fprintf_flat(fp, &he->sorted_chain, total_samples);
break;
case CHAIN_NONE:
break;
default:
pr_err("Bad callchain mode\n");
}

return 0;
}

void hists__output_recalc_col_len(struct hists *hists, int max_rows)
{
struct rb_node *next = rb_first(&hists->entries);
Expand Down
Loading

0 comments on commit 8ebfdf2

Please sign in to comment.