aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2012-01-08 06:36:18 -0500
committerIngo Molnar <mingo@elte.hu>2012-01-08 06:36:18 -0500
commitb9f616bbf4a917398aa09db89efbdf9a204e80dc (patch)
tree63bc9febd7a45c6f8ad5bfb17723a03c9071fea9 /tools/perf
parent636f0c70f2557e0819b50c74e31b4a027327015e (diff)
parentcc5a91e972212aea022ff86b2c11d3e84d552bf5 (diff)
Merge branch 'perf/core' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/Documentation/perf-list.txt2
-rw-r--r--tools/perf/MANIFEST1
-rw-r--r--tools/perf/builtin-kvm.c6
-rw-r--r--tools/perf/builtin-top.c1
-rw-r--r--tools/perf/util/evlist.c5
-rw-r--r--tools/perf/util/hist.c97
-rw-r--r--tools/perf/util/hist.h7
-rw-r--r--tools/perf/util/parse-events.c15
-rw-r--r--tools/perf/util/util.c15
-rw-r--r--tools/perf/util/util.h4
10 files changed, 93 insertions, 60 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
21Events can optionally have a modifer by appending a colon and one or 21Events can optionally have a modifer by appending a colon and one or
22more modifiers. Modifiers allow the user to restrict when events are 22more modifiers. Modifiers allow the user to restrict when events are
23counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor. 23counted with 'u' for user-space, 'k' for kernel, 'h' for hypervisor.
24Additional modifiers are 'G' for guest counting (in KVM guests) and 'H'
25for host counting (not in KVM guests).
24 26
25The 'p' modifier can be used for specifying how precise the instruction 27The 'p' modifier can be used for specifying how precise the instruction
26address should be. The 'p' modifier is currently only implemented for 28address 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 @@
1tools/perf 1tools/perf
2include/linux/const.h
2include/linux/perf_event.h 3include/linux/perf_event.h
3include/linux/rbtree.h 4include/linux/rbtree.h
4include/linux/list.h 5include/linux/list.h
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 @@
22static const char *file_name; 22static const char *file_name;
23static char name_buffer[256]; 23static char name_buffer[256];
24 24
25bool perf_host = 1;
26bool perf_guest;
27
28static const char * const kvm_usage[] = { 25static 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
108int cmd_kvm(int argc, const char **argv, const char *prefix __used) 105int 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-top.c b/tools/perf/builtin-top.c
index 4f81eeb99875..d89dec90103e 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}
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..4df449549b0c 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
79static void hist_entry__add_cpumode_period(struct hist_entry *self, 79static 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,
165static struct hist_entry *hist_entry__new(struct hist_entry *template) 165static 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
182static void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h) 182static 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
680static size_t hist_entry_callchain__fprintf(FILE *fp, struct hist_entry *self, 680static 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
733static int hist_entry__pcnt_snprintf(struct hist_entry *self, char *s, 734static 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
865int hist_entry__fprintf(struct hist_entry *he, size_t size, struct hists *hists, 866static 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
882static size_t hist_entry__fprintf_callchain(struct hist_entry *self, 884static 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
899size_t hists__fprintf(struct hists *hists, struct hists *pair, 900size_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;
@@ -1025,6 +1027,8 @@ size_t hists__fprintf(struct hists *hists, struct hists *pair,
1025 goto out; 1027 goto out;
1026 1028
1027print_entries: 1029print_entries:
1030 total_period = hists->stats.total_period;
1031
1028 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { 1032 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
1029 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1033 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
1030 1034
@@ -1040,11 +1044,10 @@ print_entries:
1040 ++position; 1044 ++position;
1041 } 1045 }
1042 ret += hist_entry__fprintf(h, max_cols, hists, pair, show_displacement, 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 if (symbol_conf.use_callchain) 1049 if (symbol_conf.use_callchain)
1046 ret += hist_entry__fprintf_callchain(h, hists, fp, 1050 ret += hist_entry__fprintf_callchain(h, hists, total_period, fp);
1047 hists->stats.total_period);
1048 if (max_rows && ++nr_rows >= max_rows) 1051 if (max_rows && ++nr_rows >= max_rows)
1049 goto out; 1052 goto out;
1050 1053
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 {
66struct hist_entry *__hists__add_entry(struct hists *self, 66struct 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);
69extern int64_t hist_entry__cmp(struct hist_entry *, struct hist_entry *); 69int64_t hist_entry__cmp(struct hist_entry *left, struct hist_entry *right);
70extern int64_t hist_entry__collapse(struct hist_entry *, struct hist_entry *); 70int64_t hist_entry__collapse(struct hist_entry *left, struct hist_entry *right);
71int 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);
74int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size, 71int hist_entry__snprintf(struct hist_entry *self, char *bf, size_t size,
75 struct hists *hists); 72 struct hists *hists);
76void hist_entry__free(struct hist_entry *); 73void 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
735parse_event_modifier(const char **strp, struct perf_event_attr *attr) 735parse_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/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 */
8bool perf_host = true;
9bool perf_guest = true;
10
11void 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
4int mkdir_p(char *path, mode_t mode) 19int 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);
242unsigned long convert_unit(unsigned long value, char *unit); 242unsigned long convert_unit(unsigned long value, char *unit);
243int readn(int fd, void *buf, size_t size); 243int readn(int fd, void *buf, size_t size);
244 244
245struct perf_event_attr;
246
247void 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