diff options
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r-- | tools/perf/builtin-record.c | 101 |
1 files changed, 35 insertions, 66 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index d40a81e8cc5..6febcc168a8 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <sys/mman.h> | 31 | #include <sys/mman.h> |
32 | 32 | ||
33 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 33 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
34 | #define SID(e, x, y) xyarray__entry(e->id, x, y) | ||
35 | 34 | ||
36 | enum write_mode_t { | 35 | enum write_mode_t { |
37 | WRITE_FORCE, | 36 | WRITE_FORCE, |
@@ -40,7 +39,6 @@ enum write_mode_t { | |||
40 | 39 | ||
41 | static u64 user_interval = ULLONG_MAX; | 40 | static u64 user_interval = ULLONG_MAX; |
42 | static u64 default_interval = 0; | 41 | static u64 default_interval = 0; |
43 | static u64 sample_type; | ||
44 | 42 | ||
45 | static unsigned int page_size; | 43 | static unsigned int page_size; |
46 | static unsigned int mmap_pages = 128; | 44 | static unsigned int mmap_pages = 128; |
@@ -160,54 +158,6 @@ static void sig_atexit(void) | |||
160 | kill(getpid(), signr); | 158 | kill(getpid(), signr); |
161 | } | 159 | } |
162 | 160 | ||
163 | static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int nr) | ||
164 | { | ||
165 | struct perf_header_attr *h_attr; | ||
166 | |||
167 | if (nr < session->header.attrs) { | ||
168 | h_attr = session->header.attr[nr]; | ||
169 | } else { | ||
170 | h_attr = perf_header_attr__new(a); | ||
171 | if (h_attr != NULL) | ||
172 | if (perf_header__add_attr(&session->header, h_attr) < 0) { | ||
173 | perf_header_attr__delete(h_attr); | ||
174 | h_attr = NULL; | ||
175 | } | ||
176 | } | ||
177 | |||
178 | return h_attr; | ||
179 | } | ||
180 | |||
181 | static void create_counter(struct perf_evsel *evsel, int cpu) | ||
182 | { | ||
183 | struct perf_event_attr *attr = &evsel->attr; | ||
184 | struct perf_header_attr *h_attr; | ||
185 | struct perf_sample_id *sid; | ||
186 | int thread_index; | ||
187 | |||
188 | for (thread_index = 0; thread_index < evsel_list->threads->nr; thread_index++) { | ||
189 | h_attr = get_header_attr(attr, evsel->idx); | ||
190 | if (h_attr == NULL) | ||
191 | die("nomem\n"); | ||
192 | |||
193 | if (!file_new) { | ||
194 | if (memcmp(&h_attr->attr, attr, sizeof(*attr))) { | ||
195 | fprintf(stderr, "incompatible append\n"); | ||
196 | exit(-1); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | sid = SID(evsel, cpu, thread_index); | ||
201 | if (perf_header_attr__add_id(h_attr, sid->id) < 0) { | ||
202 | pr_warning("Not enough memory to add id\n"); | ||
203 | exit(-1); | ||
204 | } | ||
205 | } | ||
206 | |||
207 | if (!sample_type) | ||
208 | sample_type = attr->sample_type; | ||
209 | } | ||
210 | |||
211 | static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) | 161 | static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) |
212 | { | 162 | { |
213 | struct perf_event_attr *attr = &evsel->attr; | 163 | struct perf_event_attr *attr = &evsel->attr; |
@@ -278,10 +228,28 @@ static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) | |||
278 | } | 228 | } |
279 | } | 229 | } |
280 | 230 | ||
231 | static bool perf_evlist__equal(struct perf_evlist *evlist, | ||
232 | struct perf_evlist *other) | ||
233 | { | ||
234 | struct perf_evsel *pos, *pair; | ||
235 | |||
236 | if (evlist->nr_entries != other->nr_entries) | ||
237 | return false; | ||
238 | |||
239 | pair = list_entry(other->entries.next, struct perf_evsel, node); | ||
240 | |||
241 | list_for_each_entry(pos, &evlist->entries, node) { | ||
242 | if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0)) | ||
243 | return false; | ||
244 | pair = list_entry(pair->node.next, struct perf_evsel, node); | ||
245 | } | ||
246 | |||
247 | return true; | ||
248 | } | ||
249 | |||
281 | static void open_counters(struct perf_evlist *evlist) | 250 | static void open_counters(struct perf_evlist *evlist) |
282 | { | 251 | { |
283 | struct perf_evsel *pos; | 252 | struct perf_evsel *pos; |
284 | int cpu; | ||
285 | 253 | ||
286 | list_for_each_entry(pos, &evlist->entries, node) { | 254 | list_for_each_entry(pos, &evlist->entries, node) { |
287 | struct perf_event_attr *attr = &pos->attr; | 255 | struct perf_event_attr *attr = &pos->attr; |
@@ -364,10 +332,16 @@ try_again: | |||
364 | if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) | 332 | if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) |
365 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); | 333 | die("failed to mmap with %d (%s)\n", errno, strerror(errno)); |
366 | 334 | ||
367 | for (cpu = 0; cpu < evsel_list->cpus->nr; ++cpu) { | 335 | if (file_new) |
368 | list_for_each_entry(pos, &evlist->entries, node) | 336 | session->evlist = evlist; |
369 | create_counter(pos, cpu); | 337 | else { |
370 | } | 338 | if (!perf_evlist__equal(session->evlist, evlist)) { |
339 | fprintf(stderr, "incompatible append\n"); | ||
340 | exit(-1); | ||
341 | } | ||
342 | } | ||
343 | |||
344 | perf_session__update_sample_type(session); | ||
371 | } | 345 | } |
372 | 346 | ||
373 | static int process_buildids(void) | 347 | static int process_buildids(void) |
@@ -390,7 +364,7 @@ static void atexit_header(void) | |||
390 | 364 | ||
391 | if (!no_buildid) | 365 | if (!no_buildid) |
392 | process_buildids(); | 366 | process_buildids(); |
393 | perf_header__write(&session->header, evsel_list, output, true); | 367 | perf_session__write_header(session, evsel_list, output, true); |
394 | perf_session__delete(session); | 368 | perf_session__delete(session); |
395 | perf_evlist__delete(evsel_list); | 369 | perf_evlist__delete(evsel_list); |
396 | symbol__exit(); | 370 | symbol__exit(); |
@@ -524,7 +498,7 @@ static int __cmd_record(int argc, const char **argv) | |||
524 | perf_header__set_feat(&session->header, HEADER_BUILD_ID); | 498 | perf_header__set_feat(&session->header, HEADER_BUILD_ID); |
525 | 499 | ||
526 | if (!file_new) { | 500 | if (!file_new) { |
527 | err = perf_header__read(session, output); | 501 | err = perf_session__read_header(session, output); |
528 | if (err < 0) | 502 | if (err < 0) |
529 | goto out_delete_session; | 503 | goto out_delete_session; |
530 | } | 504 | } |
@@ -588,8 +562,6 @@ static int __cmd_record(int argc, const char **argv) | |||
588 | 562 | ||
589 | open_counters(evsel_list); | 563 | open_counters(evsel_list); |
590 | 564 | ||
591 | perf_session__set_sample_type(session, sample_type); | ||
592 | |||
593 | /* | 565 | /* |
594 | * perf_session__delete(session) will be called at atexit_header() | 566 | * perf_session__delete(session) will be called at atexit_header() |
595 | */ | 567 | */ |
@@ -600,20 +572,17 @@ static int __cmd_record(int argc, const char **argv) | |||
600 | if (err < 0) | 572 | if (err < 0) |
601 | return err; | 573 | return err; |
602 | } else if (file_new) { | 574 | } else if (file_new) { |
603 | err = perf_header__write(&session->header, evsel_list, | 575 | err = perf_session__write_header(session, evsel_list, |
604 | output, false); | 576 | output, false); |
605 | if (err < 0) | 577 | if (err < 0) |
606 | return err; | 578 | return err; |
607 | } | 579 | } |
608 | 580 | ||
609 | post_processing_offset = lseek(output, 0, SEEK_CUR); | 581 | post_processing_offset = lseek(output, 0, SEEK_CUR); |
610 | 582 | ||
611 | perf_session__set_sample_id_all(session, sample_id_all_avail); | ||
612 | |||
613 | if (pipe_output) { | 583 | if (pipe_output) { |
614 | err = perf_event__synthesize_attrs(&session->header, | 584 | err = perf_session__synthesize_attrs(session, |
615 | process_synthesized_event, | 585 | process_synthesized_event); |
616 | session); | ||
617 | if (err < 0) { | 586 | if (err < 0) { |
618 | pr_err("Couldn't synthesize attrs.\n"); | 587 | pr_err("Couldn't synthesize attrs.\n"); |
619 | return err; | 588 | return err; |