diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r-- | tools/perf/builtin-record.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index e1dfef24887f..06fdfb8b4828 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -78,10 +78,10 @@ struct mmap_data { | |||
78 | 78 | ||
79 | static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; | 79 | static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; |
80 | 80 | ||
81 | static unsigned int mmap_read_head(struct mmap_data *md) | 81 | static unsigned long mmap_read_head(struct mmap_data *md) |
82 | { | 82 | { |
83 | struct perf_counter_mmap_page *pc = md->base; | 83 | struct perf_counter_mmap_page *pc = md->base; |
84 | int head; | 84 | long head; |
85 | 85 | ||
86 | head = pc->data_head; | 86 | head = pc->data_head; |
87 | rmb(); | 87 | rmb(); |
@@ -89,6 +89,17 @@ static unsigned int mmap_read_head(struct mmap_data *md) | |||
89 | return head; | 89 | return head; |
90 | } | 90 | } |
91 | 91 | ||
92 | static void mmap_write_tail(struct mmap_data *md, unsigned long tail) | ||
93 | { | ||
94 | struct perf_counter_mmap_page *pc = md->base; | ||
95 | |||
96 | /* | ||
97 | * ensure all reads are done before we write the tail out. | ||
98 | */ | ||
99 | /* mb(); */ | ||
100 | pc->data_tail = tail; | ||
101 | } | ||
102 | |||
92 | static void mmap_read(struct mmap_data *md) | 103 | static void mmap_read(struct mmap_data *md) |
93 | { | 104 | { |
94 | unsigned int head = mmap_read_head(md); | 105 | unsigned int head = mmap_read_head(md); |
@@ -109,7 +120,7 @@ static void mmap_read(struct mmap_data *md) | |||
109 | * In either case, truncate and restart at head. | 120 | * In either case, truncate and restart at head. |
110 | */ | 121 | */ |
111 | diff = head - old; | 122 | diff = head - old; |
112 | if (diff > md->mask / 2 || diff < 0) { | 123 | if (diff < 0) { |
113 | struct timeval iv; | 124 | struct timeval iv; |
114 | unsigned long msecs; | 125 | unsigned long msecs; |
115 | 126 | ||
@@ -167,6 +178,7 @@ static void mmap_read(struct mmap_data *md) | |||
167 | } | 178 | } |
168 | 179 | ||
169 | md->prev = old; | 180 | md->prev = old; |
181 | mmap_write_tail(md, old); | ||
170 | } | 182 | } |
171 | 183 | ||
172 | static volatile int done = 0; | 184 | static volatile int done = 0; |
@@ -424,7 +436,7 @@ try_again: | |||
424 | mmap_array[nr_cpu][counter].prev = 0; | 436 | mmap_array[nr_cpu][counter].prev = 0; |
425 | mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1; | 437 | mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1; |
426 | mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size, | 438 | mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size, |
427 | PROT_READ, MAP_SHARED, fd[nr_cpu][counter], 0); | 439 | PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0); |
428 | if (mmap_array[nr_cpu][counter].base == MAP_FAILED) { | 440 | if (mmap_array[nr_cpu][counter].base == MAP_FAILED) { |
429 | error("failed to mmap with %d (%s)\n", errno, strerror(errno)); | 441 | error("failed to mmap with %d (%s)\n", errno, strerror(errno)); |
430 | exit(-1); | 442 | exit(-1); |