aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-top.c')
-rw-r--r--tools/perf/builtin-top.c237
1 files changed, 131 insertions, 106 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index dd625808c2a5..1e67ab9c7ebc 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
58static int *fd[MAX_NR_CPUS][MAX_COUNTERS]; 60#define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
59 61
60static bool system_wide = false; 62static bool system_wide = false;
61 63
@@ -66,10 +68,9 @@ static int print_entries;
66 68
67static int target_pid = -1; 69static int target_pid = -1;
68static int target_tid = -1; 70static int target_tid = -1;
69static pid_t *all_tids = NULL; 71static struct thread_map *threads;
70static int thread_num = 0;
71static bool inherit = false; 72static bool inherit = false;
72static int nr_cpus = 0; 73static struct cpu_map *cpus;
73static int realtime_prio = 0; 74static int realtime_prio = 0;
74static bool group = false; 75static bool group = false;
75static unsigned int page_size; 76static unsigned int page_size;
@@ -100,6 +101,7 @@ struct sym_entry *sym_filter_entry = NULL;
100struct sym_entry *sym_filter_entry_sched = NULL; 101struct sym_entry *sym_filter_entry_sched = NULL;
101static int sym_pcnt_filter = 5; 102static int sym_pcnt_filter = 5;
102static int sym_counter = 0; 103static int sym_counter = 0;
104static struct perf_evsel *sym_evsel = NULL;
103static int display_weighted = -1; 105static int display_weighted = -1;
104static const char *cpu_list; 106static const char *cpu_list;
105 107
@@ -353,7 +355,7 @@ static void show_details(struct sym_entry *syme)
353 return; 355 return;
354 356
355 symbol = sym_entry__symbol(syme); 357 symbol = sym_entry__symbol(syme);
356 printf("Showing %s for %s\n", event_name(sym_counter), symbol->name); 358 printf("Showing %s for %s\n", event_name(sym_evsel), symbol->name);
357 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter); 359 printf(" Events Pcnt (>=%d%%)\n", sym_pcnt_filter);
358 360
359 pthread_mutex_lock(&syme->src->lock); 361 pthread_mutex_lock(&syme->src->lock);
@@ -460,7 +462,8 @@ static void rb_insert_active_sym(struct rb_root *tree, struct sym_entry *se)
460static void print_sym_table(void) 462static void print_sym_table(void)
461{ 463{
462 int printed = 0, j; 464 int printed = 0, j;
463 int counter, snap = !display_weighted ? sym_counter : 0; 465 struct perf_evsel *counter;
466 int snap = !display_weighted ? sym_counter : 0;
464 float samples_per_sec = samples/delay_secs; 467 float samples_per_sec = samples/delay_secs;
465 float ksamples_per_sec = kernel_samples/delay_secs; 468 float ksamples_per_sec = kernel_samples/delay_secs;
466 float us_samples_per_sec = (us_samples)/delay_secs; 469 float us_samples_per_sec = (us_samples)/delay_secs;
@@ -532,7 +535,9 @@ static void print_sym_table(void)
532 } 535 }
533 536
534 if (nr_counters == 1 || !display_weighted) { 537 if (nr_counters == 1 || !display_weighted) {
535 printf("%Ld", (u64)attrs[0].sample_period); 538 struct perf_evsel *first;
539 first = list_entry(evsel_list.next, struct perf_evsel, node);
540 printf("%Ld", first->attr.sample_period);
536 if (freq) 541 if (freq)
537 printf("Hz "); 542 printf("Hz ");
538 else 543 else
@@ -540,9 +545,9 @@ static void print_sym_table(void)
540 } 545 }
541 546
542 if (!display_weighted) 547 if (!display_weighted)
543 printf("%s", event_name(sym_counter)); 548 printf("%s", event_name(sym_evsel));
544 else for (counter = 0; counter < nr_counters; counter++) { 549 else list_for_each_entry(counter, &evsel_list, node) {
545 if (counter) 550 if (counter->idx)
546 printf("/"); 551 printf("/");
547 552
548 printf("%s", event_name(counter)); 553 printf("%s", event_name(counter));
@@ -558,12 +563,12 @@ static void print_sym_table(void)
558 printf(" (all"); 563 printf(" (all");
559 564
560 if (cpu_list) 565 if (cpu_list)
561 printf(", CPU%s: %s)\n", nr_cpus > 1 ? "s" : "", cpu_list); 566 printf(", CPU%s: %s)\n", cpus->nr > 1 ? "s" : "", cpu_list);
562 else { 567 else {
563 if (target_tid != -1) 568 if (target_tid != -1)
564 printf(")\n"); 569 printf(")\n");
565 else 570 else
566 printf(", %d CPU%s)\n", nr_cpus, nr_cpus > 1 ? "s" : ""); 571 printf(", %d CPU%s)\n", cpus->nr, cpus->nr > 1 ? "s" : "");
567 } 572 }
568 573
569 printf("%-*.*s\n", win_width, win_width, graph_dotted_line); 574 printf("%-*.*s\n", win_width, win_width, graph_dotted_line);
@@ -739,7 +744,7 @@ static void print_mapped_keys(void)
739 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries); 744 fprintf(stdout, "\t[e] display entries (lines). \t(%d)\n", print_entries);
740 745
741 if (nr_counters > 1) 746 if (nr_counters > 1)
742 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_counter)); 747 fprintf(stdout, "\t[E] active event counter. \t(%s)\n", event_name(sym_evsel));
743 748
744 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter); 749 fprintf(stdout, "\t[f] profile display filter (count). \t(%d)\n", count_filter);
745 750
@@ -826,19 +831,23 @@ static void handle_keypress(struct perf_session *session, int c)
826 break; 831 break;
827 case 'E': 832 case 'E':
828 if (nr_counters > 1) { 833 if (nr_counters > 1) {
829 int i;
830
831 fprintf(stderr, "\nAvailable events:"); 834 fprintf(stderr, "\nAvailable events:");
832 for (i = 0; i < nr_counters; i++) 835
833 fprintf(stderr, "\n\t%d %s", i, event_name(i)); 836 list_for_each_entry(sym_evsel, &evsel_list, node)
837 fprintf(stderr, "\n\t%d %s", sym_evsel->idx, event_name(sym_evsel));
834 838
835 prompt_integer(&sym_counter, "Enter details event counter"); 839 prompt_integer(&sym_counter, "Enter details event counter");
836 840
837 if (sym_counter >= nr_counters) { 841 if (sym_counter >= nr_counters) {
838 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(0)); 842 sym_evsel = list_entry(evsel_list.next, struct perf_evsel, node);
839 sym_counter = 0; 843 sym_counter = 0;
844 fprintf(stderr, "Sorry, no such event, using %s.\n", event_name(sym_evsel));
840 sleep(1); 845 sleep(1);
846 break;
841 } 847 }
848 list_for_each_entry(sym_evsel, &evsel_list, node)
849 if (sym_evsel->idx == sym_counter)
850 break;
842 } else sym_counter = 0; 851 } else sym_counter = 0;
843 break; 852 break;
844 case 'f': 853 case 'f':
@@ -977,12 +986,13 @@ static int symbol_filter(struct map *map, struct symbol *sym)
977} 986}
978 987
979static void event__process_sample(const event_t *self, 988static void event__process_sample(const event_t *self,
980 struct perf_session *session, int counter) 989 struct sample_data *sample,
990 struct perf_session *session,
991 struct perf_evsel *evsel)
981{ 992{
982 u64 ip = self->ip.ip; 993 u64 ip = self->ip.ip;
983 struct sym_entry *syme; 994 struct sym_entry *syme;
984 struct addr_location al; 995 struct addr_location al;
985 struct sample_data data;
986 struct machine *machine; 996 struct machine *machine;
987 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 997 u8 origin = self->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
988 998
@@ -1025,7 +1035,7 @@ static void event__process_sample(const event_t *self,
1025 if (self->header.misc & PERF_RECORD_MISC_EXACT_IP) 1035 if (self->header.misc & PERF_RECORD_MISC_EXACT_IP)
1026 exact_samples++; 1036 exact_samples++;
1027 1037
1028 if (event__preprocess_sample(self, session, &al, &data, 1038 if (event__preprocess_sample(self, session, &al, sample,
1029 symbol_filter) < 0 || 1039 symbol_filter) < 0 ||
1030 al.filtered) 1040 al.filtered)
1031 return; 1041 return;
@@ -1071,9 +1081,9 @@ static void event__process_sample(const event_t *self,
1071 1081
1072 syme = symbol__priv(al.sym); 1082 syme = symbol__priv(al.sym);
1073 if (!syme->skip) { 1083 if (!syme->skip) {
1074 syme->count[counter]++; 1084 syme->count[evsel->idx]++;
1075 syme->origin = origin; 1085 syme->origin = origin;
1076 record_precise_ip(syme, counter, ip); 1086 record_precise_ip(syme, evsel->idx, ip);
1077 pthread_mutex_lock(&active_symbols_lock); 1087 pthread_mutex_lock(&active_symbols_lock);
1078 if (list_empty(&syme->node) || !syme->node.next) 1088 if (list_empty(&syme->node) || !syme->node.next)
1079 __list_insert_active_sym(syme); 1089 __list_insert_active_sym(syme);
@@ -1082,12 +1092,24 @@ static void event__process_sample(const event_t *self,
1082} 1092}
1083 1093
1084struct mmap_data { 1094struct mmap_data {
1085 int counter;
1086 void *base; 1095 void *base;
1087 int mask; 1096 int mask;
1088 unsigned int prev; 1097 unsigned int prev;
1089}; 1098};
1090 1099
1100static int perf_evsel__alloc_mmap_per_thread(struct perf_evsel *evsel,
1101 int ncpus, int nthreads)
1102{
1103 evsel->priv = xyarray__new(ncpus, nthreads, sizeof(struct mmap_data));
1104 return evsel->priv != NULL ? 0 : -ENOMEM;
1105}
1106
1107static void perf_evsel__free_mmap(struct perf_evsel *evsel)
1108{
1109 xyarray__delete(evsel->priv);
1110 evsel->priv = NULL;
1111}
1112
1091static unsigned int mmap_read_head(struct mmap_data *md) 1113static unsigned int mmap_read_head(struct mmap_data *md)
1092{ 1114{
1093 struct perf_event_mmap_page *pc = md->base; 1115 struct perf_event_mmap_page *pc = md->base;
@@ -1100,11 +1122,15 @@ static unsigned int mmap_read_head(struct mmap_data *md)
1100} 1122}
1101 1123
1102static void perf_session__mmap_read_counter(struct perf_session *self, 1124static void perf_session__mmap_read_counter(struct perf_session *self,
1103 struct mmap_data *md) 1125 struct perf_evsel *evsel,
1126 int cpu, int thread_idx)
1104{ 1127{
1128 struct xyarray *mmap_array = evsel->priv;
1129 struct mmap_data *md = xyarray__entry(mmap_array, cpu, thread_idx);
1105 unsigned int head = mmap_read_head(md); 1130 unsigned int head = mmap_read_head(md);
1106 unsigned int old = md->prev; 1131 unsigned int old = md->prev;
1107 unsigned char *data = md->base + page_size; 1132 unsigned char *data = md->base + page_size;
1133 struct sample_data sample;
1108 int diff; 1134 int diff;
1109 1135
1110 /* 1136 /*
@@ -1152,10 +1178,11 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
1152 event = &event_copy; 1178 event = &event_copy;
1153 } 1179 }
1154 1180
1181 event__parse_sample(event, self, &sample);
1155 if (event->header.type == PERF_RECORD_SAMPLE) 1182 if (event->header.type == PERF_RECORD_SAMPLE)
1156 event__process_sample(event, self, md->counter); 1183 event__process_sample(event, &sample, self, evsel);
1157 else 1184 else
1158 event__process(event, self); 1185 event__process(event, &sample, self);
1159 old += size; 1186 old += size;
1160 } 1187 }
1161 1188
@@ -1163,36 +1190,39 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
1163} 1190}
1164 1191
1165static struct pollfd *event_array; 1192static struct pollfd *event_array;
1166static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
1167 1193
1168static void perf_session__mmap_read(struct perf_session *self) 1194static void perf_session__mmap_read(struct perf_session *self)
1169{ 1195{
1170 int i, counter, thread_index; 1196 struct perf_evsel *counter;
1197 int i, thread_index;
1171 1198
1172 for (i = 0; i < nr_cpus; i++) { 1199 for (i = 0; i < cpus->nr; i++) {
1173 for (counter = 0; counter < nr_counters; counter++) 1200 list_for_each_entry(counter, &evsel_list, node) {
1174 for (thread_index = 0; 1201 for (thread_index = 0;
1175 thread_index < thread_num; 1202 thread_index < threads->nr;
1176 thread_index++) { 1203 thread_index++) {
1177 perf_session__mmap_read_counter(self, 1204 perf_session__mmap_read_counter(self,
1178 &mmap_array[i][counter][thread_index]); 1205 counter, i, thread_index);
1179 } 1206 }
1207 }
1180 } 1208 }
1181} 1209}
1182 1210
1183int nr_poll; 1211int nr_poll;
1184int group_fd; 1212int group_fd;
1185 1213
1186static void start_counter(int i, int counter) 1214static void start_counter(int i, struct perf_evsel *evsel)
1187{ 1215{
1216 struct xyarray *mmap_array = evsel->priv;
1217 struct mmap_data *mm;
1188 struct perf_event_attr *attr; 1218 struct perf_event_attr *attr;
1189 int cpu = -1; 1219 int cpu = -1;
1190 int thread_index; 1220 int thread_index;
1191 1221
1192 if (target_tid == -1) 1222 if (target_tid == -1)
1193 cpu = cpumap[i]; 1223 cpu = cpus->map[i];
1194 1224
1195 attr = attrs + counter; 1225 attr = &evsel->attr;
1196 1226
1197 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID; 1227 attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
1198 1228
@@ -1205,16 +1235,18 @@ static void start_counter(int i, int counter)
1205 attr->inherit = (cpu < 0) && inherit; 1235 attr->inherit = (cpu < 0) && inherit;
1206 attr->mmap = 1; 1236 attr->mmap = 1;
1207 1237
1208 for (thread_index = 0; thread_index < thread_num; thread_index++) { 1238 for (thread_index = 0; thread_index < threads->nr; thread_index++) {
1209try_again: 1239try_again:
1210 fd[i][counter][thread_index] = sys_perf_event_open(attr, 1240 FD(evsel, i, thread_index) = sys_perf_event_open(attr,
1211 all_tids[thread_index], cpu, group_fd, 0); 1241 threads->map[thread_index], cpu, group_fd, 0);
1212 1242
1213 if (fd[i][counter][thread_index] < 0) { 1243 if (FD(evsel, i, thread_index) < 0) {
1214 int err = errno; 1244 int err = errno;
1215 1245
1216 if (err == EPERM || err == EACCES) 1246 if (err == EPERM || err == EACCES)
1217 die("No permission - are you root?\n"); 1247 die("Permission error - are you root?\n"
1248 "\t Consider tweaking"
1249 " /proc/sys/kernel/perf_event_paranoid.\n");
1218 /* 1250 /*
1219 * If it's cycles then fall back to hrtimer 1251 * If it's cycles then fall back to hrtimer
1220 * based cpu-clock-tick sw counter, which 1252 * based cpu-clock-tick sw counter, which
@@ -1231,30 +1263,30 @@ try_again:
1231 goto try_again; 1263 goto try_again;
1232 } 1264 }
1233 printf("\n"); 1265 printf("\n");
1234 error("perfcounter syscall returned with %d (%s)\n", 1266 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
1235 fd[i][counter][thread_index], strerror(err)); 1267 FD(evsel, i, thread_index), strerror(err));
1236 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 1268 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1237 exit(-1); 1269 exit(-1);
1238 } 1270 }
1239 assert(fd[i][counter][thread_index] >= 0); 1271 assert(FD(evsel, i, thread_index) >= 0);
1240 fcntl(fd[i][counter][thread_index], F_SETFL, O_NONBLOCK); 1272 fcntl(FD(evsel, i, thread_index), F_SETFL, O_NONBLOCK);
1241 1273
1242 /* 1274 /*
1243 * First counter acts as the group leader: 1275 * First counter acts as the group leader:
1244 */ 1276 */
1245 if (group && group_fd == -1) 1277 if (group && group_fd == -1)
1246 group_fd = fd[i][counter][thread_index]; 1278 group_fd = FD(evsel, i, thread_index);
1247 1279
1248 event_array[nr_poll].fd = fd[i][counter][thread_index]; 1280 event_array[nr_poll].fd = FD(evsel, i, thread_index);
1249 event_array[nr_poll].events = POLLIN; 1281 event_array[nr_poll].events = POLLIN;
1250 nr_poll++; 1282 nr_poll++;
1251 1283
1252 mmap_array[i][counter][thread_index].counter = counter; 1284 mm = xyarray__entry(mmap_array, i, thread_index);
1253 mmap_array[i][counter][thread_index].prev = 0; 1285 mm->prev = 0;
1254 mmap_array[i][counter][thread_index].mask = mmap_pages*page_size - 1; 1286 mm->mask = mmap_pages*page_size - 1;
1255 mmap_array[i][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size, 1287 mm->base = mmap(NULL, (mmap_pages+1)*page_size,
1256 PROT_READ, MAP_SHARED, fd[i][counter][thread_index], 0); 1288 PROT_READ, MAP_SHARED, FD(evsel, i, thread_index), 0);
1257 if (mmap_array[i][counter][thread_index].base == MAP_FAILED) 1289 if (mm->base == MAP_FAILED)
1258 die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 1290 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
1259 } 1291 }
1260} 1292}
@@ -1262,13 +1294,13 @@ try_again:
1262static int __cmd_top(void) 1294static int __cmd_top(void)
1263{ 1295{
1264 pthread_t thread; 1296 pthread_t thread;
1265 int i, counter; 1297 struct perf_evsel *counter;
1266 int ret; 1298 int i, ret;
1267 /* 1299 /*
1268 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 1300 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
1269 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now. 1301 * mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
1270 */ 1302 */
1271 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false); 1303 struct perf_session *session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
1272 if (session == NULL) 1304 if (session == NULL)
1273 return -ENOMEM; 1305 return -ENOMEM;
1274 1306
@@ -1277,9 +1309,9 @@ static int __cmd_top(void)
1277 else 1309 else
1278 event__synthesize_threads(event__process, session); 1310 event__synthesize_threads(event__process, session);
1279 1311
1280 for (i = 0; i < nr_cpus; i++) { 1312 for (i = 0; i < cpus->nr; i++) {
1281 group_fd = -1; 1313 group_fd = -1;
1282 for (counter = 0; counter < nr_counters; counter++) 1314 list_for_each_entry(counter, &evsel_list, node)
1283 start_counter(i, counter); 1315 start_counter(i, counter);
1284 } 1316 }
1285 1317
@@ -1368,8 +1400,8 @@ static const struct option options[] = {
1368 1400
1369int cmd_top(int argc, const char **argv, const char *prefix __used) 1401int cmd_top(int argc, const char **argv, const char *prefix __used)
1370{ 1402{
1371 int counter; 1403 struct perf_evsel *pos;
1372 int i,j; 1404 int status = -ENOMEM;
1373 1405
1374 page_size = sysconf(_SC_PAGE_SIZE); 1406 page_size = sysconf(_SC_PAGE_SIZE);
1375 1407
@@ -1377,34 +1409,17 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1377 if (argc) 1409 if (argc)
1378 usage_with_options(top_usage, options); 1410 usage_with_options(top_usage, options);
1379 1411
1380 if (target_pid != -1) { 1412 if (target_pid != -1)
1381 target_tid = target_pid; 1413 target_tid = target_pid;
1382 thread_num = find_all_tid(target_pid, &all_tids);
1383 if (thread_num <= 0) {
1384 fprintf(stderr, "Can't find all threads of pid %d\n",
1385 target_pid);
1386 usage_with_options(top_usage, options);
1387 }
1388 } else {
1389 all_tids=malloc(sizeof(pid_t));
1390 if (!all_tids)
1391 return -ENOMEM;
1392 1414
1393 all_tids[0] = target_tid; 1415 threads = thread_map__new(target_pid, target_tid);
1394 thread_num = 1; 1416 if (threads == NULL) {
1417 pr_err("Problems finding threads of monitor\n");
1418 usage_with_options(top_usage, options);
1395 } 1419 }
1396 1420
1397 for (i = 0; i < MAX_NR_CPUS; i++) { 1421 event_array = malloc((sizeof(struct pollfd) *
1398 for (j = 0; j < MAX_COUNTERS; j++) { 1422 MAX_NR_CPUS * MAX_COUNTERS * threads->nr));
1399 fd[i][j] = malloc(sizeof(int)*thread_num);
1400 mmap_array[i][j] = zalloc(
1401 sizeof(struct mmap_data)*thread_num);
1402 if (!fd[i][j] || !mmap_array[i][j])
1403 return -ENOMEM;
1404 }
1405 }
1406 event_array = malloc(
1407 sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
1408 if (!event_array) 1423 if (!event_array)
1409 return -ENOMEM; 1424 return -ENOMEM;
1410 1425
@@ -1415,15 +1430,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1415 cpu_list = NULL; 1430 cpu_list = NULL;
1416 } 1431 }
1417 1432
1418 if (!nr_counters) 1433 if (!nr_counters && perf_evsel_list__create_default() < 0) {
1419 nr_counters = 1; 1434 pr_err("Not enough memory for event selector list\n");
1420 1435 return -ENOMEM;
1421 symbol_conf.priv_size = (sizeof(struct sym_entry) + 1436 }
1422 (nr_counters + 1) * sizeof(unsigned long));
1423
1424 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1425 if (symbol__init() < 0)
1426 return -1;
1427 1437
1428 if (delay_secs < 1) 1438 if (delay_secs < 1)
1429 delay_secs = 1; 1439 delay_secs = 1;
@@ -1440,23 +1450,33 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1440 exit(EXIT_FAILURE); 1450 exit(EXIT_FAILURE);
1441 } 1451 }
1442 1452
1443 /* 1453 if (target_tid != -1)
1444 * Fill in the ones not specifically initialized via -c: 1454 cpus = cpu_map__dummy_new();
1445 */ 1455 else
1446 for (counter = 0; counter < nr_counters; counter++) { 1456 cpus = cpu_map__new(cpu_list);
1447 if (attrs[counter].sample_period) 1457
1458 if (cpus == NULL)
1459 usage_with_options(top_usage, options);
1460
1461 list_for_each_entry(pos, &evsel_list, node) {
1462 if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 ||
1463 perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
1464 goto out_free_fd;
1465 /*
1466 * Fill in the ones not specifically initialized via -c:
1467 */
1468 if (pos->attr.sample_period)
1448 continue; 1469 continue;
1449 1470
1450 attrs[counter].sample_period = default_interval; 1471 pos->attr.sample_period = default_interval;
1451 } 1472 }
1452 1473
1453 if (target_tid != -1) 1474 symbol_conf.priv_size = (sizeof(struct sym_entry) +
1454 nr_cpus = 1; 1475 (nr_counters + 1) * sizeof(unsigned long));
1455 else
1456 nr_cpus = read_cpu_map(cpu_list);
1457 1476
1458 if (nr_cpus < 1) 1477 symbol_conf.try_vmlinux_path = (symbol_conf.vmlinux_name == NULL);
1459 usage_with_options(top_usage, options); 1478 if (symbol__init() < 0)
1479 return -1;
1460 1480
1461 get_term_dimensions(&winsize); 1481 get_term_dimensions(&winsize);
1462 if (print_entries == 0) { 1482 if (print_entries == 0) {
@@ -1464,5 +1484,10 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1464 signal(SIGWINCH, sig_winch_handler); 1484 signal(SIGWINCH, sig_winch_handler);
1465 } 1485 }
1466 1486
1467 return __cmd_top(); 1487 status = __cmd_top();
1488out_free_fd:
1489 list_for_each_entry(pos, &evsel_list, node)
1490 perf_evsel__free_mmap(pos);
1491
1492 return status;
1468} 1493}