diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 13:39:04 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-03 13:39:04 -0500 |
commit | 69aad6f1ee69546dea8535ab8f3da9f445d57328 (patch) | |
tree | b328ec140a6a90703a049fcc661d623025d7e81f /tools/perf/builtin-top.c | |
parent | 56f4c400349157289b474a3fd49ee96acab0a4d7 (diff) |
perf tools: Introduce event selectors
Out of ad-hoc code and global arrays with hard coded sizes.
This is the first step on having a library that will be first
used on regression tests in the 'perf test' tool.
[acme@felicio linux]$ size /tmp/perf.before
text data bss dec hex filename
1273776 97384 5104416 6475576 62cf38 /tmp/perf.before
[acme@felicio linux]$ size /tmp/perf.new
text data bss dec hex filename
1275422 97416 1392416 2765254 2a31c6 /tmp/perf.new
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Tom Zanussi <tzanussi@gmail.com>
LKML-Reference: <new-submission>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r-- | tools/perf/builtin-top.c | 176 |
1 files changed, 104 insertions, 72 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index ae15f046c405..13a836efa1e1 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "perf.h" | 21 | #include "perf.h" |
22 | 22 | ||
23 | #include "util/color.h" | 23 | #include "util/color.h" |
24 | #include "util/evsel.h" | ||
24 | #include "util/session.h" | 25 | #include "util/session.h" |
25 | #include "util/symbol.h" | 26 | #include "util/symbol.h" |
26 | #include "util/thread.h" | 27 | #include "util/thread.h" |
@@ -29,6 +30,7 @@ | |||
29 | #include "util/parse-options.h" | 30 | #include "util/parse-options.h" |
30 | #include "util/parse-events.h" | 31 | #include "util/parse-events.h" |
31 | #include "util/cpumap.h" | 32 | #include "util/cpumap.h" |
33 | #include "util/xyarray.h" | ||
32 | 34 | ||
33 | #include "util/debug.h" | 35 | #include "util/debug.h" |
34 | 36 | ||
@@ -55,7 +57,7 @@ | |||
55 | #include <linux/unistd.h> | 57 | #include <linux/unistd.h> |
56 | #include <linux/types.h> | 58 | #include <linux/types.h> |
57 | 59 | ||
58 | static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; | 60 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
59 | 61 | ||
60 | static bool system_wide = false; | 62 | static bool system_wide = false; |
61 | 63 | ||
@@ -100,6 +102,7 @@ struct sym_entry *sym_filter_entry = NULL; | |||
100 | struct sym_entry *sym_filter_entry_sched = NULL; | 102 | struct sym_entry *sym_filter_entry_sched = NULL; |
101 | static int sym_pcnt_filter = 5; | 103 | static int sym_pcnt_filter = 5; |
102 | static int sym_counter = 0; | 104 | static int sym_counter = 0; |
105 | static struct perf_evsel *sym_evsel = NULL; | ||
103 | static int display_weighted = -1; | 106 | static int display_weighted = -1; |
104 | static const char *cpu_list; | 107 | static const char *cpu_list; |
105 | 108 | ||
@@ -353,7 +356,7 @@ static void show_details(struct sym_entry *syme) | |||
353 | return; | 356 | return; |
354 | 357 | ||
355 | symbol = sym_entry__symbol(syme); | 358 | symbol = sym_entry__symbol(syme); |
356 | printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); | 359 | printf("Showing %s for %s\n", event_name(sym_evsel), symbol->name); |
357 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); | 360 | printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); |
358 | 361 | ||
359 | pthread_mutex_lock(&syme->src->lock); | 362 | pthread_mutex_lock(&syme->src->lock); |
@@ -460,7 +463,8 @@ static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se) | |||
460 | static void print_sym_table(void) | 463 | static void print_sym_table(void) |
461 | { | 464 | { |
462 | int printed = 0, j; | 465 | int printed = 0, j; |
463 | int counter, snap = !display_weighted ? sym_counter : 0; | 466 | struct perf_evsel *counter; |
467 | int snap = !display_weighted ? sym_counter : 0; | ||
464 | float samples_per_sec = samples/delay_secs; | 468 | float samples_per_sec = samples/delay_secs; |
465 | float ksamples_per_sec = kernel_samples/delay_secs; | 469 | float ksamples_per_sec = kernel_samples/delay_secs; |
466 | float us_samples_per_sec = (us_samples)/delay_secs; | 470 | float us_samples_per_sec = (us_samples)/delay_secs; |
@@ -532,7 +536,9 @@ static void print_sym_table(void) | |||
532 | } | 536 | } |
533 | 537 | ||
534 | if (nr_counters == 1 || !display_weighted) { | 538 | if (nr_counters == 1 || !display_weighted) { |
535 | printf("%Ld", (u64)attrs[0].sample_period); | 539 | struct perf_evsel *first; |
540 | first = list_entry(evsel_list.next, struct perf_evsel, node); | ||
541 | printf("%Ld", first->attr.sample_period); | ||
536 | if (freq) | 542 | if (freq) |
537 | printf("Hz "); | 543 | printf("Hz "); |
538 | else | 544 | else |
@@ -540,9 +546,9 @@ static void print_sym_table(void) | |||
540 | } | 546 | } |
541 | 547 | ||
542 | if (!display_weighted) | 548 | if (!display_weighted) |
543 | printf("%s", event_name(sym_counter)); | 549 | printf("%s", event_name(sym_evsel)); |
544 | else for (counter = 0; counter < nr_counters; counter++) { | 550 | else list_for_each_entry(counter, &evsel_list, node) { |
545 | if (counter) | 551 | if (counter->idx) |
546 | printf("/"); | 552 | printf("/"); |
547 | 553 | ||
548 | printf("%s", event_name(counter)); | 554 | printf("%s", event_name(counter)); |
@@ -739,7 +745,7 @@ static void print_mapped_keys(void) | |||
739 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); | 745 | fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); |
740 | 746 | ||
741 | if (nr_counters > 1) | 747 | if (nr_counters > 1) |
742 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter)); | 748 | fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel)); |
743 | 749 | ||
744 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); | 750 | fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); |
745 | 751 | ||
@@ -826,19 +832,23 @@ static void handle_keypress(struct perf_session *session, int c) | |||
826 | break; | 832 | break; |
827 | case 'E': | 833 | case 'E': |
828 | if (nr_counters > 1) { | 834 | if (nr_counters > 1) { |
829 | int i; | ||
830 | |||
831 | fprintf(stderr, "\nAvailable events:"); | 835 | fprintf(stderr, "\nAvailable events:"); |
832 | for (i = 0; i < nr_counters; i++) | 836 | |
833 | fprintf(stderr, "\n\t%d %s", i, event_name(i)); | 837 | list_for_each_entry(sym_evsel, &evsel_list, node) |
838 | fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel)); | ||
834 | 839 | ||
835 | prompt_integer(&sym_counter, "Enter details event counter"); | 840 | prompt_integer(&sym_counter, "Enter details event counter"); |
836 | 841 | ||
837 | if (sym_counter >= nr_counters) { | 842 | if (sym_counter >= nr_counters) { |
838 | fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0)); | 843 | sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node); |
839 | sym_counter = 0; | 844 | sym_counter = 0; |
845 | fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel)); | ||
840 | sleep(1); | 846 | sleep(1); |
847 | break; | ||
841 | } | 848 | } |
849 | list_for_each_entry(sym_evsel, &evsel_list, node) | ||
850 | if (sym_evsel->idx == sym_counter) | ||
851 | break; | ||
842 | } else sym_counter = 0; | 852 | } else sym_counter = 0; |
843 | break; | 853 | break; |
844 | case 'f': | 854 | case 'f': |
@@ -978,7 +988,8 @@ static int symbol_filter(struct map *map, struct symbol *sym) | |||
978 | 988 | ||
979 | static void event__process_sample(const event_t *self, | 989 | static void event__process_sample(const event_t *self, |
980 | struct sample_data *sample, | 990 | struct sample_data *sample, |
981 | struct perf_session *session, int counter) | 991 | struct perf_session *session, |
992 | struct perf_evsel *evsel) | ||
982 | { | 993 | { |
983 | u64 ip = self->ip.ip; | 994 | u64 ip = self->ip.ip; |
984 | struct sym_entry *syme; | 995 | struct sym_entry *syme; |
@@ -1071,9 +1082,9 @@ static void event__process_sample(const event_t *self, | |||
1071 | 1082 | ||
1072 | syme = symbol__priv(al.sym); | 1083 | syme = symbol__priv(al.sym); |
1073 | if (!syme->skip) { | 1084 | if (!syme->skip) { |
1074 | syme->count[counter]++; | 1085 | syme->count[evsel->idx]++; |
1075 | syme->origin = origin; | 1086 | syme->origin = origin; |
1076 | record_precise_ip(syme, counter, ip); | 1087 | record_precise_ip(syme, evsel->idx, ip); |
1077 | pthread_mutex_lock(&active_symbols_lock); | 1088 | pthread_mutex_lock(&active_symbols_lock); |
1078 | if (list_empty(&syme->node) || !syme->node.next) | 1089 | if (list_empty(&syme->node) || !syme->node.next) |
1079 | __list_insert_active_sym(syme); | 1090 | __list_insert_active_sym(syme); |
@@ -1082,12 +1093,24 @@ static void event__process_sample(const event_t *self, | |||
1082 | } | 1093 | } |
1083 | 1094 | ||
1084 | struct mmap_data { | 1095 | struct mmap_data { |
1085 | int counter; | ||
1086 | void *base; | 1096 | void *base; |
1087 | int mask; | 1097 | int mask; |
1088 | unsigned int prev; | 1098 | unsigned int prev; |
1089 | }; | 1099 | }; |
1090 | 1100 | ||
1101 | static int perf_evsel__alloc_mmap_per_thread(struct perf_evsel *evsel, | ||
1102 | int ncpus, int nthreads) | ||
1103 | { | ||
1104 | evsel->priv = xyarray__new(ncpus, nthreads, sizeof(struct mmap_data)); | ||
1105 | return evsel->priv != NULL ? 0 : -ENOMEM; | ||
1106 | } | ||
1107 | |||
1108 | static void perf_evsel__free_mmap(struct perf_evsel *evsel) | ||
1109 | { | ||
1110 | xyarray__delete(evsel->priv); | ||
1111 | evsel->priv = NULL; | ||
1112 | } | ||
1113 | |||
1091 | static unsigned int mmap_read_head(struct mmap_data *md) | 1114 | static unsigned int mmap_read_head(struct mmap_data *md) |
1092 | { | 1115 | { |
1093 | struct perf_event_mmap_page *pc = md->base; | 1116 | struct perf_event_mmap_page *pc = md->base; |
@@ -1100,8 +1123,11 @@ static unsigned int mmap_read_head(struct mmap_data *md) | |||
1100 | } | 1123 | } |
1101 | 1124 | ||
1102 | static void perf_session__mmap_read_counter(struct perf_session *self, | 1125 | static void perf_session__mmap_read_counter(struct perf_session *self, |
1103 | struct mmap_data *md) | 1126 | struct perf_evsel *evsel, |
1127 | int cpu, int thread_idx) | ||
1104 | { | 1128 | { |
1129 | struct xyarray *mmap_array = evsel->priv; | ||
1130 | struct mmap_data *md = xyarray__entry(mmap_array, cpu, thread_idx); | ||
1105 | unsigned int head = mmap_read_head(md); | 1131 | unsigned int head = mmap_read_head(md); |
1106 | unsigned int old = md->prev; | 1132 | unsigned int old = md->prev; |
1107 | unsigned char *data = md->base + page_size; | 1133 | unsigned char *data = md->base + page_size; |
@@ -1155,7 +1181,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self, | |||
1155 | 1181 | ||
1156 | event__parse_sample(event, self, &sample); | 1182 | event__parse_sample(event, self, &sample); |
1157 | if (event->header.type == PERF_RECORD_SAMPLE) | 1183 | if (event->header.type == PERF_RECORD_SAMPLE) |
1158 | event__process_sample(event, &sample, self, md->counter); | 1184 | event__process_sample(event, &sample, self, evsel); |
1159 | else | 1185 | else |
1160 | event__process(event, &sample, self); | 1186 | event__process(event, &sample, self); |
1161 | old += size; | 1187 | old += size; |
@@ -1165,28 +1191,31 @@ static void perf_session__mmap_read_counter(struct perf_session *self, | |||
1165 | } | 1191 | } |
1166 | 1192 | ||
1167 | static struct pollfd *event_array; | 1193 | static struct pollfd *event_array; |
1168 | static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; | ||
1169 | 1194 | ||
1170 | static void perf_session__mmap_read(struct perf_session *self) | 1195 | static void perf_session__mmap_read(struct perf_session *self) |
1171 | { | 1196 | { |
1172 | int i, counter, thread_index; | 1197 | struct perf_evsel *counter; |
1198 | int i, thread_index; | ||
1173 | 1199 | ||
1174 | for (i = 0; i < nr_cpus; i++) { | 1200 | for (i = 0; i < nr_cpus; i++) { |
1175 | for (counter = 0; counter < nr_counters; counter++) | 1201 | list_for_each_entry(counter, &evsel_list, node) { |
1176 | for (thread_index = 0; | 1202 | for (thread_index = 0; |
1177 | thread_index < thread_num; | 1203 | thread_index < thread_num; |
1178 | thread_index++) { | 1204 | thread_index++) { |
1179 | perf_session__mmap_read_counter(self, | 1205 | perf_session__mmap_read_counter(self, |
1180 | &mmap_array[i][counter][thread_index]); | 1206 | counter, i, thread_index); |
1181 | } | 1207 | } |
1208 | } | ||
1182 | } | 1209 | } |
1183 | } | 1210 | } |
1184 | 1211 | ||
1185 | int nr_poll; | 1212 | int nr_poll; |
1186 | int group_fd; | 1213 | int group_fd; |
1187 | 1214 | ||
1188 | static void start_counter(int i, int counter) | 1215 | static void start_counter(int i, struct perf_evsel *evsel) |
1189 | { | 1216 | { |
1217 | struct xyarray *mmap_array = evsel->priv; | ||
1218 | struct mmap_data *mm; | ||
1190 | struct perf_event_attr *attr; | 1219 | struct perf_event_attr *attr; |
1191 | int cpu = -1; | 1220 | int cpu = -1; |
1192 | int thread_index; | 1221 | int thread_index; |
@@ -1194,7 +1223,7 @@ static void start_counter(int i, int counter) | |||
1194 | if (target_tid == -1) | 1223 | if (target_tid == -1) |
1195 | cpu = cpumap[i]; | 1224 | cpu = cpumap[i]; |
1196 | 1225 | ||
1197 | attr = attrs + counter; | 1226 | attr = &evsel->attr; |
1198 | 1227 | ||
1199 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; | 1228 | attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; |
1200 | 1229 | ||
@@ -1209,10 +1238,10 @@ static void start_counter(int i, int counter) | |||
1209 | 1238 | ||
1210 | for (thread_index = 0; thread_index < thread_num; thread_index++) { | 1239 | for (thread_index = 0; thread_index < thread_num; thread_index++) { |
1211 | try_again: | 1240 | try_again: |
1212 | fd[i][counter][thread_index] = sys_perf_event_open(attr, | 1241 | FD(evsel, i, thread_index) = sys_perf_event_open(attr, |
1213 | all_tids[thread_index], cpu, group_fd, 0); | 1242 | all_tids[thread_index], cpu, group_fd, 0); |
1214 | 1243 | ||
1215 | if (fd[i][counter][thread_index] < 0) { | 1244 | if (FD(evsel, i, thread_index) < 0) { |
1216 | int err = errno; | 1245 | int err = errno; |
1217 | 1246 | ||
1218 | if (err == EPERM || err == EACCES) | 1247 | if (err == EPERM || err == EACCES) |
@@ -1236,29 +1265,29 @@ try_again: | |||
1236 | } | 1265 | } |
1237 | printf("\n"); | 1266 | printf("\n"); |
1238 | error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", | 1267 | error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", |
1239 | fd[i][counter][thread_index], strerror(err)); | 1268 | FD(evsel, i, thread_index), strerror(err)); |
1240 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 1269 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); |
1241 | exit(-1); | 1270 | exit(-1); |
1242 | } | 1271 | } |
1243 | assert(fd[i][counter][thread_index] >= 0); | 1272 | assert(FD(evsel, i, thread_index) >= 0); |
1244 | fcntl(fd[i][counter][thread_index], F_SETFL, O_NONBLOCK); | 1273 | fcntl(FD(evsel, i, thread_index), F_SETFL, O_NONBLOCK); |
1245 | 1274 | ||
1246 | /* | 1275 | /* |
1247 | * First counter acts as the group leader: | 1276 | * First counter acts as the group leader: |
1248 | */ | 1277 | */ |
1249 | if (group && group_fd == -1) | 1278 | if (group && group_fd == -1) |
1250 | group_fd = fd[i][counter][thread_index]; | 1279 | group_fd = FD(evsel, i, thread_index); |
1251 | 1280 | ||
1252 | event_array[nr_poll].fd = fd[i][counter][thread_index]; | 1281 | event_array[nr_poll].fd = FD(evsel, i, thread_index); |
1253 | event_array[nr_poll].events = POLLIN; | 1282 | event_array[nr_poll].events = POLLIN; |
1254 | nr_poll++; | 1283 | nr_poll++; |
1255 | 1284 | ||
1256 | mmap_array[i][counter][thread_index].counter = counter; | 1285 | mm = xyarray__entry(mmap_array, i, thread_index); |
1257 | mmap_array[i][counter][thread_index].prev = 0; | 1286 | mm->prev = 0; |
1258 | mmap_array[i][counter][thread_index].mask = mmap_pages*page_size - 1; | 1287 | mm->mask = mmap_pages*page_size - 1; |
1259 | mmap_array[i][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size, | 1288 | mm->base = mmap(NULL, (mmap_pages+1)*page_size, |
1260 | PROT_READ, MAP_SHARED, fd[i][counter][thread_index], 0); | 1289 | PROT_READ, MAP_SHARED, FD(evsel, i, thread_index), 0); |
1261 | if (mmap_array[i][counter][thread_index].base == MAP_FAILED) | 1290 | if (mm->base == MAP_FAILED) |
1262 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | 1291 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); |
1263 | } | 1292 | } |
1264 | } | 1293 | } |
@@ -1266,8 +1295,8 @@ try_again: | |||
1266 | static int __cmd_top(void) | 1295 | static int __cmd_top(void) |
1267 | { | 1296 | { |
1268 | pthread_t thread; | 1297 | pthread_t thread; |
1269 | int i, counter; | 1298 | struct perf_evsel *counter; |
1270 | int ret; | 1299 | int i, ret; |
1271 | /* | 1300 | /* |
1272 | * FIXME: perf_session__new should allow passing a O_MMAP, so that all this | 1301 | * FIXME: perf_session__new should allow passing a O_MMAP, so that all this |
1273 | * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. | 1302 | * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. |
@@ -1283,7 +1312,7 @@ static int __cmd_top(void) | |||
1283 | 1312 | ||
1284 | for (i = 0; i < nr_cpus; i++) { | 1313 | for (i = 0; i < nr_cpus; i++) { |
1285 | group_fd = -1; | 1314 | group_fd = -1; |
1286 | for (counter = 0; counter < nr_counters; counter++) | 1315 | list_for_each_entry(counter, &evsel_list, node) |
1287 | start_counter(i, counter); | 1316 | start_counter(i, counter); |
1288 | } | 1317 | } |
1289 | 1318 | ||
@@ -1372,8 +1401,8 @@ static const struct option options[] = { | |||
1372 | 1401 | ||
1373 | int cmd_top(int argc, const char **argv, const char *prefix __used) | 1402 | int cmd_top(int argc, const char **argv, const char *prefix __used) |
1374 | { | 1403 | { |
1375 | int counter; | 1404 | struct perf_evsel *pos; |
1376 | int i,j; | 1405 | int status = -ENOMEM; |
1377 | 1406 | ||
1378 | page_size = sysconf(_SC_PAGE_SIZE); | 1407 | page_size = sysconf(_SC_PAGE_SIZE); |
1379 | 1408 | ||
@@ -1398,15 +1427,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1398 | thread_num = 1; | 1427 | thread_num = 1; |
1399 | } | 1428 | } |
1400 | 1429 | ||
1401 | for (i = 0; i < MAX_NR_CPUS; i++) { | ||
1402 | for (j = 0; j < MAX_COUNTERS; j++) { | ||
1403 | fd[i][j] = malloc(sizeof(int)*thread_num); | ||
1404 | mmap_array[i][j] = zalloc( | ||
1405 | sizeof(struct mmap_data)*thread_num); | ||
1406 | if (!fd[i][j] || !mmap_array[i][j]) | ||
1407 | return -ENOMEM; | ||
1408 | } | ||
1409 | } | ||
1410 | event_array = malloc( | 1430 | event_array = malloc( |
1411 | sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num); | 1431 | sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num); |
1412 | if (!event_array) | 1432 | if (!event_array) |
@@ -1419,15 +1439,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1419 | cpu_list = NULL; | 1439 | cpu_list = NULL; |
1420 | } | 1440 | } |
1421 | 1441 | ||
1422 | if (!nr_counters) | 1442 | if (!nr_counters && perf_evsel_list__create_default() < 0) { |
1423 | nr_counters = 1; | 1443 | pr_err("Not enough memory for event selector list\n"); |
1424 | 1444 | return -ENOMEM; | |
1425 | symbol_conf.priv_size = (sizeof(struct sym_entry) + | 1445 | } |
1426 | (nr_counters + 1) * sizeof(unsigned long)); | ||
1427 | |||
1428 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); | ||
1429 | if (symbol__init() < 0) | ||
1430 | return -1; | ||
1431 | 1446 | ||
1432 | if (delay_secs < 1) | 1447 | if (delay_secs < 1) |
1433 | delay_secs = 1; | 1448 | delay_secs = 1; |
@@ -1444,16 +1459,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1444 | exit(EXIT_FAILURE); | 1459 | exit(EXIT_FAILURE); |
1445 | } | 1460 | } |
1446 | 1461 | ||
1447 | /* | ||
1448 | * Fill in the ones not specifically initialized via -c: | ||
1449 | */ | ||
1450 | for (counter = 0; counter < nr_counters; counter++) { | ||
1451 | if (attrs[counter].sample_period) | ||
1452 | continue; | ||
1453 | |||
1454 | attrs[counter].sample_period = default_interval; | ||
1455 | } | ||
1456 | |||
1457 | if (target_tid != -1) | 1462 | if (target_tid != -1) |
1458 | nr_cpus = 1; | 1463 | nr_cpus = 1; |
1459 | else | 1464 | else |
@@ -1462,11 +1467,38 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1462 | if (nr_cpus < 1) | 1467 | if (nr_cpus < 1) |
1463 | usage_with_options(top_usage, options); | 1468 | usage_with_options(top_usage, options); |
1464 | 1469 | ||
1470 | list_for_each_entry(pos, &evsel_list, node) { | ||
1471 | if (perf_evsel__alloc_mmap_per_thread(pos, nr_cpus, thread_num) < 0 || | ||
1472 | perf_evsel__alloc_fd(pos, nr_cpus, thread_num) < 0) | ||
1473 | goto out_free_fd; | ||
1474 | /* | ||
1475 | * Fill in the ones not specifically initialized via -c: | ||
1476 | */ | ||
1477 | if (pos->attr.sample_period) | ||
1478 | continue; | ||
1479 | |||
1480 | pos->attr.sample_period = default_interval; | ||
1481 | } | ||
1482 | |||
1483 | symbol_conf.priv_size = (sizeof(struct sym_entry) + | ||
1484 | (nr_counters + 1) * sizeof(unsigned long)); | ||
1485 | |||
1486 | symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL); | ||
1487 | if (symbol__init() < 0) | ||
1488 | return -1; | ||
1489 | |||
1465 | get_term_dimensions(&winsize); | 1490 | get_term_dimensions(&winsize); |
1466 | if (print_entries == 0) { | 1491 | if (print_entries == 0) { |
1467 | update_print_entries(&winsize); | 1492 | update_print_entries(&winsize); |
1468 | signal(SIGWINCH, sig_winch_handler); | 1493 | signal(SIGWINCH, sig_winch_handler); |
1469 | } | 1494 | } |
1470 | 1495 | ||
1471 | return __cmd_top(); | 1496 | status = __cmd_top(); |
1497 | out_free_fd: | ||
1498 | list_for_each_entry(pos, &evsel_list, node) { | ||
1499 | perf_evsel__free_fd(pos); | ||
1500 | perf_evsel__free_mmap(pos); | ||
1501 | } | ||
1502 | |||
1503 | return status; | ||
1472 | } | 1504 | } |