diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/perf/builtin-annotate.c | 9 | ||||
-rw-r--r-- | tools/perf/builtin-diff.c | 14 | ||||
-rw-r--r-- | tools/perf/builtin-report.c | 48 | ||||
-rw-r--r-- | tools/perf/util/callchain.c | 7 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 4 | ||||
-rw-r--r-- | tools/perf/util/event.c | 27 | ||||
-rw-r--r-- | tools/perf/util/hist.c | 46 | ||||
-rw-r--r-- | tools/perf/util/hist.h | 5 | ||||
-rw-r--r-- | tools/perf/util/map.c | 24 | ||||
-rw-r--r-- | tools/perf/util/session.c | 8 | ||||
-rw-r--r-- | tools/perf/util/session.h | 14 | ||||
-rw-r--r-- | tools/perf/util/symbol.c | 2 | ||||
-rw-r--r-- | tools/perf/util/symbol.h | 2 |
13 files changed, 109 insertions, 101 deletions
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index ee154b58772b..c7ac45a59ed5 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
@@ -72,8 +72,6 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
72 | struct sym_priv *priv; | 72 | struct sym_priv *priv; |
73 | struct sym_hist *h; | 73 | struct sym_hist *h; |
74 | 74 | ||
75 | he->count++; | ||
76 | |||
77 | if (!sym || !he->ms.map) | 75 | if (!sym || !he->ms.map) |
78 | return 0; | 76 | return 0; |
79 | 77 | ||
@@ -99,9 +97,8 @@ static int annotate__hist_hit(struct hist_entry *he, u64 ip) | |||
99 | } | 97 | } |
100 | 98 | ||
101 | static int perf_session__add_hist_entry(struct perf_session *self, | 99 | static int perf_session__add_hist_entry(struct perf_session *self, |
102 | struct addr_location *al, u64 count) | 100 | struct addr_location *al) |
103 | { | 101 | { |
104 | bool hit; | ||
105 | struct hist_entry *he; | 102 | struct hist_entry *he; |
106 | 103 | ||
107 | if (sym_hist_filter != NULL && | 104 | if (sym_hist_filter != NULL && |
@@ -115,7 +112,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
115 | return 0; | 112 | return 0; |
116 | } | 113 | } |
117 | 114 | ||
118 | he = __perf_session__add_hist_entry(&self->hists, al, NULL, count, &hit); | 115 | he = __perf_session__add_hist_entry(&self->hists, al, NULL, 1); |
119 | if (he == NULL) | 116 | if (he == NULL) |
120 | return -ENOMEM; | 117 | return -ENOMEM; |
121 | 118 | ||
@@ -135,7 +132,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
135 | return -1; | 132 | return -1; |
136 | } | 133 | } |
137 | 134 | ||
138 | if (!al.filtered && perf_session__add_hist_entry(session, &al, 1)) { | 135 | if (!al.filtered && perf_session__add_hist_entry(session, &al)) { |
139 | pr_warning("problem incrementing symbol count, " | 136 | pr_warning("problem incrementing symbol count, " |
140 | "skipping event\n"); | 137 | "skipping event\n"); |
141 | return -1; | 138 | return -1; |
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c index 4cce68f23686..613a5c4f6d83 100644 --- a/tools/perf/builtin-diff.c +++ b/tools/perf/builtin-diff.c | |||
@@ -25,17 +25,9 @@ static bool show_displacement; | |||
25 | static int perf_session__add_hist_entry(struct perf_session *self, | 25 | static int perf_session__add_hist_entry(struct perf_session *self, |
26 | struct addr_location *al, u64 count) | 26 | struct addr_location *al, u64 count) |
27 | { | 27 | { |
28 | bool hit; | 28 | if (__perf_session__add_hist_entry(&self->hists, al, NULL, count) != NULL) |
29 | struct hist_entry *he = __perf_session__add_hist_entry(&self->hists, | 29 | return 0; |
30 | al, NULL, | 30 | return -ENOMEM; |
31 | count, &hit); | ||
32 | if (he == NULL) | ||
33 | return -ENOMEM; | ||
34 | |||
35 | if (hit) | ||
36 | __perf_session__add_count(he, al, count); | ||
37 | |||
38 | return 0; | ||
39 | } | 31 | } |
40 | 32 | ||
41 | static int diff__process_sample_event(event_t *event, struct perf_session *session) | 33 | static int diff__process_sample_event(event_t *event, struct perf_session *session) |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 196473b51257..642a6d8eb5dc 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -82,8 +82,7 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
82 | { | 82 | { |
83 | struct map_symbol *syms = NULL; | 83 | struct map_symbol *syms = NULL; |
84 | struct symbol *parent = NULL; | 84 | struct symbol *parent = NULL; |
85 | bool hit; | 85 | int err = -ENOMEM; |
86 | int err; | ||
87 | struct hist_entry *he; | 86 | struct hist_entry *he; |
88 | struct event_stat_id *stats; | 87 | struct event_stat_id *stats; |
89 | struct perf_event_attr *attr; | 88 | struct perf_event_attr *attr; |
@@ -101,39 +100,17 @@ static int perf_session__add_hist_entry(struct perf_session *self, | |||
101 | else | 100 | else |
102 | stats = get_stats(self, data->id, 0, 0); | 101 | stats = get_stats(self, data->id, 0, 0); |
103 | if (stats == NULL) | 102 | if (stats == NULL) |
104 | return -ENOMEM; | 103 | goto out_free_syms; |
105 | he = __perf_session__add_hist_entry(&stats->hists, al, parent, | 104 | he = __perf_session__add_hist_entry(&stats->hists, al, parent, |
106 | data->period, &hit); | 105 | data->period); |
107 | if (he == NULL) | 106 | if (he == NULL) |
108 | return -ENOMEM; | 107 | goto out_free_syms; |
109 | 108 | err = 0; | |
110 | if (hit) | 109 | if (symbol_conf.use_callchain) |
111 | __perf_session__add_count(he, al, data->period); | ||
112 | |||
113 | if (symbol_conf.use_callchain) { | ||
114 | if (!hit) | ||
115 | callchain_init(he->callchain); | ||
116 | err = append_chain(he->callchain, data->callchain, syms); | 110 | err = append_chain(he->callchain, data->callchain, syms); |
117 | free(syms); | 111 | out_free_syms: |
118 | 112 | free(syms); | |
119 | if (err) | 113 | return err; |
120 | return err; | ||
121 | } | ||
122 | |||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static int validate_chain(struct ip_callchain *chain, event_t *event) | ||
127 | { | ||
128 | unsigned int chain_size; | ||
129 | |||
130 | chain_size = event->header.size; | ||
131 | chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event; | ||
132 | |||
133 | if (chain->nr*sizeof(u64) > chain_size) | ||
134 | return -1; | ||
135 | |||
136 | return 0; | ||
137 | } | 114 | } |
138 | 115 | ||
139 | static int add_event_total(struct perf_session *session, | 116 | static int add_event_total(struct perf_session *session, |
@@ -171,7 +148,7 @@ static int process_sample_event(event_t *event, struct perf_session *session) | |||
171 | 148 | ||
172 | dump_printf("... chain: nr:%Lu\n", data.callchain->nr); | 149 | dump_printf("... chain: nr:%Lu\n", data.callchain->nr); |
173 | 150 | ||
174 | if (validate_chain(data.callchain, event) < 0) { | 151 | if (!ip_callchain__valid(data.callchain, event)) { |
175 | pr_debug("call-chain problem with event, " | 152 | pr_debug("call-chain problem with event, " |
176 | "skipping it.\n"); | 153 | "skipping it.\n"); |
177 | return 0; | 154 | return 0; |
@@ -366,7 +343,7 @@ static int | |||
366 | parse_callchain_opt(const struct option *opt __used, const char *arg, | 343 | parse_callchain_opt(const struct option *opt __used, const char *arg, |
367 | int unset) | 344 | int unset) |
368 | { | 345 | { |
369 | char *tok; | 346 | char *tok, *tok2; |
370 | char *endptr; | 347 | char *endptr; |
371 | 348 | ||
372 | /* | 349 | /* |
@@ -411,10 +388,13 @@ parse_callchain_opt(const struct option *opt __used, const char *arg, | |||
411 | if (!tok) | 388 | if (!tok) |
412 | goto setup; | 389 | goto setup; |
413 | 390 | ||
391 | tok2 = strtok(NULL, ","); | ||
414 | callchain_param.min_percent = strtod(tok, &endptr); | 392 | callchain_param.min_percent = strtod(tok, &endptr); |
415 | if (tok == endptr) | 393 | if (tok == endptr) |
416 | return -1; | 394 | return -1; |
417 | 395 | ||
396 | if (tok2) | ||
397 | callchain_param.print_limit = strtod(tok2, &endptr); | ||
418 | setup: | 398 | setup: |
419 | if (register_callchain_param(&callchain_param) < 0) { | 399 | if (register_callchain_param(&callchain_param) < 0) { |
420 | fprintf(stderr, "Can't register callchain params\n"); | 400 | fprintf(stderr, "Can't register callchain params\n"); |
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index db628af6d20d..ac148613afe8 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c | |||
@@ -17,6 +17,13 @@ | |||
17 | 17 | ||
18 | #include "callchain.h" | 18 | #include "callchain.h" |
19 | 19 | ||
20 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event) | ||
21 | { | ||
22 | unsigned int chain_size = event->header.size; | ||
23 | chain_size -= (unsigned long)&event->ip.__more_data - (unsigned long)event; | ||
24 | return chain->nr * sizeof(u64) <= chain_size; | ||
25 | } | ||
26 | |||
20 | #define chain_for_each_child(child, parent) \ | 27 | #define chain_for_each_child(child, parent) \ |
21 | list_for_each_entry(child, &parent->children, brothers) | 28 | list_for_each_entry(child, &parent->children, brothers) |
22 | 29 | ||
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index 8a7e8bbd0fda..1cba1f5504e7 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include "../perf.h" | 4 | #include "../perf.h" |
5 | #include <linux/list.h> | 5 | #include <linux/list.h> |
6 | #include <linux/rbtree.h> | 6 | #include <linux/rbtree.h> |
7 | #include "event.h" | ||
7 | #include "util.h" | 8 | #include "util.h" |
8 | #include "symbol.h" | 9 | #include "symbol.h" |
9 | 10 | ||
@@ -33,6 +34,7 @@ typedef void (*sort_chain_func_t)(struct rb_root *, struct callchain_node *, | |||
33 | 34 | ||
34 | struct callchain_param { | 35 | struct callchain_param { |
35 | enum chain_mode mode; | 36 | enum chain_mode mode; |
37 | u32 print_limit; | ||
36 | double min_percent; | 38 | double min_percent; |
37 | sort_chain_func_t sort; | 39 | sort_chain_func_t sort; |
38 | }; | 40 | }; |
@@ -58,4 +60,6 @@ static inline u64 cumul_hits(struct callchain_node *node) | |||
58 | int register_callchain_param(struct callchain_param *param); | 60 | int register_callchain_param(struct callchain_param *param); |
59 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, | 61 | int append_chain(struct callchain_node *root, struct ip_callchain *chain, |
60 | struct map_symbol *syms); | 62 | struct map_symbol *syms); |
63 | |||
64 | bool ip_callchain__valid(struct ip_callchain *chain, event_t *event); | ||
61 | #endif /* __PERF_CALLCHAIN_H */ | 65 | #endif /* __PERF_CALLCHAIN_H */ |
diff --git a/tools/perf/util/event.c b/tools/perf/util/event.c index 23d5dfd4ed73..d2ea9dd9fdf1 100644 --- a/tools/perf/util/event.c +++ b/tools/perf/util/event.c | |||
@@ -493,8 +493,10 @@ int event__process_mmap(event_t *self, struct perf_session *session) | |||
493 | return 0; | 493 | return 0; |
494 | } | 494 | } |
495 | 495 | ||
496 | thread = perf_session__findnew(session, self->mmap.pid); | ||
497 | machine = perf_session__find_host_machine(session); | 496 | machine = perf_session__find_host_machine(session); |
497 | if (machine == NULL) | ||
498 | goto out_problem; | ||
499 | thread = perf_session__findnew(session, self->mmap.pid); | ||
498 | map = map__new(&machine->user_dsos, self->mmap.start, | 500 | map = map__new(&machine->user_dsos, self->mmap.start, |
499 | self->mmap.len, self->mmap.pgoff, | 501 | self->mmap.len, self->mmap.pgoff, |
500 | self->mmap.pid, self->mmap.filename, | 502 | self->mmap.pid, self->mmap.filename, |
@@ -552,6 +554,10 @@ void thread__find_addr_map(struct thread *self, | |||
552 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { | 554 | if (cpumode == PERF_RECORD_MISC_KERNEL && perf_host) { |
553 | al->level = 'k'; | 555 | al->level = 'k'; |
554 | machine = perf_session__find_host_machine(session); | 556 | machine = perf_session__find_host_machine(session); |
557 | if (machine == NULL) { | ||
558 | al->map = NULL; | ||
559 | return; | ||
560 | } | ||
555 | mg = &machine->kmaps; | 561 | mg = &machine->kmaps; |
556 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { | 562 | } else if (cpumode == PERF_RECORD_MISC_USER && perf_host) { |
557 | al->level = '.'; | 563 | al->level = '.'; |
@@ -559,7 +565,7 @@ void thread__find_addr_map(struct thread *self, | |||
559 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { | 565 | } else if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL && perf_guest) { |
560 | al->level = 'g'; | 566 | al->level = 'g'; |
561 | machine = perf_session__find_machine(session, pid); | 567 | machine = perf_session__find_machine(session, pid); |
562 | if (!machine) { | 568 | if (machine == NULL) { |
563 | al->map = NULL; | 569 | al->map = NULL; |
564 | return; | 570 | return; |
565 | } | 571 | } |
@@ -650,6 +656,16 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
650 | goto out_filtered; | 656 | goto out_filtered; |
651 | 657 | ||
652 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); | 658 | dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); |
659 | /* | ||
660 | * Have we already created the kernel maps for the host machine? | ||
661 | * | ||
662 | * This should have happened earlier, when we processed the kernel MMAP | ||
663 | * events, but for older perf.data files there was no such thing, so do | ||
664 | * it now. | ||
665 | */ | ||
666 | if (cpumode == PERF_RECORD_MISC_KERNEL && | ||
667 | session->host_machine.vmlinux_maps[MAP__FUNCTION] == NULL) | ||
668 | machine__create_kernel_maps(&session->host_machine); | ||
653 | 669 | ||
654 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, | 670 | thread__find_addr_map(thread, session, cpumode, MAP__FUNCTION, |
655 | self->ip.pid, self->ip.ip, al); | 671 | self->ip.pid, self->ip.ip, al); |
@@ -676,6 +692,13 @@ int event__preprocess_sample(const event_t *self, struct perf_session *session, | |||
676 | dso__calc_col_width(al->map->dso); | 692 | dso__calc_col_width(al->map->dso); |
677 | 693 | ||
678 | al->sym = map__find_symbol(al->map, al->addr, filter); | 694 | al->sym = map__find_symbol(al->map, al->addr, filter); |
695 | } else { | ||
696 | const unsigned int unresolved_col_width = BITS_PER_LONG / 4; | ||
697 | |||
698 | if (dsos__col_width < unresolved_col_width && | ||
699 | !symbol_conf.col_width_list_str && !symbol_conf.field_sep && | ||
700 | !symbol_conf.dso_list) | ||
701 | dsos__col_width = unresolved_col_width; | ||
679 | } | 702 | } |
680 | 703 | ||
681 | if (symbol_conf.sym_list && al->sym && | 704 | if (symbol_conf.sym_list && al->sym && |
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index ad6b22dde27f..0f154a530dfd 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
@@ -8,13 +8,10 @@ struct callchain_param callchain_param = { | |||
8 | .min_percent = 0.5 | 8 | .min_percent = 0.5 |
9 | }; | 9 | }; |
10 | 10 | ||
11 | void __perf_session__add_count(struct hist_entry *he, | 11 | static void perf_session__add_cpumode_count(struct hist_entry *he, |
12 | struct addr_location *al, | 12 | unsigned int cpumode, u64 count) |
13 | u64 count) | ||
14 | { | 13 | { |
15 | he->count += count; | 14 | switch (cpumode) { |
16 | |||
17 | switch (al->cpumode) { | ||
18 | case PERF_RECORD_MISC_KERNEL: | 15 | case PERF_RECORD_MISC_KERNEL: |
19 | he->count_sys += count; | 16 | he->count_sys += count; |
20 | break; | 17 | break; |
@@ -36,10 +33,24 @@ void __perf_session__add_count(struct hist_entry *he, | |||
36 | * histogram, sorted on item, collects counts | 33 | * histogram, sorted on item, collects counts |
37 | */ | 34 | */ |
38 | 35 | ||
36 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | ||
37 | { | ||
38 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_node) : 0; | ||
39 | struct hist_entry *self = malloc(sizeof(*self) + callchain_size); | ||
40 | |||
41 | if (self != NULL) { | ||
42 | *self = *template; | ||
43 | if (symbol_conf.use_callchain) | ||
44 | callchain_init(self->callchain); | ||
45 | } | ||
46 | |||
47 | return self; | ||
48 | } | ||
49 | |||
39 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 50 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, |
40 | struct addr_location *al, | 51 | struct addr_location *al, |
41 | struct symbol *sym_parent, | 52 | struct symbol *sym_parent, |
42 | u64 count, bool *hit) | 53 | u64 count) |
43 | { | 54 | { |
44 | struct rb_node **p = &hists->rb_node; | 55 | struct rb_node **p = &hists->rb_node; |
45 | struct rb_node *parent = NULL; | 56 | struct rb_node *parent = NULL; |
@@ -64,8 +75,8 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
64 | cmp = hist_entry__cmp(&entry, he); | 75 | cmp = hist_entry__cmp(&entry, he); |
65 | 76 | ||
66 | if (!cmp) { | 77 | if (!cmp) { |
67 | *hit = true; | 78 | he->count += count; |
68 | return he; | 79 | goto out; |
69 | } | 80 | } |
70 | 81 | ||
71 | if (cmp < 0) | 82 | if (cmp < 0) |
@@ -74,14 +85,13 @@ struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | |||
74 | p = &(*p)->rb_right; | 85 | p = &(*p)->rb_right; |
75 | } | 86 | } |
76 | 87 | ||
77 | he = malloc(sizeof(*he) + (symbol_conf.use_callchain ? | 88 | he = hist_entry__new(&entry); |
78 | sizeof(struct callchain_node) : 0)); | ||
79 | if (!he) | 89 | if (!he) |
80 | return NULL; | 90 | return NULL; |
81 | *he = entry; | ||
82 | rb_link_node(&he->rb_node, parent, p); | 91 | rb_link_node(&he->rb_node, parent, p); |
83 | rb_insert_color(&he->rb_node, hists); | 92 | rb_insert_color(&he->rb_node, hists); |
84 | *hit = false; | 93 | out: |
94 | perf_session__add_cpumode_count(he, al->cpumode, count); | ||
85 | return he; | 95 | return he; |
86 | } | 96 | } |
87 | 97 | ||
@@ -323,6 +333,7 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
323 | u64 remaining; | 333 | u64 remaining; |
324 | size_t ret = 0; | 334 | size_t ret = 0; |
325 | int i; | 335 | int i; |
336 | uint entries_printed = 0; | ||
326 | 337 | ||
327 | if (callchain_param.mode == CHAIN_GRAPH_REL) | 338 | if (callchain_param.mode == CHAIN_GRAPH_REL) |
328 | new_total = self->children_hit; | 339 | new_total = self->children_hit; |
@@ -369,6 +380,8 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
369 | new_depth_mask | (1 << depth), | 380 | new_depth_mask | (1 << depth), |
370 | left_margin); | 381 | left_margin); |
371 | node = next; | 382 | node = next; |
383 | if (++entries_printed == callchain_param.print_limit) | ||
384 | break; | ||
372 | } | 385 | } |
373 | 386 | ||
374 | if (callchain_param.mode == CHAIN_GRAPH_REL && | 387 | if (callchain_param.mode == CHAIN_GRAPH_REL && |
@@ -394,6 +407,7 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
394 | bool printed = false; | 407 | bool printed = false; |
395 | int i = 0; | 408 | int i = 0; |
396 | int ret = 0; | 409 | int ret = 0; |
410 | u32 entries_printed = 0; | ||
397 | 411 | ||
398 | list_for_each_entry(chain, &self->val, list) { | 412 | list_for_each_entry(chain, &self->val, list) { |
399 | if (!i++ && sort__first_dimension == SORT_SYM) | 413 | if (!i++ && sort__first_dimension == SORT_SYM) |
@@ -414,6 +428,9 @@ static size_t callchain__fprintf_graph(FILE *fp, struct callchain_node *self, | |||
414 | ret += fprintf(fp, " %s\n", chain->ms.sym->name); | 428 | ret += fprintf(fp, " %s\n", chain->ms.sym->name); |
415 | else | 429 | else |
416 | ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); | 430 | ret += fprintf(fp, " %p\n", (void *)(long)chain->ip); |
431 | |||
432 | if (++entries_printed == callchain_param.print_limit) | ||
433 | break; | ||
417 | } | 434 | } |
418 | 435 | ||
419 | ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin); | 436 | ret += __callchain__fprintf_graph(fp, self, total_samples, 1, 1, left_margin); |
@@ -452,6 +469,7 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
452 | struct rb_node *rb_node; | 469 | struct rb_node *rb_node; |
453 | struct callchain_node *chain; | 470 | struct callchain_node *chain; |
454 | size_t ret = 0; | 471 | size_t ret = 0; |
472 | u32 entries_printed = 0; | ||
455 | 473 | ||
456 | rb_node = rb_first(&self->sorted_chain); | 474 | rb_node = rb_first(&self->sorted_chain); |
457 | while (rb_node) { | 475 | while (rb_node) { |
@@ -474,6 +492,8 @@ static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |||
474 | break; | 492 | break; |
475 | } | 493 | } |
476 | ret += fprintf(fp, "\n"); | 494 | ret += fprintf(fp, "\n"); |
495 | if (++entries_printed == callchain_param.print_limit) | ||
496 | break; | ||
477 | rb_node = rb_next(rb_node); | 497 | rb_node = rb_next(rb_node); |
478 | } | 498 | } |
479 | 499 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index 9df1c340ec92..b49013adb34b 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
@@ -12,13 +12,10 @@ struct addr_location; | |||
12 | struct symbol; | 12 | struct symbol; |
13 | struct rb_root; | 13 | struct rb_root; |
14 | 14 | ||
15 | void __perf_session__add_count(struct hist_entry *he, | ||
16 | struct addr_location *al, | ||
17 | u64 count); | ||
18 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, | 15 | struct hist_entry *__perf_session__add_hist_entry(struct rb_root *hists, |
19 | struct addr_location *al, | 16 | struct addr_location *al, |
20 | struct symbol *parent, | 17 | struct symbol *parent, |
21 | u64 count, bool *hit); | 18 | u64 count); |
22 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 19 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); |
23 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 20 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); |
24 | int hist_entry__fprintf(struct hist_entry *self, | 21 | int hist_entry__fprintf(struct hist_entry *self, |
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c index 44a4df68b3cf..e672f2fef65b 100644 --- a/tools/perf/util/map.c +++ b/tools/perf/util/map.c | |||
@@ -579,30 +579,6 @@ struct machine *machines__find(struct rb_root *self, pid_t pid) | |||
579 | return default_machine; | 579 | return default_machine; |
580 | } | 580 | } |
581 | 581 | ||
582 | /* | ||
583 | * FIXME: Why repeatedly search for this? | ||
584 | */ | ||
585 | struct machine *machines__find_host(struct rb_root *self) | ||
586 | { | ||
587 | struct rb_node **p = &self->rb_node; | ||
588 | struct rb_node *parent = NULL; | ||
589 | struct machine *machine; | ||
590 | pid_t pid = HOST_KERNEL_ID; | ||
591 | |||
592 | while (*p != NULL) { | ||
593 | parent = *p; | ||
594 | machine = rb_entry(parent, struct machine, rb_node); | ||
595 | if (pid < machine->pid) | ||
596 | p = &(*p)->rb_left; | ||
597 | else if (pid > machine->pid) | ||
598 | p = &(*p)->rb_right; | ||
599 | else | ||
600 | return machine; | ||
601 | } | ||
602 | |||
603 | return NULL; | ||
604 | } | ||
605 | |||
606 | struct machine *machines__findnew(struct rb_root *self, pid_t pid) | 582 | struct machine *machines__findnew(struct rb_root *self, pid_t pid) |
607 | { | 583 | { |
608 | char path[PATH_MAX]; | 584 | char path[PATH_MAX]; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 00ab298bbb4b..c088d8f9b51c 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -99,6 +99,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, bool forc | |||
99 | self->machines = RB_ROOT; | 99 | self->machines = RB_ROOT; |
100 | self->repipe = repipe; | 100 | self->repipe = repipe; |
101 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); | 101 | INIT_LIST_HEAD(&self->ordered_samples.samples_head); |
102 | machine__init(&self->host_machine, "", HOST_KERNEL_ID); | ||
102 | 103 | ||
103 | if (mode == O_RDONLY) { | 104 | if (mode == O_RDONLY) { |
104 | if (perf_session__open(self, force) < 0) | 105 | if (perf_session__open(self, force) < 0) |
@@ -919,3 +920,10 @@ int perf_session__set_kallsyms_ref_reloc_sym(struct map **maps, | |||
919 | 920 | ||
920 | return 0; | 921 | return 0; |
921 | } | 922 | } |
923 | |||
924 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) | ||
925 | { | ||
926 | return __dsos__fprintf(&self->host_machine.kernel_dsos, fp) + | ||
927 | __dsos__fprintf(&self->host_machine.user_dsos, fp) + | ||
928 | machines__fprintf_dsos(&self->machines, fp); | ||
929 | } | ||
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 568fd08a478d..242d528bfae2 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -26,6 +26,7 @@ struct perf_session { | |||
26 | unsigned long mmap_window; | 26 | unsigned long mmap_window; |
27 | struct rb_root threads; | 27 | struct rb_root threads; |
28 | struct thread *last_match; | 28 | struct thread *last_match; |
29 | struct machine host_machine; | ||
29 | struct rb_root machines; | 30 | struct rb_root machines; |
30 | struct events_stats events_stats; | 31 | struct events_stats events_stats; |
31 | struct rb_root stats_by_id; | 32 | struct rb_root stats_by_id; |
@@ -113,18 +114,22 @@ int perf_session__browse_hists(struct rb_root *hists, u64 nr_hists, | |||
113 | static inline | 114 | static inline |
114 | struct machine *perf_session__find_host_machine(struct perf_session *self) | 115 | struct machine *perf_session__find_host_machine(struct perf_session *self) |
115 | { | 116 | { |
116 | return machines__find_host(&self->machines); | 117 | return &self->host_machine; |
117 | } | 118 | } |
118 | 119 | ||
119 | static inline | 120 | static inline |
120 | struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid) | 121 | struct machine *perf_session__find_machine(struct perf_session *self, pid_t pid) |
121 | { | 122 | { |
123 | if (pid == HOST_KERNEL_ID) | ||
124 | return &self->host_machine; | ||
122 | return machines__find(&self->machines, pid); | 125 | return machines__find(&self->machines, pid); |
123 | } | 126 | } |
124 | 127 | ||
125 | static inline | 128 | static inline |
126 | struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid) | 129 | struct machine *perf_session__findnew_machine(struct perf_session *self, pid_t pid) |
127 | { | 130 | { |
131 | if (pid == HOST_KERNEL_ID) | ||
132 | return &self->host_machine; | ||
128 | return machines__findnew(&self->machines, pid); | 133 | return machines__findnew(&self->machines, pid); |
129 | } | 134 | } |
130 | 135 | ||
@@ -132,14 +137,11 @@ static inline | |||
132 | void perf_session__process_machines(struct perf_session *self, | 137 | void perf_session__process_machines(struct perf_session *self, |
133 | machine__process_t process) | 138 | machine__process_t process) |
134 | { | 139 | { |
140 | process(&self->host_machine, self); | ||
135 | return machines__process(&self->machines, process, self); | 141 | return machines__process(&self->machines, process, self); |
136 | } | 142 | } |
137 | 143 | ||
138 | static inline | 144 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp); |
139 | size_t perf_session__fprintf_dsos(struct perf_session *self, FILE *fp) | ||
140 | { | ||
141 | return machines__fprintf_dsos(&self->machines, fp); | ||
142 | } | ||
143 | 145 | ||
144 | static inline | 146 | static inline |
145 | size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, | 147 | size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, FILE *fp, |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index 4c0146a49063..994efdb531e4 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -1889,7 +1889,7 @@ struct dso *__dsos__findnew(struct list_head *head, const char *name) | |||
1889 | return dso; | 1889 | return dso; |
1890 | } | 1890 | } |
1891 | 1891 | ||
1892 | static size_t __dsos__fprintf(struct list_head *head, FILE *fp) | 1892 | size_t __dsos__fprintf(struct list_head *head, FILE *fp) |
1893 | { | 1893 | { |
1894 | struct dso *pos; | 1894 | struct dso *pos; |
1895 | size_t ret = 0; | 1895 | size_t ret = 0; |
diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index a517c17407b7..edff866d76b2 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h | |||
@@ -167,6 +167,8 @@ int machine__load_kallsyms(struct machine *self, const char *filename, | |||
167 | int machine__load_vmlinux_path(struct machine *self, enum map_type type, | 167 | int machine__load_vmlinux_path(struct machine *self, enum map_type type, |
168 | symbol_filter_t filter); | 168 | symbol_filter_t filter); |
169 | 169 | ||
170 | size_t __dsos__fprintf(struct list_head *head, FILE *fp); | ||
171 | |||
170 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); | 172 | size_t machines__fprintf_dsos(struct rb_root *self, FILE *fp); |
171 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); | 173 | size_t machines__fprintf_dsos_buildid(struct rb_root *self, FILE *fp, bool with_hits); |
172 | 174 | ||