aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2012-10-01 14:20:58 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2012-10-02 17:36:29 -0400
commitb070a547fda009bdb840b90aab7274be9e41de4d (patch)
tree94b17eecf13a9e46758b1de3a103b9640f1ab8df /tools/perf
parent73ee3b276864af1ca042258e67237e8454d7b7b6 (diff)
perf stat: Don't use globals where not needed to
Some variables were global but used in just one function, so move it to where it belongs. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Namhyung Kim <namhyung@gmail.com> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-spa8e7nnohtn1z32q2l2ae2c@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/builtin-stat.c328
1 files changed, 159 insertions, 169 deletions
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index e8cd4d81b06e..93b9011fa3e2 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -64,122 +64,12 @@
64#define CNTR_NOT_SUPPORTED "<not supported>" 64#define CNTR_NOT_SUPPORTED "<not supported>"
65#define CNTR_NOT_COUNTED "<not counted>" 65#define CNTR_NOT_COUNTED "<not counted>"
66 66
67static struct perf_event_attr default_attrs[] = {
68
69 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
70 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
71 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
72 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
73
74 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
75 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
76 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
77 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
78 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
79 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
80
81};
82
83/*
84 * Detailed stats (-d), covering the L1 and last level data caches:
85 */
86static struct perf_event_attr detailed_attrs[] = {
87
88 { .type = PERF_TYPE_HW_CACHE,
89 .config =
90 PERF_COUNT_HW_CACHE_L1D << 0 |
91 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
92 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
93
94 { .type = PERF_TYPE_HW_CACHE,
95 .config =
96 PERF_COUNT_HW_CACHE_L1D << 0 |
97 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
98 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
99
100 { .type = PERF_TYPE_HW_CACHE,
101 .config =
102 PERF_COUNT_HW_CACHE_LL << 0 |
103 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
104 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
105
106 { .type = PERF_TYPE_HW_CACHE,
107 .config =
108 PERF_COUNT_HW_CACHE_LL << 0 |
109 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
110 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
111};
112
113/*
114 * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
115 */
116static struct perf_event_attr very_detailed_attrs[] = {
117
118 { .type = PERF_TYPE_HW_CACHE,
119 .config =
120 PERF_COUNT_HW_CACHE_L1I << 0 |
121 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
122 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
123
124 { .type = PERF_TYPE_HW_CACHE,
125 .config =
126 PERF_COUNT_HW_CACHE_L1I << 0 |
127 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
128 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
129
130 { .type = PERF_TYPE_HW_CACHE,
131 .config =
132 PERF_COUNT_HW_CACHE_DTLB << 0 |
133 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
134 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
135
136 { .type = PERF_TYPE_HW_CACHE,
137 .config =
138 PERF_COUNT_HW_CACHE_DTLB << 0 |
139 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
140 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
141
142 { .type = PERF_TYPE_HW_CACHE,
143 .config =
144 PERF_COUNT_HW_CACHE_ITLB << 0 |
145 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
146 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
147
148 { .type = PERF_TYPE_HW_CACHE,
149 .config =
150 PERF_COUNT_HW_CACHE_ITLB << 0 |
151 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
152 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
153
154};
155
156/*
157 * Very, very detailed stats (-d -d -d), adding prefetch events:
158 */
159static struct perf_event_attr very_very_detailed_attrs[] = {
160
161 { .type = PERF_TYPE_HW_CACHE,
162 .config =
163 PERF_COUNT_HW_CACHE_L1D << 0 |
164 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
165 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
166
167 { .type = PERF_TYPE_HW_CACHE,
168 .config =
169 PERF_COUNT_HW_CACHE_L1D << 0 |
170 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
171 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
172};
173
174
175
176static struct perf_evlist *evsel_list; 67static struct perf_evlist *evsel_list;
177 68
178static struct perf_target target = { 69static struct perf_target target = {
179 .uid = UINT_MAX, 70 .uid = UINT_MAX,
180}; 71};
181 72
182static int run_idx = 0;
183static int run_count = 1; 73static int run_count = 1;
184static bool no_inherit = false; 74static bool no_inherit = false;
185static bool scale = true; 75static bool scale = true;
@@ -187,15 +77,12 @@ static bool no_aggr = false;
187static pid_t child_pid = -1; 77static pid_t child_pid = -1;
188static bool null_run = false; 78static bool null_run = false;
189static int detailed_run = 0; 79static int detailed_run = 0;
190static bool sync_run = false;
191static bool big_num = true; 80static bool big_num = true;
192static int big_num_opt = -1; 81static int big_num_opt = -1;
193static const char *csv_sep = NULL; 82static const char *csv_sep = NULL;
194static bool csv_output = false; 83static bool csv_output = false;
195static bool group = false; 84static bool group = false;
196static const char *output_name = NULL;
197static FILE *output = NULL; 85static FILE *output = NULL;
198static int output_fd;
199 86
200static volatile int done = 0; 87static volatile int done = 0;
201 88
@@ -1028,11 +915,6 @@ static void sig_atexit(void)
1028 kill(getpid(), signr); 915 kill(getpid(), signr);
1029} 916}
1030 917
1031static const char * const stat_usage[] = {
1032 "perf stat [<options>] [<command>]",
1033 NULL
1034};
1035
1036static int stat__set_big_num(const struct option *opt __maybe_unused, 918static int stat__set_big_num(const struct option *opt __maybe_unused,
1037 const char *s __maybe_unused, int unset) 919 const char *s __maybe_unused, int unset)
1038{ 920{
@@ -1040,62 +922,119 @@ static int stat__set_big_num(const struct option *opt __maybe_unused,
1040 return 0; 922 return 0;
1041} 923}
1042 924
1043static bool append_file;
1044
1045static const struct option options[] = {
1046 OPT_CALLBACK('e', "event", &evsel_list, "event",
1047 "event selector. use 'perf list' to list available events",
1048 parse_events_option),
1049 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1050 "event filter", parse_filter),
1051 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1052 "child tasks do not inherit counters"),
1053 OPT_STRING('p', "pid", &target.pid, "pid",
1054 "stat events on existing process id"),
1055 OPT_STRING('t', "tid", &target.tid, "tid",
1056 "stat events on existing thread id"),
1057 OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1058 "system-wide collection from all CPUs"),
1059 OPT_BOOLEAN('g', "group", &group,
1060 "put the counters into a counter group"),
1061 OPT_BOOLEAN('c', "scale", &scale,
1062 "scale/normalize counters"),
1063 OPT_INCR('v', "verbose", &verbose,
1064 "be more verbose (show counter open errors, etc)"),
1065 OPT_INTEGER('r', "repeat", &run_count,
1066 "repeat command and print average + stddev (max: 100)"),
1067 OPT_BOOLEAN('n', "null", &null_run,
1068 "null run - dont start any counters"),
1069 OPT_INCR('d', "detailed", &detailed_run,
1070 "detailed run - start a lot of events"),
1071 OPT_BOOLEAN('S', "sync", &sync_run,
1072 "call sync() before starting a run"),
1073 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1074 "print large numbers with thousands\' separators",
1075 stat__set_big_num),
1076 OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1077 "list of cpus to monitor in system-wide"),
1078 OPT_BOOLEAN('A', "no-aggr", &no_aggr,
1079 "disable CPU count aggregation"),
1080 OPT_STRING('x', "field-separator", &csv_sep, "separator",
1081 "print counts with custom separator"),
1082 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1083 "monitor event in cgroup name only",
1084 parse_cgroups),
1085 OPT_STRING('o', "output", &output_name, "file",
1086 "output file name"),
1087 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1088 OPT_INTEGER(0, "log-fd", &output_fd,
1089 "log output to fd, instead of stderr"),
1090 OPT_END()
1091};
1092
1093/* 925/*
1094 * Add default attributes, if there were no attributes specified or 926 * Add default attributes, if there were no attributes specified or
1095 * if -d/--detailed, -d -d or -d -d -d is used: 927 * if -d/--detailed, -d -d or -d -d -d is used:
1096 */ 928 */
1097static int add_default_attributes(void) 929static int add_default_attributes(void)
1098{ 930{
931 struct perf_event_attr default_attrs[] = {
932
933 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_TASK_CLOCK },
934 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CONTEXT_SWITCHES },
935 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_CPU_MIGRATIONS },
936 { .type = PERF_TYPE_SOFTWARE, .config = PERF_COUNT_SW_PAGE_FAULTS },
937
938 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES },
939 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
940 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
941 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_INSTRUCTIONS },
942 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
943 { .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_BRANCH_MISSES },
944
945};
946
947/*
948 * Detailed stats (-d), covering the L1 and last level data caches:
949 */
950 struct perf_event_attr detailed_attrs[] = {
951
952 { .type = PERF_TYPE_HW_CACHE,
953 .config =
954 PERF_COUNT_HW_CACHE_L1D << 0 |
955 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
956 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
957
958 { .type = PERF_TYPE_HW_CACHE,
959 .config =
960 PERF_COUNT_HW_CACHE_L1D << 0 |
961 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
962 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
963
964 { .type = PERF_TYPE_HW_CACHE,
965 .config =
966 PERF_COUNT_HW_CACHE_LL << 0 |
967 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
968 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
969
970 { .type = PERF_TYPE_HW_CACHE,
971 .config =
972 PERF_COUNT_HW_CACHE_LL << 0 |
973 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
974 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
975};
976
977/*
978 * Very detailed stats (-d -d), covering the instruction cache and the TLB caches:
979 */
980 struct perf_event_attr very_detailed_attrs[] = {
981
982 { .type = PERF_TYPE_HW_CACHE,
983 .config =
984 PERF_COUNT_HW_CACHE_L1I << 0 |
985 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
986 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
987
988 { .type = PERF_TYPE_HW_CACHE,
989 .config =
990 PERF_COUNT_HW_CACHE_L1I << 0 |
991 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
992 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
993
994 { .type = PERF_TYPE_HW_CACHE,
995 .config =
996 PERF_COUNT_HW_CACHE_DTLB << 0 |
997 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
998 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
999
1000 { .type = PERF_TYPE_HW_CACHE,
1001 .config =
1002 PERF_COUNT_HW_CACHE_DTLB << 0 |
1003 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1004 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1005
1006 { .type = PERF_TYPE_HW_CACHE,
1007 .config =
1008 PERF_COUNT_HW_CACHE_ITLB << 0 |
1009 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1010 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1011
1012 { .type = PERF_TYPE_HW_CACHE,
1013 .config =
1014 PERF_COUNT_HW_CACHE_ITLB << 0 |
1015 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
1016 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1017
1018};
1019
1020/*
1021 * Very, very detailed stats (-d -d -d), adding prefetch events:
1022 */
1023 struct perf_event_attr very_very_detailed_attrs[] = {
1024
1025 { .type = PERF_TYPE_HW_CACHE,
1026 .config =
1027 PERF_COUNT_HW_CACHE_L1D << 0 |
1028 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
1029 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16) },
1030
1031 { .type = PERF_TYPE_HW_CACHE,
1032 .config =
1033 PERF_COUNT_HW_CACHE_L1D << 0 |
1034 (PERF_COUNT_HW_CACHE_OP_PREFETCH << 8) |
1035 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16) },
1036};
1037
1099 /* Set attrs if no event is selected and !null_run: */ 1038 /* Set attrs if no event is selected and !null_run: */
1100 if (null_run) 1039 if (null_run)
1101 return 0; 1040 return 0;
@@ -1130,8 +1069,59 @@ static int add_default_attributes(void)
1130 1069
1131int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused) 1070int cmd_stat(int argc, const char **argv, const char *prefix __maybe_unused)
1132{ 1071{
1072 bool append_file = false,
1073 sync_run = false;
1074 int output_fd = 0;
1075 const char *output_name = NULL;
1076 const struct option options[] = {
1077 OPT_CALLBACK('e', "event", &evsel_list, "event",
1078 "event selector. use 'perf list' to list available events",
1079 parse_events_option),
1080 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
1081 "event filter", parse_filter),
1082 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
1083 "child tasks do not inherit counters"),
1084 OPT_STRING('p', "pid", &target.pid, "pid",
1085 "stat events on existing process id"),
1086 OPT_STRING('t', "tid", &target.tid, "tid",
1087 "stat events on existing thread id"),
1088 OPT_BOOLEAN('a', "all-cpus", &target.system_wide,
1089 "system-wide collection from all CPUs"),
1090 OPT_BOOLEAN('g', "group", &group,
1091 "put the counters into a counter group"),
1092 OPT_BOOLEAN('c', "scale", &scale, "scale/normalize counters"),
1093 OPT_INCR('v', "verbose", &verbose,
1094 "be more verbose (show counter open errors, etc)"),
1095 OPT_INTEGER('r', "repeat", &run_count,
1096 "repeat command and print average + stddev (max: 100)"),
1097 OPT_BOOLEAN('n', "null", &null_run,
1098 "null run - dont start any counters"),
1099 OPT_INCR('d', "detailed", &detailed_run,
1100 "detailed run - start a lot of events"),
1101 OPT_BOOLEAN('S', "sync", &sync_run,
1102 "call sync() before starting a run"),
1103 OPT_CALLBACK_NOOPT('B', "big-num", NULL, NULL,
1104 "print large numbers with thousands\' separators",
1105 stat__set_big_num),
1106 OPT_STRING('C', "cpu", &target.cpu_list, "cpu",
1107 "list of cpus to monitor in system-wide"),
1108 OPT_BOOLEAN('A', "no-aggr", &no_aggr, "disable CPU count aggregation"),
1109 OPT_STRING('x', "field-separator", &csv_sep, "separator",
1110 "print counts with custom separator"),
1111 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
1112 "monitor event in cgroup name only", parse_cgroups),
1113 OPT_STRING('o', "output", &output_name, "file", "output file name"),
1114 OPT_BOOLEAN(0, "append", &append_file, "append to the output file"),
1115 OPT_INTEGER(0, "log-fd", &output_fd,
1116 "log output to fd, instead of stderr"),
1117 OPT_END()
1118 };
1119 const char * const stat_usage[] = {
1120 "perf stat [<options>] [<command>]",
1121 NULL
1122 };
1133 struct perf_evsel *pos; 1123 struct perf_evsel *pos;
1134 int status = -ENOMEM; 1124 int status = -ENOMEM, run_idx;
1135 const char *mode; 1125 const char *mode;
1136 1126
1137 setlocale(LC_ALL, ""); 1127 setlocale(LC_ALL, "");