aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-top.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-01-12 19:39:13 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-01-22 16:56:29 -0500
commit70db7533caef02350ec8d6852e589491bca3a951 (patch)
tree463dadbec60d585cb8c1de84b230378010d5c8b5 /tools/perf/builtin-top.c
parent115d2d8963a426670ac3ce983fc4c4e001703943 (diff)
perf evlist: Move the mmap array from perf_evsel
Adopting the new model used in 'perf record', where we don't have a map per thread per cpu, instead we have an mmap per cpu, established on the first fd for that cpu and ask the kernel using the PERF_EVENT_IOC_SET_OUTPUT ioctl to send events for the other fds on that cpu for the one with the mmap. The methods moved from perf_evsel to perf_evlist, but for easing review they were modified in place, in evsel.c, the next patch will move the migrated methods to evlist.c. With this 'perf top' now uses the same mmap model used by 'perf record' and the next patches will make 'perf record' use these new routines, establishing a common codebase for both tools. 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.c56
1 files changed, 28 insertions, 28 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 7d723ad0bfa..df85c1f9417 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -78,7 +78,7 @@ static struct cpu_map *cpus;
78static int realtime_prio = 0; 78static int realtime_prio = 0;
79static bool group = false; 79static bool group = false;
80static unsigned int page_size; 80static unsigned int page_size;
81static unsigned int mmap_pages = 16; 81static unsigned int mmap_pages = 128;
82static int freq = 1000; /* 1 KHz */ 82static int freq = 1000; /* 1 KHz */
83 83
84static int delay_secs = 2; 84static int delay_secs = 2;
@@ -991,8 +991,7 @@ static int symbol_filter(struct map *map, struct symbol *sym)
991 991
992static void event__process_sample(const event_t *self, 992static void event__process_sample(const event_t *self,
993 struct sample_data *sample, 993 struct sample_data *sample,
994 struct perf_session *session, 994 struct perf_session *session)
995 struct perf_evsel *evsel)
996{ 995{
997 u64 ip = self->ip.ip; 996 u64 ip = self->ip.ip;
998 struct sym_entry *syme; 997 struct sym_entry *syme;
@@ -1085,8 +1084,12 @@ static void event__process_sample(const event_t *self,
1085 1084
1086 syme = symbol__priv(al.sym); 1085 syme = symbol__priv(al.sym);
1087 if (!syme->skip) { 1086 if (!syme->skip) {
1088 syme->count[evsel->idx]++; 1087 struct perf_evsel *evsel;
1088
1089 syme->origin = origin; 1089 syme->origin = origin;
1090 evsel = perf_evlist__id2evsel(evsel_list, sample->id);
1091 assert(evsel != NULL);
1092 syme->count[evsel->idx]++;
1090 record_precise_ip(syme, evsel->idx, ip); 1093 record_precise_ip(syme, evsel->idx, ip);
1091 pthread_mutex_lock(&active_symbols_lock); 1094 pthread_mutex_lock(&active_symbols_lock);
1092 if (list_empty(&syme->node) || !syme->node.next) 1095 if (list_empty(&syme->node) || !syme->node.next)
@@ -1095,11 +1098,9 @@ static void event__process_sample(const event_t *self,
1095 } 1098 }
1096} 1099}
1097 1100
1098static void perf_session__mmap_read_counter(struct perf_session *self, 1101static void perf_session__mmap_read_cpu(struct perf_session *self, int cpu)
1099 struct perf_evsel *evsel,
1100 int cpu, int thread_idx)
1101{ 1102{
1102 struct perf_mmap *md = xyarray__entry(evsel->mmap, cpu, thread_idx); 1103 struct perf_mmap *md = &evsel_list->mmap[cpu];
1103 unsigned int head = perf_mmap__read_head(md); 1104 unsigned int head = perf_mmap__read_head(md);
1104 unsigned int old = md->prev; 1105 unsigned int old = md->prev;
1105 unsigned char *data = md->base + page_size; 1106 unsigned char *data = md->base + page_size;
@@ -1153,7 +1154,7 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
1153 1154
1154 event__parse_sample(event, self, &sample); 1155 event__parse_sample(event, self, &sample);
1155 if (event->header.type == PERF_RECORD_SAMPLE) 1156 if (event->header.type == PERF_RECORD_SAMPLE)
1156 event__process_sample(event, &sample, self, evsel); 1157 event__process_sample(event, &sample, self);
1157 else 1158 else
1158 event__process(event, &sample, self); 1159 event__process(event, &sample, self);
1159 old += size; 1160 old += size;
@@ -1164,19 +1165,10 @@ static void perf_session__mmap_read_counter(struct perf_session *self,
1164 1165
1165static void perf_session__mmap_read(struct perf_session *self) 1166static void perf_session__mmap_read(struct perf_session *self)
1166{ 1167{
1167 struct perf_evsel *counter; 1168 int i;
1168 int i, thread_index; 1169
1169 1170 for (i = 0; i < cpus->nr; i++)
1170 for (i = 0; i < cpus->nr; i++) { 1171 perf_session__mmap_read_cpu(self, i);
1171 list_for_each_entry(counter, &evsel_list->entries, node) {
1172 for (thread_index = 0;
1173 thread_index < threads->nr;
1174 thread_index++) {
1175 perf_session__mmap_read_counter(self,
1176 counter, i, thread_index);
1177 }
1178 }
1179 }
1180} 1172}
1181 1173
1182static void start_counters(struct perf_evlist *evlist) 1174static void start_counters(struct perf_evlist *evlist)
@@ -1194,6 +1186,11 @@ static void start_counters(struct perf_evlist *evlist)
1194 attr->sample_freq = freq; 1186 attr->sample_freq = freq;
1195 } 1187 }
1196 1188
1189 if (evlist->nr_entries > 1) {
1190 attr->sample_type |= PERF_SAMPLE_ID;
1191 attr->read_format |= PERF_FORMAT_ID;
1192 }
1193
1197 attr->mmap = 1; 1194 attr->mmap = 1;
1198try_again: 1195try_again:
1199 if (perf_evsel__open(counter, cpus, threads, group, inherit) < 0) { 1196 if (perf_evsel__open(counter, cpus, threads, group, inherit) < 0) {
@@ -1225,15 +1222,16 @@ try_again:
1225 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 1222 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
1226 exit(-1); 1223 exit(-1);
1227 } 1224 }
1228
1229 if (perf_evsel__mmap(counter, cpus, threads, mmap_pages, evlist) < 0)
1230 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
1231 } 1225 }
1226
1227 if (perf_evlist__mmap(evlist, cpus, threads, mmap_pages, true) < 0)
1228 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
1232} 1229}
1233 1230
1234static int __cmd_top(void) 1231static int __cmd_top(void)
1235{ 1232{
1236 pthread_t thread; 1233 pthread_t thread;
1234 struct perf_evsel *first;
1237 int ret; 1235 int ret;
1238 /* 1236 /*
1239 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this 1237 * FIXME: perf_session__new should allow passing a O_MMAP, so that all this
@@ -1249,6 +1247,8 @@ static int __cmd_top(void)
1249 event__synthesize_threads(event__process, session); 1247 event__synthesize_threads(event__process, session);
1250 1248
1251 start_counters(evsel_list); 1249 start_counters(evsel_list);
1250 first = list_entry(evsel_list->entries.next, struct perf_evsel, node);
1251 perf_session__set_sample_type(session, first->attr.sample_type);
1252 1252
1253 /* Wait for a minimal set of events before starting the snapshot */ 1253 /* Wait for a minimal set of events before starting the snapshot */
1254 poll(evsel_list->pollfd, evsel_list->nr_fds, 100); 1254 poll(evsel_list->pollfd, evsel_list->nr_fds, 100);
@@ -1394,8 +1394,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1394 usage_with_options(top_usage, options); 1394 usage_with_options(top_usage, options);
1395 1395
1396 list_for_each_entry(pos, &evsel_list->entries, node) { 1396 list_for_each_entry(pos, &evsel_list->entries, node) {
1397 if (perf_evsel__alloc_mmap(pos, cpus->nr, threads->nr) < 0 || 1397 if (perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
1398 perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0)
1399 goto out_free_fd; 1398 goto out_free_fd;
1400 /* 1399 /*
1401 * Fill in the ones not specifically initialized via -c: 1400 * Fill in the ones not specifically initialized via -c:
@@ -1406,7 +1405,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __used)
1406 pos->attr.sample_period = default_interval; 1405 pos->attr.sample_period = default_interval;
1407 } 1406 }
1408 1407
1409 if (perf_evlist__alloc_pollfd(evsel_list, cpus->nr, threads->nr) < 0) 1408 if (perf_evlist__alloc_pollfd(evsel_list, cpus->nr, threads->nr) < 0 ||
1409 perf_evlist__alloc_mmap(evsel_list, cpus->nr) < 0)
1410 goto out_free_fd; 1410 goto out_free_fd;
1411 1411
1412 sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node); 1412 sym_evsel = list_entry(evsel_list->entries.next, struct perf_evsel, node);