diff options
author | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-12 14:03:24 -0500 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2011-01-22 16:56:29 -0500 |
commit | 70082dd92c4b288bd723a77897e2b555f0e63113 (patch) | |
tree | 907a2d78fcaabc28cd4d034901e0eac800d1ed17 /tools/perf/builtin-top.c | |
parent | dd7927f4f8ee75b032ff15aeef4bda49719a443a (diff) |
perf evsel: Introduce mmap support
Out of the code in 'perf top'. Record is next in line.
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 | 71 |
1 files changed, 5 insertions, 66 deletions
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 15d89bede2f..7d723ad0bfa 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -1095,43 +1095,12 @@ static void event__process_sample(const event_t *self, | |||
1095 | } | 1095 | } |
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | struct mmap_data { | ||
1099 | void *base; | ||
1100 | int mask; | ||
1101 | unsigned int prev; | ||
1102 | }; | ||
1103 | |||
1104 | static int perf_evsel__alloc_mmap_per_thread(struct perf_evsel *evsel, | ||
1105 | int ncpus, int nthreads) | ||
1106 | { | ||
1107 | evsel->priv = xyarray__new(ncpus, nthreads, sizeof(struct mmap_data)); | ||
1108 | return evsel->priv != NULL ? 0 : -ENOMEM; | ||
1109 | } | ||
1110 | |||
1111 | static void perf_evsel__free_mmap(struct perf_evsel *evsel) | ||
1112 | { | ||
1113 | xyarray__delete(evsel->priv); | ||
1114 | evsel->priv = NULL; | ||
1115 | } | ||
1116 | |||
1117 | static unsigned int mmap_read_head(struct mmap_data *md) | ||
1118 | { | ||
1119 | struct perf_event_mmap_page *pc = md->base; | ||
1120 | int head; | ||
1121 | |||
1122 | head = pc->data_head; | ||
1123 | rmb(); | ||
1124 | |||
1125 | return head; | ||
1126 | } | ||
1127 | |||
1128 | static void perf_session__mmap_read_counter(struct perf_session *self, | 1098 | static void perf_session__mmap_read_counter(struct perf_session *self, |
1129 | struct perf_evsel *evsel, | 1099 | struct perf_evsel *evsel, |
1130 | int cpu, int thread_idx) | 1100 | int cpu, int thread_idx) |
1131 | { | 1101 | { |
1132 | struct xyarray *mmap_array = evsel->priv; | 1102 | struct perf_mmap *md = xyarray__entry(evsel->mmap, cpu, thread_idx); |
1133 | struct mmap_data *md = xyarray__entry(mmap_array, cpu, thread_idx); | 1103 | unsigned int head = perf_mmap__read_head(md); |
1134 | unsigned int head = mmap_read_head(md); | ||
1135 | unsigned int old = md->prev; | 1104 | unsigned int old = md->prev; |
1136 | unsigned char *data = md->base + page_size; | 1105 | unsigned char *data = md->base + page_size; |
1137 | struct sample_data sample; | 1106 | struct sample_data sample; |
@@ -1210,35 +1179,9 @@ static void perf_session__mmap_read(struct perf_session *self) | |||
1210 | } | 1179 | } |
1211 | } | 1180 | } |
1212 | 1181 | ||
1213 | static void start_counter(int i, struct perf_evlist *evlist, | ||
1214 | struct perf_evsel *evsel) | ||
1215 | { | ||
1216 | struct xyarray *mmap_array = evsel->priv; | ||
1217 | struct mmap_data *mm; | ||
1218 | int thread_index; | ||
1219 | |||
1220 | for (thread_index = 0; thread_index < threads->nr; thread_index++) { | ||
1221 | assert(FD(evsel, i, thread_index) >= 0); | ||
1222 | fcntl(FD(evsel, i, thread_index), F_SETFL, O_NONBLOCK); | ||
1223 | |||
1224 | evlist->pollfd[evlist->nr_fds].fd = FD(evsel, i, thread_index); | ||
1225 | evlist->pollfd[evlist->nr_fds].events = POLLIN; | ||
1226 | evlist->nr_fds++; | ||
1227 | |||
1228 | mm = xyarray__entry(mmap_array, i, thread_index); | ||
1229 | mm->prev = 0; | ||
1230 | mm->mask = mmap_pages*page_size - 1; | ||
1231 | mm->base = mmap(NULL, (mmap_pages+1)*page_size, | ||
1232 | PROT_READ, MAP_SHARED, FD(evsel, i, thread_index), 0); | ||
1233 | if (mm->base == MAP_FAILED) | ||
1234 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | ||
1235 | } | ||
1236 | } | ||
1237 | |||
1238 | static void start_counters(struct perf_evlist *evlist) | 1182 | static void start_counters(struct perf_evlist *evlist) |
1239 | { | 1183 | { |
1240 | struct perf_evsel *counter; | 1184 | struct perf_evsel *counter; |
1241 | int i; | ||
1242 | 1185 | ||
1243 | list_for_each_entry(counter, &evlist->entries, node) { | 1186 | list_for_each_entry(counter, &evlist->entries, node) { |
1244 | struct perf_event_attr *attr = &counter->attr; | 1187 | struct perf_event_attr *attr = &counter->attr; |
@@ -1282,11 +1225,9 @@ try_again: | |||
1282 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); | 1225 | die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); |
1283 | exit(-1); | 1226 | exit(-1); |
1284 | } | 1227 | } |
1285 | } | ||
1286 | 1228 | ||
1287 | for (i = 0; i < cpus->nr; i++) { | 1229 | if (perf_evsel__mmap(counter, cpus, threads, mmap_pages, evlist) < 0) |
1288 | list_for_each_entry(counter, &evlist->entries, node) | 1230 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); |
1289 | start_counter(i, evsel_list, counter); | ||
1290 | } | 1231 | } |
1291 | } | 1232 | } |
1292 | 1233 | ||
@@ -1453,7 +1394,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1453 | usage_with_options(top_usage, options); | 1394 | usage_with_options(top_usage, options); |
1454 | 1395 | ||
1455 | list_for_each_entry(pos, &evsel_list->entries, node) { | 1396 | list_for_each_entry(pos, &evsel_list->entries, node) { |
1456 | if (perf_evsel__alloc_mmap_per_thread(pos, cpus->nr, threads->nr) < 0 || | 1397 | if (perf_evsel__alloc_mmap(pos, cpus->nr, threads->nr) < 0 || |
1457 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) | 1398 | perf_evsel__alloc_fd(pos, cpus->nr, threads->nr) < 0) |
1458 | goto out_free_fd; | 1399 | goto out_free_fd; |
1459 | /* | 1400 | /* |
@@ -1485,8 +1426,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __used) | |||
1485 | 1426 | ||
1486 | status = __cmd_top(); | 1427 | status = __cmd_top(); |
1487 | out_free_fd: | 1428 | out_free_fd: |
1488 | list_for_each_entry(pos, &evsel_list->entries, node) | ||
1489 | perf_evsel__free_mmap(pos); | ||
1490 | perf_evlist__delete(evsel_list); | 1429 | perf_evlist__delete(evsel_list); |
1491 | 1430 | ||
1492 | return status; | 1431 | return status; |