Skip to content

Commit 8ebfdf2

Browse files
author
Ingo Molnar
committed
Merge branch 'perf/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
2 parents 12b5da3 + 65f3e56 commit 8ebfdf2

15 files changed

+135
-8546
lines changed

tools/perf/Makefile

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,6 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
6161

6262
CC = $(CROSS_COMPILE)gcc
6363
AR = $(CROSS_COMPILE)ar
64-
FLEX = $(CROSS_COMPILE)flex
65-
BISON= $(CROSS_COMPILE)bison
6664

6765
# Additional ARCH settings for x86
6866
ifeq ($(ARCH),i386)
@@ -184,7 +182,7 @@ endif
184182

185183
### --- END CONFIGURATION SECTION ---
186184

187-
BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
185+
BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include -I$(OUTPUT)/util -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
188186
BASIC_LDFLAGS =
189187

190188
# Guard against environment variables
@@ -236,6 +234,25 @@ endif
236234

237235
export PERL_PATH
238236

237+
FLEX = $(CROSS_COMPILE)flex
238+
BISON= $(CROSS_COMPILE)bison
239+
240+
event-parser:
241+
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o $(OUTPUT)util/parse-events-bison.c
242+
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
243+
244+
$(OUTPUT)util/parse-events-flex.c: event-parser
245+
$(OUTPUT)util/parse-events-bison.c: event-parser
246+
247+
pmu-parser:
248+
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c
249+
$(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
250+
251+
$(OUTPUT)util/pmu-flex.c: pmu-parser
252+
$(OUTPUT)util/pmu-bison.c: pmu-parser
253+
254+
$(OUTPUT)util/parse-events.o: event-parser pmu-parser
255+
239256
LIB_FILE=$(OUTPUT)libperf.a
240257

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

774+
# These two need to be here so that when O= is not used they take precedence
775+
# over the general rule for .o
776+
777+
$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
778+
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
779+
780+
$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
781+
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -Iutil/ -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
782+
757783
$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
758784
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
759785
$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
@@ -790,12 +816,6 @@ $(OUTPUT)util/ui/browsers/map.o: util/ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
790816
$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
791817
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
792818

793-
$(OUTPUT)util/parse-events-flex.o: util/parse-events-flex.c $(OUTPUT)PERF-CFLAGS
794-
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
795-
796-
$(OUTPUT)util/pmu-flex.o: util/pmu-flex.c $(OUTPUT)PERF-CFLAGS
797-
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls -Wno-switch-default -Wno-unused-function $<
798-
799819
$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
800820
$(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
801821

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

886-
event-parser:
887-
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d -o util/parse-events-bison.c
888-
$(QUIET_FLEX)$(FLEX) --header-file=util/parse-events-flex.h -t util/parse-events.l > util/parse-events-flex.c
889-
890-
pmu-parser:
891-
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o util/pmu-bison.c
892-
$(QUIET_FLEX)$(FLEX) --header-file=util/pmu-flex.h -t util/pmu.l > util/pmu-flex.c
893-
894906
### Detect prefix changes
895907
TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
896908
$(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
@@ -978,6 +990,7 @@ clean:
978990
$(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
979991
$(MAKE) -C Documentation/ clean
980992
$(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
993+
$(RM) $(OUTPUT)util/*-{bison,flex}*
981994
$(python-clean)
982995

983996
.PHONY: all install clean strip

tools/perf/util/annotate.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ int symbol__annotate_init(struct map *map __used, struct symbol *sym)
2828
int symbol__alloc_hist(struct symbol *sym)
2929
{
3030
struct annotation *notes = symbol__annotation(sym);
31-
size_t sizeof_sym_hist = (sizeof(struct sym_hist) +
32-
(sym->end - sym->start) * sizeof(u64));
31+
const size_t size = sym->end - sym->start + 1;
32+
size_t sizeof_sym_hist = (sizeof(struct sym_hist) + size * sizeof(u64));
3333

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

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

67-
if (addr >= sym->end)
67+
if (addr > sym->end)
6868
return 0;
6969

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

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

413413
for (i = 0; i < len; i++) {
414414
char *path = NULL;

tools/perf/util/evsel.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ int perf_event__parse_sample(const union perf_event *event, u64 type,
580580
return -EFAULT;
581581

582582
data->raw_data = (void *) pdata;
583+
584+
array = (void *)array + data->raw_size + sizeof(u32);
583585
}
584586

585587
if (type & PERF_SAMPLE_BRANCH_STACK) {

tools/perf/util/hist.c

Lines changed: 93 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -607,29 +607,24 @@ static void init_rem_hits(void)
607607
rem_hits.ms.sym = rem_sq_bracket;
608608
}
609609

610-
static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
610+
static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
611611
u64 total_samples, int depth,
612612
int depth_mask, int left_margin)
613613
{
614614
struct rb_node *node, *next;
615615
struct callchain_node *child;
616616
struct callchain_list *chain;
617617
int new_depth_mask = depth_mask;
618-
u64 new_total;
619618
u64 remaining;
620619
size_t ret = 0;
621620
int i;
622621
uint entries_printed = 0;
623622

624-
if (callchain_param.mode == CHAIN_GRAPH_REL)
625-
new_total = self->children_hit;
626-
else
627-
new_total = total_samples;
628-
629-
remaining = new_total;
623+
remaining = total_samples;
630624

631-
node = rb_first(&self->rb_root);
625+
node = rb_first(root);
632626
while (node) {
627+
u64 new_total;
633628
u64 cumul;
634629

635630
child = rb_entry(node, struct callchain_node, rb_node);
@@ -657,11 +652,17 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
657652
list_for_each_entry(chain, &child->val, list) {
658653
ret += ipchain__fprintf_graph(fp, chain, depth,
659654
new_depth_mask, i++,
660-
new_total,
655+
total_samples,
661656
cumul,
662657
left_margin);
663658
}
664-
ret += __callchain__fprintf_graph(fp, child, new_total,
659+
660+
if (callchain_param.mode == CHAIN_GRAPH_REL)
661+
new_total = child->children_hit;
662+
else
663+
new_total = total_samples;
664+
665+
ret += __callchain__fprintf_graph(fp, &child->rb_root, new_total,
665666
depth + 1,
666667
new_depth_mask | (1 << depth),
667668
left_margin);
@@ -671,69 +672,83 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
671672
}
672673

673674
if (callchain_param.mode == CHAIN_GRAPH_REL &&
674-
remaining && remaining != new_total) {
675+
remaining && remaining != total_samples) {
675676

676677
if (!rem_sq_bracket)
677678
return ret;
678679

679680
new_depth_mask &= ~(1 << (depth - 1));
680-
681681
ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
682-
new_depth_mask, 0, new_total,
682+
new_depth_mask, 0, total_samples,
683683
remaining, left_margin);
684684
}
685685

686686
return ret;
687687
}
688688

689-
static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self,
689+
static size_t callchain__fprintf_graph(FILE *fp, struct rb_root *root,
690690
u64 total_samples, int left_margin)
691691
{
692+
struct callchain_node *cnode;
692693
struct callchain_list *chain;
694+
u32 entries_printed = 0;
693695
bool printed = false;
696+
struct rb_node *node;
694697
int i = 0;
695-
int ret = 0;
696-
u32 entries_printed = 0;
697-
698-
list_for_each_entry(chain, &self->val, list) {
699-
if (!i++ && sort__first_dimension == SORT_SYM)
700-
continue;
701-
702-
if (!printed) {
703-
ret += callchain__fprintf_left_margin(fp, left_margin);
704-
ret += fprintf(fp, "|\n");
705-
ret += callchain__fprintf_left_margin(fp, left_margin);
706-
ret += fprintf(fp, "---");
707-
708-
left_margin += 3;
709-
printed = true;
710-
} else
711-
ret += callchain__fprintf_left_margin(fp, left_margin);
698+
int ret;
712699

713-
if (chain->ms.sym)
714-
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
715-
else
716-
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
700+
/*
701+
* If have one single callchain root, don't bother printing
702+
* its percentage (100 % in fractal mode and the same percentage
703+
* than the hist in graph mode). This also avoid one level of column.
704+
*/
705+
node = rb_first(root);
706+
if (node && !rb_next(node)) {
707+
cnode = rb_entry(node, struct callchain_node, rb_node);
708+
list_for_each_entry(chain, &cnode->val, list) {
709+
/*
710+
* If we sort by symbol, the first entry is the same than
711+
* the symbol. No need to print it otherwise it appears as
712+
* displayed twice.
713+
*/
714+
if (!i++ && sort__first_dimension == SORT_SYM)
715+
continue;
716+
if (!printed) {
717+
ret += callchain__fprintf_left_margin(fp, left_margin);
718+
ret += fprintf(fp, "|\n");
719+
ret += callchain__fprintf_left_margin(fp, left_margin);
720+
ret += fprintf(fp, "---");
721+
left_margin += 3;
722+
printed = true;
723+
} else
724+
ret += callchain__fprintf_left_margin(fp, left_margin);
725+
726+
if (chain->ms.sym)
727+
ret += fprintf(fp, " %s\n", chain->ms.sym->name);
728+
else
729+
ret += fprintf(fp, " %p\n", (void *)(long)chain->ip);
717730

718-
if (++entries_printed == callchain_param.print_limit)
719-
break;
731+
if (++entries_printed == callchain_param.print_limit)
732+
break;
733+
}
734+
root = &cnode->rb_root;
720735
}
721736

722-
ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin);
723-
724-
return ret;
737+
return __callchain__fprintf_graph(fp, root, total_samples,
738+
1, 1, left_margin);
725739
}
726740

727-
static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self,
728-
u64 total_samples)
741+
static size_t __callchain__fprintf_flat(FILE *fp,
742+
struct callchain_node *self,
743+
u64 total_samples)
729744
{
730745
struct callchain_list *chain;
731746
size_t ret = 0;
732747

733748
if (!self)
734749
return 0;
735750

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

738753

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

752-
static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
753-
u64 total_samples, int left_margin,
754-
FILE *fp)
767+
static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *self,
768+
u64 total_samples)
755769
{
756-
struct rb_node *rb_node;
757-
struct callchain_node *chain;
758770
size_t ret = 0;
759771
u32 entries_printed = 0;
772+
struct rb_node *rb_node;
773+
struct callchain_node *chain;
760774

761-
rb_node = rb_first(&he->sorted_chain);
775+
rb_node = rb_first(self);
762776
while (rb_node) {
763777
double percent;
764778

765779
chain = rb_entry(rb_node, struct callchain_node, rb_node);
766780
percent = chain->hit * 100.0 / total_samples;
767-
switch (callchain_param.mode) {
768-
case CHAIN_FLAT:
769-
ret += percent_color_fprintf(fp, " %6.2f%%\n",
770-
percent);
771-
ret += callchain__fprintf_flat(fp, chain, total_samples);
772-
break;
773-
case CHAIN_GRAPH_ABS: /* Falldown */
774-
case CHAIN_GRAPH_REL:
775-
ret += callchain__fprintf_graph(fp, chain, total_samples,
776-
left_margin);
777-
case CHAIN_NONE:
778-
default:
779-
break;
780-
}
781+
782+
ret = percent_color_fprintf(fp, " %6.2f%%\n", percent);
783+
ret += __callchain__fprintf_flat(fp, chain, total_samples);
781784
ret += fprintf(fp, "\n");
782785
if (++entries_printed == callchain_param.print_limit)
783786
break;
787+
784788
rb_node = rb_next(rb_node);
785789
}
786790

787791
return ret;
788792
}
789793

794+
static size_t hist_entry_callchain__fprintf(struct hist_entry *he,
795+
u64 total_samples, int left_margin,
796+
FILE *fp)
797+
{
798+
switch (callchain_param.mode) {
799+
case CHAIN_GRAPH_REL:
800+
return callchain__fprintf_graph(fp, &he->sorted_chain, he->period,
801+
left_margin);
802+
break;
803+
case CHAIN_GRAPH_ABS:
804+
return callchain__fprintf_graph(fp, &he->sorted_chain, total_samples,
805+
left_margin);
806+
break;
807+
case CHAIN_FLAT:
808+
return callchain__fprintf_flat(fp, &he->sorted_chain, total_samples);
809+
break;
810+
case CHAIN_NONE:
811+
break;
812+
default:
813+
pr_err("Bad callchain mode\n");
814+
}
815+
816+
return 0;
817+
}
818+
790819
void hists__output_recalc_col_len(struct hists *hists, int max_rows)
791820
{
792821
struct rb_node *next = rb_first(&hists->entries);

0 commit comments

Comments
 (0)