aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c72
1 files changed, 25 insertions, 47 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index cb46c7d0ea9..9bc89050e6f 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -25,6 +25,7 @@
25 25
26#include <unistd.h> 26#include <unistd.h>
27#include <sched.h> 27#include <sched.h>
28#include <sys/mman.h>
28 29
29enum write_mode_t { 30enum write_mode_t {
30 WRITE_FORCE, 31 WRITE_FORCE,
@@ -60,13 +61,8 @@ static bool call_graph = false;
60static bool inherit_stat = false; 61static bool inherit_stat = false;
61static bool no_samples = false; 62static bool no_samples = false;
62static bool sample_address = false; 63static bool sample_address = false;
63static bool multiplex = false;
64static int multiplex_fd = -1;
65 64
66static long samples = 0; 65static long samples = 0;
67static struct timeval last_read;
68static struct timeval this_read;
69
70static u64 bytes_written = 0; 66static u64 bytes_written = 0;
71 67
72static struct pollfd *event_array; 68static struct pollfd *event_array;
@@ -86,7 +82,7 @@ struct mmap_data {
86 unsigned int prev; 82 unsigned int prev;
87}; 83};
88 84
89static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; 85static struct mmap_data mmap_array[MAX_NR_CPUS];
90 86
91static unsigned long mmap_read_head(struct mmap_data *md) 87static unsigned long mmap_read_head(struct mmap_data *md)
92{ 88{
@@ -146,8 +142,6 @@ static void mmap_read(struct mmap_data *md)
146 void *buf; 142 void *buf;
147 int diff; 143 int diff;
148 144
149 gettimeofday(&this_read, NULL);
150
151 /* 145 /*
152 * If we're further behind than half the buffer, there's a chance 146 * If we're further behind than half the buffer, there's a chance
153 * the writer will bite our tail and mess up the samples under us. 147 * the writer will bite our tail and mess up the samples under us.
@@ -158,23 +152,13 @@ static void mmap_read(struct mmap_data *md)
158 */ 152 */
159 diff = head - old; 153 diff = head - old;
160 if (diff < 0) { 154 if (diff < 0) {
161 struct timeval iv; 155 fprintf(stderr, "WARNING: failed to keep up with mmap data\n");
162 unsigned long msecs;
163
164 timersub(&this_read, &last_read, &iv);
165 msecs = iv.tv_sec*1000 + iv.tv_usec/1000;
166
167 fprintf(stderr, "WARNING: failed to keep up with mmap data."
168 " Last read %lu msecs ago.\n", msecs);
169
170 /* 156 /*
171 * head points to a known good entry, start there. 157 * head points to a known good entry, start there.
172 */ 158 */
173 old = head; 159 old = head;
174 } 160 }
175 161
176 last_read = this_read;
177
178 if (old != head) 162 if (old != head)
179 samples++; 163 samples++;
180 164
@@ -380,27 +364,30 @@ try_again:
380 */ 364 */
381 if (group && group_fd == -1) 365 if (group && group_fd == -1)
382 group_fd = fd[nr_cpu][counter][thread_index]; 366 group_fd = fd[nr_cpu][counter][thread_index];
383 if (multiplex && multiplex_fd == -1)
384 multiplex_fd = fd[nr_cpu][counter][thread_index];
385 367
386 if (multiplex && fd[nr_cpu][counter][thread_index] != multiplex_fd) { 368 if (counter || thread_index) {
387 369 ret = ioctl(fd[nr_cpu][counter][thread_index],
388 ret = ioctl(fd[nr_cpu][counter][thread_index], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd); 370 PERF_EVENT_IOC_SET_OUTPUT,
389 assert(ret != -1); 371 fd[nr_cpu][0][0]);
372 if (ret) {
373 error("failed to set output: %d (%s)\n", errno,
374 strerror(errno));
375 exit(-1);
376 }
390 } else { 377 } else {
391 event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index]; 378 mmap_array[nr_cpu].counter = counter;
392 event_array[nr_poll].events = POLLIN; 379 mmap_array[nr_cpu].prev = 0;
393 nr_poll++; 380 mmap_array[nr_cpu].mask = mmap_pages*page_size - 1;
394 381 mmap_array[nr_cpu].base = mmap(NULL, (mmap_pages+1)*page_size,
395 mmap_array[nr_cpu][counter][thread_index].counter = counter;
396 mmap_array[nr_cpu][counter][thread_index].prev = 0;
397 mmap_array[nr_cpu][counter][thread_index].mask = mmap_pages*page_size - 1;
398 mmap_array[nr_cpu][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
399 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0); 382 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0);
400 if (mmap_array[nr_cpu][counter][thread_index].base == MAP_FAILED) { 383 if (mmap_array[nr_cpu].base == MAP_FAILED) {
401 error("failed to mmap with %d (%s)\n", errno, strerror(errno)); 384 error("failed to mmap with %d (%s)\n", errno, strerror(errno));
402 exit(-1); 385 exit(-1);
403 } 386 }
387
388 event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index];
389 event_array[nr_poll].events = POLLIN;
390 nr_poll++;
404 } 391 }
405 392
406 if (filter != NULL) { 393 if (filter != NULL) {
@@ -501,16 +488,11 @@ static struct perf_event_header finished_round_event = {
501 488
502static void mmap_read_all(void) 489static void mmap_read_all(void)
503{ 490{
504 int i, counter, thread; 491 int i;
505 492
506 for (i = 0; i < nr_cpu; i++) { 493 for (i = 0; i < nr_cpu; i++) {
507 for (counter = 0; counter < nr_counters; counter++) { 494 if (mmap_array[i].base)
508 for (thread = 0; thread < thread_num; thread++) { 495 mmap_read(&mmap_array[i]);
509 if (mmap_array[i][counter][thread].base)
510 mmap_read(&mmap_array[i][counter][thread]);
511 }
512
513 }
514 } 496 }
515 497
516 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO)) 498 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
@@ -834,8 +816,6 @@ static const struct option options[] = {
834 "Sample addresses"), 816 "Sample addresses"),
835 OPT_BOOLEAN('n', "no-samples", &no_samples, 817 OPT_BOOLEAN('n', "no-samples", &no_samples,
836 "don't sample"), 818 "don't sample"),
837 OPT_BOOLEAN('M', "multiplex", &multiplex,
838 "multiplex counter output in a single channel"),
839 OPT_END() 819 OPT_END()
840}; 820};
841 821
@@ -887,9 +867,7 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
887 for (i = 0; i < MAX_NR_CPUS; i++) { 867 for (i = 0; i < MAX_NR_CPUS; i++) {
888 for (j = 0; j < MAX_COUNTERS; j++) { 868 for (j = 0; j < MAX_COUNTERS; j++) {
889 fd[i][j] = malloc(sizeof(int)*thread_num); 869 fd[i][j] = malloc(sizeof(int)*thread_num);
890 mmap_array[i][j] = zalloc( 870 if (!fd[i][j])
891 sizeof(struct mmap_data)*thread_num);
892 if (!fd[i][j] || !mmap_array[i][j])
893 return -ENOMEM; 871 return -ENOMEM;
894 } 872 }
895 } 873 }