Commit b9f616bbf4a917398aa09db89efbdf9a204e80dc
Exists in
master
and in
6 other branches
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Showing 10 changed files Side-by-side Diff
tools/perf/Documentation/perf-list.txt
... | ... | @@ -21,6 +21,8 @@ |
21 | 21 | Events can optionally have a modifer by appending a colon and one or |
22 | 22 | more modifiers. Modifiers allow the user to restrict when events are |
23 | 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 | 27 | The 'p' modifier can be used for specifying how precise the instruction |
26 | 28 | address should be. The 'p' modifier is currently only implemented for |
tools/perf/MANIFEST
tools/perf/builtin-kvm.c
... | ... | @@ -22,9 +22,6 @@ |
22 | 22 | static const char *file_name; |
23 | 23 | static char name_buffer[256]; |
24 | 24 | |
25 | -bool perf_host = 1; | |
26 | -bool perf_guest; | |
27 | - | |
28 | 25 | static const char * const kvm_usage[] = { |
29 | 26 | "perf kvm [<options>] {top|record|report|diff|buildid-list}", |
30 | 27 | NULL |
... | ... | @@ -107,7 +104,8 @@ |
107 | 104 | |
108 | 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 | 110 | argc = parse_options(argc, argv, kvm_options, kvm_usage, |
113 | 111 | PARSE_OPT_STOP_AT_NON_OPTION); |
tools/perf/builtin-top.c
tools/perf/util/evlist.c
... | ... | @@ -111,8 +111,11 @@ |
111 | 111 | .type = PERF_TYPE_HARDWARE, |
112 | 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 | 115 | |
116 | + event_attr_init(&attr); | |
117 | + | |
118 | + evsel = perf_evsel__new(&attr, 0); | |
116 | 119 | if (evsel == NULL) |
117 | 120 | goto error; |
118 | 121 |
tools/perf/util/hist.c
... | ... | @@ -76,21 +76,21 @@ |
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 | 80 | unsigned int cpumode, u64 period) |
81 | 81 | { |
82 | 82 | switch (cpumode) { |
83 | 83 | case PERF_RECORD_MISC_KERNEL: |
84 | - self->period_sys += period; | |
84 | + he->period_sys += period; | |
85 | 85 | break; |
86 | 86 | case PERF_RECORD_MISC_USER: |
87 | - self->period_us += period; | |
87 | + he->period_us += period; | |
88 | 88 | break; |
89 | 89 | case PERF_RECORD_MISC_GUEST_KERNEL: |
90 | - self->period_guest_sys += period; | |
90 | + he->period_guest_sys += period; | |
91 | 91 | break; |
92 | 92 | case PERF_RECORD_MISC_GUEST_USER: |
93 | - self->period_guest_us += period; | |
93 | + he->period_guest_us += period; | |
94 | 94 | break; |
95 | 95 | default: |
96 | 96 | break; |
97 | 97 | |
98 | 98 | |
99 | 99 | |
... | ... | @@ -165,18 +165,18 @@ |
165 | 165 | static struct hist_entry *hist_entry__new(struct hist_entry *template) |
166 | 166 | { |
167 | 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) { | |
171 | - *self = *template; | |
172 | - self->nr_events = 1; | |
173 | - if (self->ms.map) | |
174 | - self->ms.map->referenced = true; | |
170 | + if (he != NULL) { | |
171 | + *he = *template; | |
172 | + he->nr_events = 1; | |
173 | + if (he->ms.map) | |
174 | + he->ms.map->referenced = true; | |
175 | 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 | 182 | static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) |
183 | 183 | |
... | ... | @@ -677,15 +677,16 @@ |
677 | 677 | return ret; |
678 | 678 | } |
679 | 679 | |
680 | -static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, | |
681 | - u64 total_samples, int left_margin) | |
680 | +static size_t hist_entry_callchain__fprintf(struct hist_entry *he, | |
681 | + u64 total_samples, int left_margin, | |
682 | + FILE *fp) | |
682 | 683 | { |
683 | 684 | struct rb_node *rb_node; |
684 | 685 | struct callchain_node *chain; |
685 | 686 | size_t ret = 0; |
686 | 687 | u32 entries_printed = 0; |
687 | 688 | |
688 | - rb_node = rb_first(&self->sorted_chain); | |
689 | + rb_node = rb_first(&he->sorted_chain); | |
689 | 690 | while (rb_node) { |
690 | 691 | double percent; |
691 | 692 | |
692 | 693 | |
693 | 694 | |
694 | 695 | |
695 | 696 | |
696 | 697 | |
... | ... | @@ -730,35 +731,35 @@ |
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 | 735 | size_t size, struct hists *pair_hists, |
735 | 736 | bool show_displacement, long displacement, |
736 | - bool color, u64 session_total) | |
737 | + bool color, u64 total_period) | |
737 | 738 | { |
738 | 739 | u64 period, total, period_sys, period_us, period_guest_sys, period_guest_us; |
739 | 740 | u64 nr_events; |
740 | 741 | const char *sep = symbol_conf.field_sep; |
741 | 742 | int ret; |
742 | 743 | |
743 | - if (symbol_conf.exclude_other && !self->parent) | |
744 | + if (symbol_conf.exclude_other && !he->parent) | |
744 | 745 | return 0; |
745 | 746 | |
746 | 747 | if (pair_hists) { |
747 | - period = self->pair ? self->pair->period : 0; | |
748 | - nr_events = self->pair ? self->pair->nr_events : 0; | |
748 | + period = he->pair ? he->pair->period : 0; | |
749 | + nr_events = he->pair ? he->pair->nr_events : 0; | |
749 | 750 | total = pair_hists->stats.total_period; |
750 | - period_sys = self->pair ? self->pair->period_sys : 0; | |
751 | - period_us = self->pair ? self->pair->period_us : 0; | |
752 | - period_guest_sys = self->pair ? self->pair->period_guest_sys : 0; | |
753 | - period_guest_us = self->pair ? self->pair->period_guest_us : 0; | |
751 | + period_sys = he->pair ? he->pair->period_sys : 0; | |
752 | + period_us = he->pair ? he->pair->period_us : 0; | |
753 | + period_guest_sys = he->pair ? he->pair->period_guest_sys : 0; | |
754 | + period_guest_us = he->pair ? he->pair->period_guest_us : 0; | |
754 | 755 | } else { |
755 | - period = self->period; | |
756 | - nr_events = self->nr_events; | |
757 | - total = session_total; | |
758 | - period_sys = self->period_sys; | |
759 | - period_us = self->period_us; | |
760 | - period_guest_sys = self->period_guest_sys; | |
761 | - period_guest_us = self->period_guest_us; | |
756 | + period = he->period; | |
757 | + nr_events = he->nr_events; | |
758 | + total = total_period; | |
759 | + period_sys = he->period_sys; | |
760 | + period_us = he->period_us; | |
761 | + period_guest_sys = he->period_guest_sys; | |
762 | + period_guest_us = he->period_guest_us; | |
762 | 763 | } |
763 | 764 | |
764 | 765 | if (total) { |
... | ... | @@ -812,8 +813,8 @@ |
812 | 813 | |
813 | 814 | if (total > 0) |
814 | 815 | old_percent = (period * 100.0) / total; |
815 | - if (session_total > 0) | |
816 | - new_percent = (self->period * 100.0) / session_total; | |
816 | + if (total_period > 0) | |
817 | + new_percent = (he->period * 100.0) / total_period; | |
817 | 818 | |
818 | 819 | diff = new_percent - old_percent; |
819 | 820 | |
... | ... | @@ -862,9 +863,10 @@ |
862 | 863 | return ret; |
863 | 864 | } |
864 | 865 | |
865 | -int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, | |
866 | - struct hists *pair_hists, bool show_displacement, | |
867 | - long displacement, FILE *fp, u64 session_total) | |
866 | +static int hist_entry__fprintf(struct hist_entry *he, size_t size, | |
867 | + struct hists *hists, struct hists *pair_hists, | |
868 | + bool show_displacement, long displacement, | |
869 | + u64 total_period, FILE *fp) | |
868 | 870 | { |
869 | 871 | char bf[512]; |
870 | 872 | int ret; |
871 | 873 | |
... | ... | @@ -874,14 +876,14 @@ |
874 | 876 | |
875 | 877 | ret = hist_entry__pcnt_snprintf(he, bf, size, pair_hists, |
876 | 878 | show_displacement, displacement, |
877 | - true, session_total); | |
879 | + true, total_period); | |
878 | 880 | hist_entry__snprintf(he, bf + ret, size - ret, hists); |
879 | 881 | return fprintf(fp, "%s\n", bf); |
880 | 882 | } |
881 | 883 | |
882 | -static size_t hist_entry__fprintf_callchain(struct hist_entry *self, | |
883 | - struct hists *hists, FILE *fp, | |
884 | - u64 session_total) | |
884 | +static size_t hist_entry__fprintf_callchain(struct hist_entry *he, | |
885 | + struct hists *hists, | |
886 | + u64 total_period, FILE *fp) | |
885 | 887 | { |
886 | 888 | int left_margin = 0; |
887 | 889 | |
888 | 890 | |
... | ... | @@ -889,11 +891,10 @@ |
889 | 891 | struct sort_entry *se = list_first_entry(&hist_entry__sort_list, |
890 | 892 | typeof(*se), list); |
891 | 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, | |
896 | - left_margin); | |
897 | + return hist_entry_callchain__fprintf(he, total_period, left_margin, fp); | |
897 | 898 | } |
898 | 899 | |
899 | 900 | size_t hists__fprintf(struct hists *hists, struct hists *pair, |
... | ... | @@ -903,6 +904,7 @@ |
903 | 904 | struct sort_entry *se; |
904 | 905 | struct rb_node *nd; |
905 | 906 | size_t ret = 0; |
907 | + u64 total_period; | |
906 | 908 | unsigned long position = 1; |
907 | 909 | long displacement = 0; |
908 | 910 | unsigned int width; |
... | ... | @@ -1025,6 +1027,8 @@ |
1025 | 1027 | goto out; |
1026 | 1028 | |
1027 | 1029 | print_entries: |
1030 | + total_period = hists->stats.total_period; | |
1031 | + | |
1028 | 1032 | for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { |
1029 | 1033 | struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); |
1030 | 1034 | |
1031 | 1035 | |
... | ... | @@ -1040,11 +1044,10 @@ |
1040 | 1044 | ++position; |
1041 | 1045 | } |
1042 | 1046 | ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, |
1043 | - displacement, fp, hists->stats.total_period); | |
1047 | + displacement, total_period, fp); | |
1044 | 1048 | |
1045 | 1049 | if (symbol_conf.use_callchain) |
1046 | - ret += hist_entry__fprintf_callchain(h, hists, fp, | |
1047 | - hists->stats.total_period); | |
1050 | + ret += hist_entry__fprintf_callchain(h, hists, total_period, fp); | |
1048 | 1051 | if (max_rows && ++nr_rows >= max_rows) |
1049 | 1052 | goto out; |
1050 | 1053 |
tools/perf/util/hist.h
... | ... | @@ -66,11 +66,8 @@ |
66 | 66 | struct hist_entry *__hists__add_entry(struct hists *self, |
67 | 67 | struct addr_location *al, |
68 | 68 | struct symbol *parent, u64 period); |
69 | -extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); | |
70 | -extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); | |
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); | |
69 | +int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right); | |
70 | +int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right); | |
74 | 71 | int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, |
75 | 72 | struct hists *hists); |
76 | 73 | void hist_entry__free(struct hist_entry *); |
tools/perf/util/parse-events.c
... | ... | @@ -735,8 +735,8 @@ |
735 | 735 | parse_event_modifier(const char **strp, struct perf_event_attr *attr) |
736 | 736 | { |
737 | 737 | const char *str = *strp; |
738 | - int exclude = 0; | |
739 | - int eu = 0, ek = 0, eh = 0, precise = 0; | |
738 | + int exclude = 0, exclude_GH = 0; | |
739 | + int eu = 0, ek = 0, eh = 0, eH = 0, eG = 0, precise = 0; | |
740 | 740 | |
741 | 741 | if (!*str) |
742 | 742 | return 0; |
... | ... | @@ -760,6 +760,14 @@ |
760 | 760 | if (!exclude) |
761 | 761 | exclude = eu = ek = eh = 1; |
762 | 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 | 771 | } else if (*str == 'p') { |
764 | 772 | precise++; |
765 | 773 | } else |
... | ... | @@ -776,6 +784,8 @@ |
776 | 784 | attr->exclude_kernel = ek; |
777 | 785 | attr->exclude_hv = eh; |
778 | 786 | attr->precise_ip = precise; |
787 | + attr->exclude_host = eH; | |
788 | + attr->exclude_guest = eG; | |
779 | 789 | |
780 | 790 | return 0; |
781 | 791 | } |
... | ... | @@ -838,6 +848,7 @@ |
838 | 848 | for (;;) { |
839 | 849 | ostr = str; |
840 | 850 | memset(&attr, 0, sizeof(attr)); |
851 | + event_attr_init(&attr); | |
841 | 852 | ret = parse_event_symbols(evlist, &str, &attr); |
842 | 853 | if (ret == EVT_FAILED) |
843 | 854 | return -1; |
tools/perf/util/util.c
1 | +#include "../perf.h" | |
1 | 2 | #include "util.h" |
2 | 3 | #include <sys/mman.h> |
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 | +} | |
3 | 18 | |
4 | 19 | int mkdir_p(char *path, mode_t mode) |
5 | 20 | { |
tools/perf/util/util.h
... | ... | @@ -242,6 +242,10 @@ |
242 | 242 | unsigned long convert_unit(unsigned long value, char *unit); |
243 | 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 | 249 | #define _STR(x) #x |
246 | 250 | #define STR(x) _STR(x) |
247 | 251 |