Commit b9f616bbf4a917398aa09db89efbdf9a204e80dc

Authored by Ingo Molnar

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
1 1 tools/perf
  2 +include/linux/const.h
2 3 include/linux/perf_event.h
3 4 include/linux/rbtree.h
4 5 include/linux/list.h
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
... ... @@ -235,7 +235,6 @@
235 235 if (he == NULL)
236 236 return NULL;
237 237  
238   - evsel->hists.stats.total_period += sample->period;
239 238 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
240 239 return he;
241 240 }
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