diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-15 14:26:35 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-01-15 14:26:35 -0500 |
| commit | 83c2f912b43c3a7babbb6cb7ae2a5276c1ed2a3e (patch) | |
| tree | eaa7f50dea154d9f19721db69c7adde64d48848f /tools | |
| parent | f0ed5b9a28536b8be2f578a9450cfa42ab31ccf8 (diff) | |
| parent | 172d1b0b73256551f100fc00c69e356d047103f5 (diff) | |
Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (39 commits)
perf tools: Fix compile error on x86_64 Ubuntu
perf report: Fix --stdio output alignment when --showcpuutilization used
perf annotate: Get rid of field_sep check
perf annotate: Fix usage string
perf kmem: Fix a memory leak
perf kmem: Add missing closedir() calls
perf top: Add error message for EMFILE
perf test: Change type of '-v' option to INCR
perf script: Add missing closedir() calls
tracing: Fix compile error when static ftrace is enabled
recordmcount: Fix handling of elf64 big-endian objects.
perf tools: Add const.h to MANIFEST to make perf-tar-src-pkg work again
perf tools: Add support for guest/host-only profiling
perf kvm: Do guest-only counting by default
perf top: Don't update total_period on process_sample
perf hists: Stop using 'self' for struct hist_entry
perf hists: Rename total_session to total_period
x86: Add counter when debug stack is used with interrupts enabled
x86: Allow NMIs to hit breakpoints in i386
x86: Keep current stack in NMI breakpoints
...
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/perf/Documentation/perf-list.txt | 2 | ||||
| -rw-r--r-- | tools/perf/MANIFEST | 1 | ||||
| -rw-r--r-- | tools/perf/builtin-annotate.c | 7 | ||||
| -rw-r--r-- | tools/perf/builtin-kmem.c | 3 | ||||
| -rw-r--r-- | tools/perf/builtin-kvm.c | 6 | ||||
| -rw-r--r-- | tools/perf/builtin-script.c | 4 | ||||
| -rw-r--r-- | tools/perf/builtin-test.c | 2 | ||||
| -rw-r--r-- | tools/perf/builtin-top.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/evlist.c | 5 | ||||
| -rw-r--r-- | tools/perf/util/hist.c | 131 | ||||
| -rw-r--r-- | tools/perf/util/hist.h | 7 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.c | 15 | ||||
| -rw-r--r-- | tools/perf/util/trace-event-info.c | 1 | ||||
| -rw-r--r-- | tools/perf/util/util.c | 15 | ||||
| -rw-r--r-- | tools/perf/util/util.h | 4 |
15 files changed, 124 insertions, 84 deletions
diff --git a/tools/perf/Documentation/perf-list.txt b/tools/perf/Documentation/perf-list.txt index 7a527f7e9da9..ddc22525228d 100644 --- a/tools/perf/Documentation/perf-list.txt +++ b/tools/perf/Documentation/perf-list.txt | |||
| @@ -21,6 +21,8 @@ EVENT MODIFIERS | |||
| 21 | Events can optionally have a modifer by appending a colon and one or | 21 | Events can optionally have a modifer by appending a colon and one or |
| 22 | more modifiers. Modifiers allow the user to restrict when events are | 22 | more modifiers. Modifiers allow the user to restrict when events are |
| 23 | counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor. | 23 | counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor. |
| 24 | Additional modifiers are 'G' for guest counting (in KVM guests) and 'H' | ||
| 25 | for host counting (not in KVM guests). | ||
| 24 | 26 | ||
| 25 | The 'p' modifier can be used for specifying how precise the instruction | 27 | The 'p' modifier can be used for specifying how precise the instruction |
| 26 | address should be. The 'p' modifier is currently only implemented for | 28 | address should be. The 'p' modifier is currently only implemented for |
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST index c12659d8cb26..1078c5fadd5b 100644 --- a/tools/perf/MANIFEST +++ b/tools/perf/MANIFEST | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | tools/perf | 1 | tools/perf |
| 2 | include/linux/const.h | ||
| 2 | include/linux/perf_event.h | 3 | include/linux/perf_event.h |
| 3 | include/linux/rbtree.h | 4 | include/linux/rbtree.h |
| 4 | include/linux/list.h | 5 | include/linux/list.h |
diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c index 214ba7f9f577..806e0a286634 100644 --- a/tools/perf/builtin-annotate.c +++ b/tools/perf/builtin-annotate.c | |||
| @@ -235,7 +235,7 @@ out_delete: | |||
| 235 | } | 235 | } |
| 236 | 236 | ||
| 237 | static const char * const annotate_usage[] = { | 237 | static const char * const annotate_usage[] = { |
| 238 | "perf annotate [<options>] <command>", | 238 | "perf annotate [<options>]", |
| 239 | NULL | 239 | NULL |
| 240 | }; | 240 | }; |
| 241 | 241 | ||
| @@ -313,10 +313,5 @@ int cmd_annotate(int argc, const char **argv, const char *prefix __used) | |||
| 313 | annotate.sym_hist_filter = argv[0]; | 313 | annotate.sym_hist_filter = argv[0]; |
| 314 | } | 314 | } |
| 315 | 315 | ||
| 316 | if (field_sep && *field_sep == '.') { | ||
| 317 | pr_err("'.' is the only non valid --field-separator argument\n"); | ||
| 318 | return -1; | ||
| 319 | } | ||
| 320 | |||
| 321 | return __cmd_annotate(&annotate); | 316 | return __cmd_annotate(&annotate); |
| 322 | } | 317 | } |
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c index fe1ad8f21961..39104c0beea3 100644 --- a/tools/perf/builtin-kmem.c +++ b/tools/perf/builtin-kmem.c | |||
| @@ -108,7 +108,9 @@ static void setup_cpunode_map(void) | |||
| 108 | continue; | 108 | continue; |
| 109 | cpunode_map[cpu] = mem; | 109 | cpunode_map[cpu] = mem; |
| 110 | } | 110 | } |
| 111 | closedir(dir2); | ||
| 111 | } | 112 | } |
| 113 | closedir(dir1); | ||
| 112 | } | 114 | } |
| 113 | 115 | ||
| 114 | static void insert_alloc_stat(unsigned long call_site, unsigned long ptr, | 116 | static void insert_alloc_stat(unsigned long call_site, unsigned long ptr, |
| @@ -645,6 +647,7 @@ static int setup_sorting(struct list_head *sort_list, const char *arg) | |||
| 645 | break; | 647 | break; |
| 646 | if (sort_dimension__add(tok, sort_list) < 0) { | 648 | if (sort_dimension__add(tok, sort_list) < 0) { |
| 647 | error("Unknown --sort key: '%s'", tok); | 649 | error("Unknown --sort key: '%s'", tok); |
| 650 | free(str); | ||
| 648 | return -1; | 651 | return -1; |
| 649 | } | 652 | } |
| 650 | } | 653 | } |
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c index 032324a76b87..9fc6e0fa3dce 100644 --- a/tools/perf/builtin-kvm.c +++ b/tools/perf/builtin-kvm.c | |||
| @@ -22,9 +22,6 @@ | |||
| 22 | static const char *file_name; | 22 | static const char *file_name; |
| 23 | static char name_buffer[256]; | 23 | static char name_buffer[256]; |
| 24 | 24 | ||
| 25 | bool perf_host = 1; | ||
| 26 | bool perf_guest; | ||
| 27 | |||
| 28 | static const char * const kvm_usage[] = { | 25 | static const char * const kvm_usage[] = { |
| 29 | "perf kvm [<options>] {top|record|report|diff|buildid-list}", | 26 | "perf kvm [<options>] {top|record|report|diff|buildid-list}", |
| 30 | NULL | 27 | NULL |
| @@ -107,7 +104,8 @@ static int __cmd_buildid_list(int argc, const char **argv) | |||
| 107 | 104 | ||
| 108 | int cmd_kvm(int argc, const char **argv, const char *prefix __used) | 105 | int cmd_kvm(int argc, const char **argv, const char *prefix __used) |
| 109 | { | 106 | { |
| 110 | perf_host = perf_guest = 0; | 107 | perf_host = 0; |
| 108 | perf_guest = 1; | ||
| 111 | 109 | ||
| 112 | argc = parse_options(argc, argv, kvm_options, kvm_usage, | 110 | argc = parse_options(argc, argv, kvm_options, kvm_usage, |
| 113 | PARSE_OPT_STOP_AT_NON_OPTION); | 111 | PARSE_OPT_STOP_AT_NON_OPTION); |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index fd1909afcfd6..bb68ddf257b7 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
| @@ -1018,13 +1018,17 @@ static char *get_script_path(const char *script_root, const char *suffix) | |||
| 1018 | __script_root = get_script_root(&script_dirent, suffix); | 1018 | __script_root = get_script_root(&script_dirent, suffix); |
| 1019 | if (__script_root && !strcmp(script_root, __script_root)) { | 1019 | if (__script_root && !strcmp(script_root, __script_root)) { |
| 1020 | free(__script_root); | 1020 | free(__script_root); |
| 1021 | closedir(lang_dir); | ||
| 1022 | closedir(scripts_dir); | ||
| 1021 | snprintf(script_path, MAXPATHLEN, "%s/%s", | 1023 | snprintf(script_path, MAXPATHLEN, "%s/%s", |
| 1022 | lang_path, script_dirent.d_name); | 1024 | lang_path, script_dirent.d_name); |
| 1023 | return strdup(script_path); | 1025 | return strdup(script_path); |
| 1024 | } | 1026 | } |
| 1025 | free(__script_root); | 1027 | free(__script_root); |
| 1026 | } | 1028 | } |
| 1029 | closedir(lang_dir); | ||
| 1027 | } | 1030 | } |
| 1031 | closedir(scripts_dir); | ||
| 1028 | 1032 | ||
| 1029 | return NULL; | 1033 | return NULL; |
| 1030 | } | 1034 | } |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index 2b9a7f497a20..3854e869dce1 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
| @@ -1396,7 +1396,7 @@ int cmd_test(int argc, const char **argv, const char *prefix __used) | |||
| 1396 | NULL, | 1396 | NULL, |
| 1397 | }; | 1397 | }; |
| 1398 | const struct option test_options[] = { | 1398 | const struct option test_options[] = { |
| 1399 | OPT_INTEGER('v', "verbose", &verbose, | 1399 | OPT_INCR('v', "verbose", &verbose, |
| 1400 | "be more verbose (show symbol address, etc)"), | 1400 | "be more verbose (show symbol address, etc)"), |
| 1401 | OPT_END() | 1401 | OPT_END() |
| 1402 | }; | 1402 | }; |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 4f81eeb99875..8f80df896038 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
| @@ -235,7 +235,6 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel, | |||
| 235 | if (he == NULL) | 235 | if (he == NULL) |
| 236 | return NULL; | 236 | return NULL; |
| 237 | 237 | ||
| 238 | evsel->hists.stats.total_period += sample->period; | ||
| 239 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); | 238 | hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); |
| 240 | return he; | 239 | return he; |
| 241 | } | 240 | } |
| @@ -889,6 +888,10 @@ try_again: | |||
| 889 | ui__warning("The %s event is not supported.\n", | 888 | ui__warning("The %s event is not supported.\n", |
| 890 | event_name(counter)); | 889 | event_name(counter)); |
| 891 | goto out_err; | 890 | goto out_err; |
| 891 | } else if (err == EMFILE) { | ||
| 892 | ui__warning("Too many events are opened.\n" | ||
| 893 | "Try again after reducing the number of events\n"); | ||
| 894 | goto out_err; | ||
| 892 | } | 895 | } |
| 893 | 896 | ||
| 894 | ui__warning("The sys_perf_event_open() syscall " | 897 | ui__warning("The sys_perf_event_open() syscall " |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index fa1837088ca8..3f16e08a5c8d 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
| @@ -111,8 +111,11 @@ int perf_evlist__add_default(struct perf_evlist *evlist) | |||
| 111 | .type = PERF_TYPE_HARDWARE, | 111 | .type = PERF_TYPE_HARDWARE, |
| 112 | .config = PERF_COUNT_HW_CPU_CYCLES, | 112 | .config = PERF_COUNT_HW_CPU_CYCLES, |
| 113 | }; | 113 | }; |
| 114 | struct perf_evsel *evsel = perf_evsel__new(&attr, 0); | 114 | struct perf_evsel *evsel; |
| 115 | |||
| 116 | event_attr_init(&attr); | ||
| 115 | 117 | ||
| 118 | evsel = perf_evsel__new(&attr, 0); | ||
| 116 | if (evsel == NULL) | 119 | if (evsel == NULL) |
| 117 | goto error; | 120 | goto error; |
| 118 | 121 | ||
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c index abef2703cd24..6f505d1abac7 100644 --- a/tools/perf/util/hist.c +++ b/tools/perf/util/hist.c | |||
| @@ -76,21 +76,21 @@ static void hists__calc_col_len(struct hists *hists, struct hist_entry *h) | |||
| 76 | } | 76 | } |
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | static void hist_entry__add_cpumode_period(struct hist_entry *self, | 79 | static void hist_entry__add_cpumode_period(struct hist_entry *he, |
| 80 | unsigned int cpumode, u64 period) | 80 | unsigned int cpumode, u64 period) |
| 81 | { | 81 | { |
| 82 | switch (cpumode) { | 82 | switch (cpumode) { |
| 83 | case PERF_RECORD_MISC_KERNEL: | 83 | case PERF_RECORD_MISC_KERNEL: |
| 84 | self->period_sys += period; | 84 | he->period_sys += period; |
| 85 | break; | 85 | break; |
| 86 | case PERF_RECORD_MISC_USER: | 86 | case PERF_RECORD_MISC_USER: |
| 87 | self->period_us += period; | 87 | he->period_us += period; |
| 88 | break; | 88 | break; |
| 89 | case PERF_RECORD_MISC_GUEST_KERNEL: | 89 | case PERF_RECORD_MISC_GUEST_KERNEL: |
| 90 | self->period_guest_sys += period; | 90 | he->period_guest_sys += period; |
| 91 | break; | 91 | break; |
| 92 | case PERF_RECORD_MISC_GUEST_USER: | 92 | case PERF_RECORD_MISC_GUEST_USER: |
| 93 | self->period_guest_us += period; | 93 | he->period_guest_us += period; |
| 94 | break; | 94 | break; |
| 95 | default: | 95 | default: |
| 96 | break; | 96 | break; |
| @@ -165,18 +165,18 @@ void hists__decay_entries_threaded(struct hists *hists, | |||
| 165 | static struct hist_entry *hist_entry__new(struct hist_entry *template) | 165 | static struct hist_entry *hist_entry__new(struct hist_entry *template) |
| 166 | { | 166 | { |
| 167 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0; | 167 | size_t callchain_size = symbol_conf.use_callchain ? sizeof(struct callchain_root) : 0; |
| 168 | struct hist_entry *self = malloc(sizeof(*self) + callchain_size); | 168 | struct hist_entry *he = malloc(sizeof(*he) + callchain_size); |
| 169 | 169 | ||
| 170 | if (self != NULL) { | 170 | if (he != NULL) { |
| 171 | *self = *template; | 171 | *he = *template; |
| 172 | self->nr_events = 1; | 172 | he->nr_events = 1; |
| 173 | if (self->ms.map) | 173 | if (he->ms.map) |
| 174 | self->ms.map->referenced = true; | 174 | he->ms.map->referenced = true; |
| 175 | if (symbol_conf.use_callchain) | 175 | if (symbol_conf.use_callchain) |
| 176 | callchain_init(self->callchain); | 176 | callchain_init(he->callchain); |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | return self; | 179 | return he; |
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) | 182 | static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) |
| @@ -677,15 +677,16 @@ static size_t callchain__fprintf_flat(FILE *fp, struct callchain_node *self, | |||
| 677 | return ret; | 677 | return ret; |
| 678 | } | 678 | } |
| 679 | 679 | ||
| 680 | static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | 680 | static size_t hist_entry_callchain__fprintf(struct hist_entry *he, |
| 681 | u64 total_samples, int left_margin) | 681 | u64 total_samples, int left_margin, |
| 682 | FILE *fp) | ||
| 682 | { | 683 | { |
| 683 | struct rb_node *rb_node; | 684 | struct rb_node *rb_node; |
| 684 | struct callchain_node *chain; | 685 | struct callchain_node *chain; |
| 685 | size_t ret = 0; | 686 | size_t ret = 0; |
| 686 | u32 entries_printed = 0; | 687 | u32 entries_printed = 0; |
| 687 | 688 | ||
| 688 | rb_node = rb_first(&self->sorted_chain); | 689 | rb_node = rb_first(&he->sorted_chain); |
| 689 | while (rb_node) { | 690 | while (rb_node) { |
| 690 | double percent; | 691 | double percent; |
| 691 | 692 | ||
| @@ -730,35 +731,35 @@ void hists__output_recalc_col_len(struct hists *hists, int max_rows) | |||
| 730 | } | 731 | } |
| 731 | } | 732 | } |
| 732 | 733 | ||
| 733 | static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s, | 734 | static int hist_entry__pcnt_snprintf(struct hist_entry *he, char *s, |
| 734 | size_t size, struct hists *pair_hists, | 735 | size_t size, struct hists *pair_hists, |
| 735 | bool show_displacement, long displacement, | 736 | bool show_displacement, long displacement, |
| 736 | bool color, u64 session_total) | 737 | bool color, u64 total_period) |
| 737 | { | 738 | { |
| 738 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; | 739 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; |
| 739 | u64 nr_events; | 740 | u64 nr_events; |
| 740 | const char *sep = symbol_conf.field_sep; | 741 | const char *sep = symbol_conf.field_sep; |
| 741 | int ret; | 742 | int ret; |
| 742 | 743 | ||
| 743 | if (symbol_conf.exclude_other && !self->parent) | 744 | if (symbol_conf.exclude_other && !he->parent) |
| 744 | return 0; | 745 | return 0; |
| 745 | 746 | ||
| 746 | if (pair_hists) { | 747 | if (pair_hists) { |
| 747 | period = self->pair ? self->pair->period : 0; | 748 | period = he->pair ? he->pair->period : 0; |
| 748 | nr_events = self->pair ? self->pair->nr_events : 0; | 749 | nr_events = he->pair ? he->pair->nr_events : 0; |
| 749 | total = pair_hists->stats.total_period; | 750 | total = pair_hists->stats.total_period; |
| 750 | period_sys = self->pair ? self->pair->period_sys : 0; | 751 | period_sys = he->pair ? he->pair->period_sys : 0; |
| 751 | period_us = self->pair ? self->pair->period_us : 0; | 752 | period_us = he->pair ? he->pair->period_us : 0; |
| 752 | period_guest_sys = self->pair ? self->pair->period_guest_sys : 0; | 753 | period_guest_sys = he->pair ? he->pair->period_guest_sys : 0; |
| 753 | period_guest_us = self->pair ? self->pair->period_guest_us : 0; | 754 | period_guest_us = he->pair ? he->pair->period_guest_us : 0; |
| 754 | } else { | 755 | } else { |
| 755 | period = self->period; | 756 | period = he->period; |
| 756 | nr_events = self->nr_events; | 757 | nr_events = he->nr_events; |
| 757 | total = session_total; | 758 | total = total_period; |
| 758 | period_sys = self->period_sys; | 759 | period_sys = he->period_sys; |
| 759 | period_us = self->period_us; | 760 | period_us = he->period_us; |
| 760 | period_guest_sys = self->period_guest_sys; | 761 | period_guest_sys = he->period_guest_sys; |
| 761 | period_guest_us = self->period_guest_us; | 762 | period_guest_us = he->period_guest_us; |
| 762 | } | 763 | } |
| 763 | 764 | ||
| 764 | if (total) { | 765 | if (total) { |
| @@ -812,8 +813,8 @@ static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s, | |||
| 812 | 813 | ||
| 813 | if (total > 0) | 814 | if (total > 0) |
| 814 | old_percent = (period * 100.0) / total; | 815 | old_percent = (period * 100.0) / total; |
| 815 | if (session_total > 0) | 816 | if (total_period > 0) |
| 816 | new_percent = (self->period * 100.0) / session_total; | 817 | new_percent = (he->period * 100.0) / total_period; |
| 817 | 818 | ||
| 818 | diff = new_percent - old_percent; | 819 | diff = new_percent - old_percent; |
| 819 | 820 | ||
| @@ -862,9 +863,10 @@ int hist_entry__snprintf(struct hist_entry *he, char *s, size_t size, | |||
| 862 | return ret; | 863 | return ret; |
| 863 | } | 864 | } |
| 864 | 865 | ||
| 865 | int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, | 866 | static int hist_entry__fprintf(struct hist_entry *he, size_t size, |
| 866 | struct hists *pair_hists, bool show_displacement, | 867 | struct hists *hists, struct hists *pair_hists, |
| 867 | long displacement, FILE *fp, u64 session_total) | 868 | bool show_displacement, long displacement, |
| 869 | u64 total_period, FILE *fp) | ||
| 868 | { | 870 | { |
| 869 | char bf[512]; | 871 | char bf[512]; |
| 870 | int ret; | 872 | int ret; |
| @@ -874,14 +876,14 @@ int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, | |||
| 874 | 876 | ||
| 875 | ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists, | 877 | ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists, |
| 876 | show_displacement, displacement, | 878 | show_displacement, displacement, |
| 877 | true, session_total); | 879 | true, total_period); |
| 878 | hist_entry__snprintf(he, bf + ret, size - ret, hists); | 880 | hist_entry__snprintf(he, bf + ret, size - ret, hists); |
| 879 | return fprintf(fp, "%s\n", bf); | 881 | return fprintf(fp, "%s\n", bf); |
| 880 | } | 882 | } |
| 881 | 883 | ||
| 882 | static size_t hist_entry__fprintf_callchain(struct hist_entry *self, | 884 | static size_t hist_entry__fprintf_callchain(struct hist_entry *he, |
| 883 | struct hists *hists, FILE *fp, | 885 | struct hists *hists, |
| 884 | u64 session_total) | 886 | u64 total_period, FILE *fp) |
| 885 | { | 887 | { |
| 886 | int left_margin = 0; | 888 | int left_margin = 0; |
| 887 | 889 | ||
| @@ -889,11 +891,10 @@ static size_t hist_entry__fprintf_callchain(struct hist_entry *self, | |||
| 889 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, | 891 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, |
| 890 | typeof(*se), list); | 892 | typeof(*se), list); |
| 891 | left_margin = hists__col_len(hists, se->se_width_idx); | 893 | left_margin = hists__col_len(hists, se->se_width_idx); |
| 892 | left_margin -= thread__comm_len(self->thread); | 894 | left_margin -= thread__comm_len(he->thread); |
| 893 | } | 895 | } |
| 894 | 896 | ||
| 895 | return hist_entry_callchain__fprintf(fp, self, session_total, | 897 | return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); |
| 896 | left_margin); | ||
| 897 | } | 898 | } |
| 898 | 899 | ||
| 899 | size_t hists__fprintf(struct hists *hists, struct hists *pair, | 900 | size_t hists__fprintf(struct hists *hists, struct hists *pair, |
| @@ -903,6 +904,7 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 903 | struct sort_entry *se; | 904 | struct sort_entry *se; |
| 904 | struct rb_node *nd; | 905 | struct rb_node *nd; |
| 905 | size_t ret = 0; | 906 | size_t ret = 0; |
| 907 | u64 total_period; | ||
| 906 | unsigned long position = 1; | 908 | unsigned long position = 1; |
| 907 | long displacement = 0; | 909 | long displacement = 0; |
| 908 | unsigned int width; | 910 | unsigned int width; |
| @@ -917,20 +919,6 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 917 | 919 | ||
| 918 | fprintf(fp, "# %s", pair ? "Baseline" : "Overhead"); | 920 | fprintf(fp, "# %s", pair ? "Baseline" : "Overhead"); |
| 919 | 921 | ||
| 920 | if (symbol_conf.show_nr_samples) { | ||
| 921 | if (sep) | ||
| 922 | fprintf(fp, "%cSamples", *sep); | ||
| 923 | else | ||
| 924 | fputs(" Samples ", fp); | ||
| 925 | } | ||
| 926 | |||
| 927 | if (symbol_conf.show_total_period) { | ||
| 928 | if (sep) | ||
| 929 | ret += fprintf(fp, "%cPeriod", *sep); | ||
| 930 | else | ||
| 931 | ret += fprintf(fp, " Period "); | ||
| 932 | } | ||
| 933 | |||
| 934 | if (symbol_conf.show_cpu_utilization) { | 922 | if (symbol_conf.show_cpu_utilization) { |
| 935 | if (sep) { | 923 | if (sep) { |
| 936 | ret += fprintf(fp, "%csys", *sep); | 924 | ret += fprintf(fp, "%csys", *sep); |
| @@ -940,8 +928,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 940 | ret += fprintf(fp, "%cguest us", *sep); | 928 | ret += fprintf(fp, "%cguest us", *sep); |
| 941 | } | 929 | } |
| 942 | } else { | 930 | } else { |
| 943 | ret += fprintf(fp, " sys "); | 931 | ret += fprintf(fp, " sys "); |
| 944 | ret += fprintf(fp, " us "); | 932 | ret += fprintf(fp, " us "); |
| 945 | if (perf_guest) { | 933 | if (perf_guest) { |
| 946 | ret += fprintf(fp, " guest sys "); | 934 | ret += fprintf(fp, " guest sys "); |
| 947 | ret += fprintf(fp, " guest us "); | 935 | ret += fprintf(fp, " guest us "); |
| @@ -949,6 +937,20 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 949 | } | 937 | } |
| 950 | } | 938 | } |
| 951 | 939 | ||
| 940 | if (symbol_conf.show_nr_samples) { | ||
| 941 | if (sep) | ||
| 942 | fprintf(fp, "%cSamples", *sep); | ||
| 943 | else | ||
| 944 | fputs(" Samples ", fp); | ||
| 945 | } | ||
| 946 | |||
| 947 | if (symbol_conf.show_total_period) { | ||
| 948 | if (sep) | ||
| 949 | ret += fprintf(fp, "%cPeriod", *sep); | ||
| 950 | else | ||
| 951 | ret += fprintf(fp, " Period "); | ||
| 952 | } | ||
| 953 | |||
| 952 | if (pair) { | 954 | if (pair) { |
| 953 | if (sep) | 955 | if (sep) |
| 954 | ret += fprintf(fp, "%cDelta", *sep); | 956 | ret += fprintf(fp, "%cDelta", *sep); |
| @@ -993,6 +995,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 993 | goto print_entries; | 995 | goto print_entries; |
| 994 | 996 | ||
| 995 | fprintf(fp, "# ........"); | 997 | fprintf(fp, "# ........"); |
| 998 | if (symbol_conf.show_cpu_utilization) | ||
| 999 | fprintf(fp, " ....... ......."); | ||
| 996 | if (symbol_conf.show_nr_samples) | 1000 | if (symbol_conf.show_nr_samples) |
| 997 | fprintf(fp, " .........."); | 1001 | fprintf(fp, " .........."); |
| 998 | if (symbol_conf.show_total_period) | 1002 | if (symbol_conf.show_total_period) |
| @@ -1025,6 +1029,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair, | |||
| 1025 | goto out; | 1029 | goto out; |
| 1026 | 1030 | ||
| 1027 | print_entries: | 1031 | print_entries: |
| 1032 | total_period = hists->stats.total_period; | ||
| 1033 | |||
| 1028 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { | 1034 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { |
| 1029 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); | 1035 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
| 1030 | 1036 | ||
| @@ -1040,11 +1046,10 @@ print_entries: | |||
| 1040 | ++position; | 1046 | ++position; |
| 1041 | } | 1047 | } |
| 1042 | ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, | 1048 | ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, |
| 1043 | displacement, fp, hists->stats.total_period); | 1049 | displacement, total_period, fp); |
| 1044 | 1050 | ||
| 1045 | if (symbol_conf.use_callchain) | 1051 | if (symbol_conf.use_callchain) |
| 1046 | ret += hist_entry__fprintf_callchain(h, hists, fp, | 1052 | ret += hist_entry__fprintf_callchain(h, hists, total_period, fp); |
| 1047 | hists->stats.total_period); | ||
| 1048 | if (max_rows && ++nr_rows >= max_rows) | 1053 | if (max_rows && ++nr_rows >= max_rows) |
| 1049 | goto out; | 1054 | goto out; |
| 1050 | 1055 | ||
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h index ff6f9d56ea41..f55f0a8d1f81 100644 --- a/tools/perf/util/hist.h +++ b/tools/perf/util/hist.h | |||
| @@ -66,11 +66,8 @@ struct hists { | |||
| 66 | struct hist_entry *__hists__add_entry(struct hists *self, | 66 | struct hist_entry *__hists__add_entry(struct hists *self, |
| 67 | struct addr_location *al, | 67 | struct addr_location *al, |
| 68 | struct symbol *parent, u64 period); | 68 | struct symbol *parent, u64 period); |
| 69 | extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | 69 | int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); |
| 70 | extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | 70 | int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); |
| 71 | int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, | ||
| 72 | struct hists *pair_hists, bool show_displacement, | ||
| 73 | long displacement, FILE *fp, u64 session_total); | ||
| 74 | int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, | 71 | int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, |
| 75 | struct hists *hists); | 72 | struct hists *hists); |
| 76 | void hist_entry__free(struct hist_entry *); | 73 | void hist_entry__free(struct hist_entry *); |
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c index 531c283fc0c5..b029296d20d9 100644 --- a/tools/perf/util/parse-events.c +++ b/tools/perf/util/parse-events.c | |||
| @@ -735,8 +735,8 @@ static int | |||
| 735 | parse_event_modifier(const char **strp, struct perf_event_attr *attr) | 735 | parse_event_modifier(const char **strp, struct perf_event_attr *attr) |
| 736 | { | 736 | { |
| 737 | const char *str = *strp; | 737 | const char *str = *strp; |
| 738 | int exclude = 0; | 738 | int exclude = 0, exclude_GH = 0; |
| 739 | int eu = 0, ek = 0, eh = 0, precise = 0; | 739 | int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; |
| 740 | 740 | ||
| 741 | if (!*str) | 741 | if (!*str) |
| 742 | return 0; | 742 | return 0; |
| @@ -760,6 +760,14 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) | |||
| 760 | if (!exclude) | 760 | if (!exclude) |
| 761 | exclude = eu = ek = eh = 1; | 761 | exclude = eu = ek = eh = 1; |
| 762 | eh = 0; | 762 | eh = 0; |
| 763 | } else if (*str == 'G') { | ||
| 764 | if (!exclude_GH) | ||
| 765 | exclude_GH = eG = eH = 1; | ||
| 766 | eG = 0; | ||
| 767 | } else if (*str == 'H') { | ||
| 768 | if (!exclude_GH) | ||
| 769 | exclude_GH = eG = eH = 1; | ||
| 770 | eH = 0; | ||
| 763 | } else if (*str == 'p') { | 771 | } else if (*str == 'p') { |
| 764 | precise++; | 772 | precise++; |
| 765 | } else | 773 | } else |
| @@ -776,6 +784,8 @@ parse_event_modifier(const char **strp, struct perf_event_attr *attr) | |||
| 776 | attr->exclude_kernel = ek; | 784 | attr->exclude_kernel = ek; |
| 777 | attr->exclude_hv = eh; | 785 | attr->exclude_hv = eh; |
| 778 | attr->precise_ip = precise; | 786 | attr->precise_ip = precise; |
| 787 | attr->exclude_host = eH; | ||
| 788 | attr->exclude_guest = eG; | ||
| 779 | 789 | ||
| 780 | return 0; | 790 | return 0; |
| 781 | } | 791 | } |
| @@ -838,6 +848,7 @@ int parse_events(struct perf_evlist *evlist , const char *str, int unset __used) | |||
| 838 | for (;;) { | 848 | for (;;) { |
| 839 | ostr = str; | 849 | ostr = str; |
| 840 | memset(&attr, 0, sizeof(attr)); | 850 | memset(&attr, 0, sizeof(attr)); |
| 851 | event_attr_init(&attr); | ||
| 841 | ret = parse_event_symbols(evlist, &str, &attr); | 852 | ret = parse_event_symbols(evlist, &str, &attr); |
| 842 | if (ret == EVT_FAILED) | 853 | if (ret == EVT_FAILED) |
| 843 | return -1; | 854 | return -1; |
diff --git a/tools/perf/util/trace-event-info.c b/tools/perf/util/trace-event-info.c index ac6830d8292b..fc22cf5c605f 100644 --- a/tools/perf/util/trace-event-info.c +++ b/tools/perf/util/trace-event-info.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | * | 18 | * |
| 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 19 | * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 20 | */ | 20 | */ |
| 21 | #include <ctype.h> | ||
| 22 | #include "util.h" | 21 | #include "util.h" |
| 23 | #include <dirent.h> | 22 | #include <dirent.h> |
| 24 | #include <mntent.h> | 23 | #include <mntent.h> |
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 5b3ea49aa63e..813141047fc2 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
| @@ -1,6 +1,21 @@ | |||
| 1 | #include "../perf.h" | ||
| 1 | #include "util.h" | 2 | #include "util.h" |
| 2 | #include <sys/mman.h> | 3 | #include <sys/mman.h> |
| 3 | 4 | ||
| 5 | /* | ||
| 6 | * XXX We need to find a better place for these things... | ||
| 7 | */ | ||
| 8 | bool perf_host = true; | ||
| 9 | bool perf_guest = true; | ||
| 10 | |||
| 11 | void event_attr_init(struct perf_event_attr *attr) | ||
| 12 | { | ||
| 13 | if (!perf_host) | ||
| 14 | attr->exclude_host = 1; | ||
| 15 | if (!perf_guest) | ||
| 16 | attr->exclude_guest = 1; | ||
| 17 | } | ||
| 18 | |||
| 4 | int mkdir_p(char *path, mode_t mode) | 19 | int mkdir_p(char *path, mode_t mode) |
| 5 | { | 20 | { |
| 6 | struct stat st; | 21 | struct stat st; |
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h index 37be34dff798..b9c530cce79a 100644 --- a/tools/perf/util/util.h +++ b/tools/perf/util/util.h | |||
| @@ -242,6 +242,10 @@ int strtailcmp(const char *s1, const char *s2); | |||
| 242 | unsigned long convert_unit(unsigned long value, char *unit); | 242 | unsigned long convert_unit(unsigned long value, char *unit); |
| 243 | int readn(int fd, void *buf, size_t size); | 243 | int readn(int fd, void *buf, size_t size); |
| 244 | 244 | ||
| 245 | struct perf_event_attr; | ||
| 246 | |||
| 247 | void event_attr_init(struct perf_event_attr *attr); | ||
| 248 | |||
| 245 | #define _STR(x) #x | 249 | #define _STR(x) #x |
| 246 | #define STR(x) _STR(x) | 250 | #define STR(x) _STR(x) |
| 247 | 251 | ||
