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.c546
1 files changed, 368 insertions, 178 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index f1411e9cdf47..cb46c7d0ea99 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -15,7 +15,6 @@
15#include "util/util.h" 15#include "util/util.h"
16#include "util/parse-options.h" 16#include "util/parse-options.h"
17#include "util/parse-events.h" 17#include "util/parse-events.h"
18#include "util/string.h"
19 18
20#include "util/header.h" 19#include "util/header.h"
21#include "util/event.h" 20#include "util/event.h"
@@ -27,31 +26,41 @@
27#include <unistd.h> 26#include <unistd.h>
28#include <sched.h> 27#include <sched.h>
29 28
30static int fd[MAX_NR_CPUS][MAX_COUNTERS]; 29enum write_mode_t {
30 WRITE_FORCE,
31 WRITE_APPEND
32};
33
34static int *fd[MAX_NR_CPUS][MAX_COUNTERS];
31 35
32static long default_interval = 0; 36static u64 user_interval = ULLONG_MAX;
37static u64 default_interval = 0;
33 38
34static int nr_cpus = 0; 39static int nr_cpus = 0;
35static unsigned int page_size; 40static unsigned int page_size;
36static unsigned int mmap_pages = 128; 41static unsigned int mmap_pages = 128;
42static unsigned int user_freq = UINT_MAX;
37static int freq = 1000; 43static int freq = 1000;
38static int output; 44static int output;
45static int pipe_output = 0;
39static const char *output_name = "perf.data"; 46static const char *output_name = "perf.data";
40static int group = 0; 47static int group = 0;
41static unsigned int realtime_prio = 0; 48static int realtime_prio = 0;
42static int raw_samples = 0; 49static bool raw_samples = false;
43static int system_wide = 0; 50static bool system_wide = false;
44static int profile_cpu = -1; 51static int profile_cpu = -1;
45static pid_t target_pid = -1; 52static pid_t target_pid = -1;
53static pid_t target_tid = -1;
54static pid_t *all_tids = NULL;
55static int thread_num = 0;
46static pid_t child_pid = -1; 56static pid_t child_pid = -1;
47static int inherit = 1; 57static bool no_inherit = false;
48static int force = 0; 58static enum write_mode_t write_mode = WRITE_FORCE;
49static int append_file = 0; 59static bool call_graph = false;
50static int call_graph = 0; 60static bool inherit_stat = false;
51static int inherit_stat = 0; 61static bool no_samples = false;
52static int no_samples = 0; 62static bool sample_address = false;
53static int sample_address = 0; 63static bool multiplex = false;
54static int multiplex = 0;
55static int multiplex_fd = -1; 64static int multiplex_fd = -1;
56 65
57static long samples = 0; 66static long samples = 0;
@@ -60,7 +69,7 @@ static struct timeval this_read;
60 69
61static u64 bytes_written = 0; 70static u64 bytes_written = 0;
62 71
63static struct pollfd event_array[MAX_NR_CPUS * MAX_COUNTERS]; 72static struct pollfd *event_array;
64 73
65static int nr_poll = 0; 74static int nr_poll = 0;
66static int nr_cpu = 0; 75static int nr_cpu = 0;
@@ -77,7 +86,7 @@ struct mmap_data {
77 unsigned int prev; 86 unsigned int prev;
78}; 87};
79 88
80static struct mmap_data mmap_array[MAX_NR_CPUS][MAX_COUNTERS]; 89static struct mmap_data *mmap_array[MAX_NR_CPUS][MAX_COUNTERS];
81 90
82static unsigned long mmap_read_head(struct mmap_data *md) 91static unsigned long mmap_read_head(struct mmap_data *md)
83{ 92{
@@ -101,6 +110,11 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
101 pc->data_tail = tail; 110 pc->data_tail = tail;
102} 111}
103 112
113static void advance_output(size_t size)
114{
115 bytes_written += size;
116}
117
104static void write_output(void *buf, size_t size) 118static void write_output(void *buf, size_t size)
105{ 119{
106 while (size) { 120 while (size) {
@@ -225,12 +239,13 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
225 return h_attr; 239 return h_attr;
226} 240}
227 241
228static void create_counter(int counter, int cpu, pid_t pid) 242static void create_counter(int counter, int cpu)
229{ 243{
230 char *filter = filters[counter]; 244 char *filter = filters[counter];
231 struct perf_event_attr *attr = attrs + counter; 245 struct perf_event_attr *attr = attrs + counter;
232 struct perf_header_attr *h_attr; 246 struct perf_header_attr *h_attr;
233 int track = !counter; /* only the first counter needs these */ 247 int track = !counter; /* only the first counter needs these */
248 int thread_index;
234 int ret; 249 int ret;
235 struct { 250 struct {
236 u64 count; 251 u64 count;
@@ -248,10 +263,19 @@ static void create_counter(int counter, int cpu, pid_t pid)
248 if (nr_counters > 1) 263 if (nr_counters > 1)
249 attr->sample_type |= PERF_SAMPLE_ID; 264 attr->sample_type |= PERF_SAMPLE_ID;
250 265
251 if (freq) { 266 /*
252 attr->sample_type |= PERF_SAMPLE_PERIOD; 267 * We default some events to a 1 default interval. But keep
253 attr->freq = 1; 268 * it a weak assumption overridable by the user.
254 attr->sample_freq = freq; 269 */
270 if (!attr->sample_period || (user_freq != UINT_MAX &&
271 user_interval != ULLONG_MAX)) {
272 if (freq) {
273 attr->sample_type |= PERF_SAMPLE_PERIOD;
274 attr->freq = 1;
275 attr->sample_freq = freq;
276 } else {
277 attr->sample_period = default_interval;
278 }
255 } 279 }
256 280
257 if (no_samples) 281 if (no_samples)
@@ -274,119 +298,130 @@ static void create_counter(int counter, int cpu, pid_t pid)
274 298
275 attr->mmap = track; 299 attr->mmap = track;
276 attr->comm = track; 300 attr->comm = track;
277 attr->inherit = inherit; 301 attr->inherit = !no_inherit;
278 attr->disabled = 1; 302 if (target_pid == -1 && target_tid == -1 && !system_wide) {
303 attr->disabled = 1;
304 attr->enable_on_exec = 1;
305 }
279 306
307 for (thread_index = 0; thread_index < thread_num; thread_index++) {
280try_again: 308try_again:
281 fd[nr_cpu][counter] = sys_perf_event_open(attr, pid, cpu, group_fd, 0); 309 fd[nr_cpu][counter][thread_index] = sys_perf_event_open(attr,
282 310 all_tids[thread_index], cpu, group_fd, 0);
283 if (fd[nr_cpu][counter] < 0) { 311
284 int err = errno; 312 if (fd[nr_cpu][counter][thread_index] < 0) {
285 313 int err = errno;
286 if (err == EPERM || err == EACCES) 314
287 die("Permission error - are you root?\n"); 315 if (err == EPERM || err == EACCES)
288 else if (err == ENODEV && profile_cpu != -1) 316 die("Permission error - are you root?\n"
289 die("No such device - did you specify an out-of-range profile CPU?\n"); 317 "\t Consider tweaking"
318 " /proc/sys/kernel/perf_event_paranoid.\n");
319 else if (err == ENODEV && profile_cpu != -1) {
320 die("No such device - did you specify"
321 " an out-of-range profile CPU?\n");
322 }
290 323
291 /* 324 /*
292 * If it's cycles then fall back to hrtimer 325 * If it's cycles then fall back to hrtimer
293 * based cpu-clock-tick sw counter, which 326 * based cpu-clock-tick sw counter, which
294 * is always available even if no PMU support: 327 * is always available even if no PMU support:
295 */ 328 */
296 if (attr->type == PERF_TYPE_HARDWARE 329 if (attr->type == PERF_TYPE_HARDWARE
297 && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 330 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
298 331
299 if (verbose) 332 if (verbose)
300 warning(" ... trying to fall back to cpu-clock-ticks\n"); 333 warning(" ... trying to fall back to cpu-clock-ticks\n");
301 attr->type = PERF_TYPE_SOFTWARE; 334 attr->type = PERF_TYPE_SOFTWARE;
302 attr->config = PERF_COUNT_SW_CPU_CLOCK; 335 attr->config = PERF_COUNT_SW_CPU_CLOCK;
303 goto try_again; 336 goto try_again;
304 } 337 }
305 printf("\n"); 338 printf("\n");
306 error("perfcounter syscall returned with %d (%s)\n", 339 error("perfcounter syscall returned with %d (%s)\n",
307 fd[nr_cpu][counter], strerror(err)); 340 fd[nr_cpu][counter][thread_index], strerror(err));
308 341
309#if defined(__i386__) || defined(__x86_64__) 342#if defined(__i386__) || defined(__x86_64__)
310 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) 343 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
311 die("No hardware sampling interrupt available. No APIC? If so then you can boot the kernel with the \"lapic\" boot parameter to force-enable it.\n"); 344 die("No hardware sampling interrupt available."
345 " No APIC? If so then you can boot the kernel"
346 " with the \"lapic\" boot parameter to"
347 " force-enable it.\n");
312#endif 348#endif
313 349
314 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 350 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
315 exit(-1); 351 exit(-1);
316 } 352 }
317 353
318 h_attr = get_header_attr(attr, counter); 354 h_attr = get_header_attr(attr, counter);
319 if (h_attr == NULL) 355 if (h_attr == NULL)
320 die("nomem\n"); 356 die("nomem\n");
321 357
322 if (!file_new) { 358 if (!file_new) {
323 if (memcmp(&h_attr->attr, attr, sizeof(*attr))) { 359 if (memcmp(&h_attr->attr, attr, sizeof(*attr))) {
324 fprintf(stderr, "incompatible append\n"); 360 fprintf(stderr, "incompatible append\n");
325 exit(-1); 361 exit(-1);
362 }
326 } 363 }
327 }
328 364
329 if (read(fd[nr_cpu][counter], &read_data, sizeof(read_data)) == -1) { 365 if (read(fd[nr_cpu][counter][thread_index], &read_data, sizeof(read_data)) == -1) {
330 perror("Unable to read perf file descriptor\n"); 366 perror("Unable to read perf file descriptor\n");
331 exit(-1); 367 exit(-1);
332 } 368 }
333 369
334 if (perf_header_attr__add_id(h_attr, read_data.id) < 0) { 370 if (perf_header_attr__add_id(h_attr, read_data.id) < 0) {
335 pr_warning("Not enough memory to add id\n"); 371 pr_warning("Not enough memory to add id\n");
336 exit(-1); 372 exit(-1);
337 } 373 }
338 374
339 assert(fd[nr_cpu][counter] >= 0); 375 assert(fd[nr_cpu][counter][thread_index] >= 0);
340 fcntl(fd[nr_cpu][counter], F_SETFL, O_NONBLOCK); 376 fcntl(fd[nr_cpu][counter][thread_index], F_SETFL, O_NONBLOCK);
341 377
342 /* 378 /*
343 * First counter acts as the group leader: 379 * First counter acts as the group leader:
344 */ 380 */
345 if (group && group_fd == -1) 381 if (group && group_fd == -1)
346 group_fd = fd[nr_cpu][counter]; 382 group_fd = fd[nr_cpu][counter][thread_index];
347 if (multiplex && multiplex_fd == -1) 383 if (multiplex && multiplex_fd == -1)
348 multiplex_fd = fd[nr_cpu][counter]; 384 multiplex_fd = fd[nr_cpu][counter][thread_index];
349 385
350 if (multiplex && fd[nr_cpu][counter] != multiplex_fd) { 386 if (multiplex && fd[nr_cpu][counter][thread_index] != multiplex_fd) {
351 387
352 ret = ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd); 388 ret = ioctl(fd[nr_cpu][counter][thread_index], PERF_EVENT_IOC_SET_OUTPUT, multiplex_fd);
353 assert(ret != -1); 389 assert(ret != -1);
354 } else { 390 } else {
355 event_array[nr_poll].fd = fd[nr_cpu][counter]; 391 event_array[nr_poll].fd = fd[nr_cpu][counter][thread_index];
356 event_array[nr_poll].events = POLLIN; 392 event_array[nr_poll].events = POLLIN;
357 nr_poll++; 393 nr_poll++;
358 394
359 mmap_array[nr_cpu][counter].counter = counter; 395 mmap_array[nr_cpu][counter][thread_index].counter = counter;
360 mmap_array[nr_cpu][counter].prev = 0; 396 mmap_array[nr_cpu][counter][thread_index].prev = 0;
361 mmap_array[nr_cpu][counter].mask = mmap_pages*page_size - 1; 397 mmap_array[nr_cpu][counter][thread_index].mask = mmap_pages*page_size - 1;
362 mmap_array[nr_cpu][counter].base = mmap(NULL, (mmap_pages+1)*page_size, 398 mmap_array[nr_cpu][counter][thread_index].base = mmap(NULL, (mmap_pages+1)*page_size,
363 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter], 0); 399 PROT_READ|PROT_WRITE, MAP_SHARED, fd[nr_cpu][counter][thread_index], 0);
364 if (mmap_array[nr_cpu][counter].base == MAP_FAILED) { 400 if (mmap_array[nr_cpu][counter][thread_index].base == MAP_FAILED) {
365 error("failed to mmap with %d (%s)\n", errno, strerror(errno)); 401 error("failed to mmap with %d (%s)\n", errno, strerror(errno));
366 exit(-1); 402 exit(-1);
403 }
367 } 404 }
368 }
369 405
370 if (filter != NULL) { 406 if (filter != NULL) {
371 ret = ioctl(fd[nr_cpu][counter], 407 ret = ioctl(fd[nr_cpu][counter][thread_index],
372 PERF_EVENT_IOC_SET_FILTER, filter); 408 PERF_EVENT_IOC_SET_FILTER, filter);
373 if (ret) { 409 if (ret) {
374 error("failed to set filter with %d (%s)\n", errno, 410 error("failed to set filter with %d (%s)\n", errno,
375 strerror(errno)); 411 strerror(errno));
376 exit(-1); 412 exit(-1);
413 }
377 } 414 }
378 } 415 }
379
380 ioctl(fd[nr_cpu][counter], PERF_EVENT_IOC_ENABLE);
381} 416}
382 417
383static void open_counters(int cpu, pid_t pid) 418static void open_counters(int cpu)
384{ 419{
385 int counter; 420 int counter;
386 421
387 group_fd = -1; 422 group_fd = -1;
388 for (counter = 0; counter < nr_counters; counter++) 423 for (counter = 0; counter < nr_counters; counter++)
389 create_counter(counter, cpu, pid); 424 create_counter(counter, cpu);
390 425
391 nr_cpu++; 426 nr_cpu++;
392} 427}
@@ -406,10 +441,80 @@ static int process_buildids(void)
406 441
407static void atexit_header(void) 442static void atexit_header(void)
408{ 443{
409 session->header.data_size += bytes_written; 444 if (!pipe_output) {
445 session->header.data_size += bytes_written;
446
447 process_buildids();
448 perf_header__write(&session->header, output, true);
449 }
450}
451
452static void event__synthesize_guest_os(struct machine *machine, void *data)
453{
454 int err;
455 char *guest_kallsyms;
456 char path[PATH_MAX];
457 struct perf_session *psession = data;
458
459 if (machine__is_host(machine))
460 return;
461
462 /*
463 *As for guest kernel when processing subcommand record&report,
464 *we arrange module mmap prior to guest kernel mmap and trigger
465 *a preload dso because default guest module symbols are loaded
466 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
467 *method is used to avoid symbol missing when the first addr is
468 *in module instead of in guest kernel.
469 */
470 err = event__synthesize_modules(process_synthesized_event,
471 psession, machine);
472 if (err < 0)
473 pr_err("Couldn't record guest kernel [%d]'s reference"
474 " relocation symbol.\n", machine->pid);
475
476 if (machine__is_default_guest(machine))
477 guest_kallsyms = (char *) symbol_conf.default_guest_kallsyms;
478 else {
479 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
480 guest_kallsyms = path;
481 }
482
483 /*
484 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
485 * have no _text sometimes.
486 */
487 err = event__synthesize_kernel_mmap(process_synthesized_event,
488 psession, machine, "_text");
489 if (err < 0)
490 err = event__synthesize_kernel_mmap(process_synthesized_event,
491 psession, machine, "_stext");
492 if (err < 0)
493 pr_err("Couldn't record guest kernel [%d]'s reference"
494 " relocation symbol.\n", machine->pid);
495}
496
497static struct perf_event_header finished_round_event = {
498 .size = sizeof(struct perf_event_header),
499 .type = PERF_RECORD_FINISHED_ROUND,
500};
501
502static void mmap_read_all(void)
503{
504 int i, counter, thread;
505
506 for (i = 0; i < nr_cpu; i++) {
507 for (counter = 0; counter < nr_counters; counter++) {
508 for (thread = 0; thread < thread_num; thread++) {
509 if (mmap_array[i][counter][thread].base)
510 mmap_read(&mmap_array[i][counter][thread]);
511 }
512
513 }
514 }
410 515
411 process_buildids(); 516 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
412 perf_header__write(&session->header, output, true); 517 write_output(&finished_round_event, sizeof(finished_round_event));
413} 518}
414 519
415static int __cmd_record(int argc, const char **argv) 520static int __cmd_record(int argc, const char **argv)
@@ -421,8 +526,9 @@ static int __cmd_record(int argc, const char **argv)
421 int err; 526 int err;
422 unsigned long waking = 0; 527 unsigned long waking = 0;
423 int child_ready_pipe[2], go_pipe[2]; 528 int child_ready_pipe[2], go_pipe[2];
424 const bool forks = target_pid == -1 && argc > 0; 529 const bool forks = argc > 0;
425 char buf; 530 char buf;
531 struct machine *machine;
426 532
427 page_size = sysconf(_SC_PAGE_SIZE); 533 page_size = sysconf(_SC_PAGE_SIZE);
428 534
@@ -435,70 +541,63 @@ static int __cmd_record(int argc, const char **argv)
435 exit(-1); 541 exit(-1);
436 } 542 }
437 543
438 if (!stat(output_name, &st) && st.st_size) { 544 if (!strcmp(output_name, "-"))
439 if (!force) { 545 pipe_output = 1;
440 if (!append_file) { 546 else if (!stat(output_name, &st) && st.st_size) {
441 pr_err("Error, output file %s exists, use -A " 547 if (write_mode == WRITE_FORCE) {
442 "to append or -f to overwrite.\n",
443 output_name);
444 exit(-1);
445 }
446 } else {
447 char oldname[PATH_MAX]; 548 char oldname[PATH_MAX];
448 snprintf(oldname, sizeof(oldname), "%s.old", 549 snprintf(oldname, sizeof(oldname), "%s.old",
449 output_name); 550 output_name);
450 unlink(oldname); 551 unlink(oldname);
451 rename(output_name, oldname); 552 rename(output_name, oldname);
452 } 553 }
453 } else { 554 } else if (write_mode == WRITE_APPEND) {
454 append_file = 0; 555 write_mode = WRITE_FORCE;
455 } 556 }
456 557
457 flags = O_CREAT|O_RDWR; 558 flags = O_CREAT|O_RDWR;
458 if (append_file) 559 if (write_mode == WRITE_APPEND)
459 file_new = 0; 560 file_new = 0;
460 else 561 else
461 flags |= O_TRUNC; 562 flags |= O_TRUNC;
462 563
463 output = open(output_name, flags, S_IRUSR|S_IWUSR); 564 if (pipe_output)
565 output = STDOUT_FILENO;
566 else
567 output = open(output_name, flags, S_IRUSR | S_IWUSR);
464 if (output < 0) { 568 if (output < 0) {
465 perror("failed to create output file"); 569 perror("failed to create output file");
466 exit(-1); 570 exit(-1);
467 } 571 }
468 572
469 session = perf_session__new(output_name, O_WRONLY, force); 573 session = perf_session__new(output_name, O_WRONLY,
574 write_mode == WRITE_FORCE, false);
470 if (session == NULL) { 575 if (session == NULL) {
471 pr_err("Not enough memory for reading perf file header\n"); 576 pr_err("Not enough memory for reading perf file header\n");
472 return -1; 577 return -1;
473 } 578 }
474 579
475 if (!file_new) { 580 if (!file_new) {
476 err = perf_header__read(&session->header, output); 581 err = perf_header__read(session, output);
477 if (err < 0) 582 if (err < 0)
478 return err; 583 return err;
479 } 584 }
480 585
481 if (raw_samples) { 586 if (have_tracepoints(attrs, nr_counters))
482 perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 587 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
483 } else {
484 for (i = 0; i < nr_counters; i++) {
485 if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
486 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
487 break;
488 }
489 }
490 }
491 588
492 atexit(atexit_header); 589 atexit(atexit_header);
493 590
494 if (forks) { 591 if (forks) {
495 pid = fork(); 592 child_pid = fork();
496 if (pid < 0) { 593 if (pid < 0) {
497 perror("failed to fork"); 594 perror("failed to fork");
498 exit(-1); 595 exit(-1);
499 } 596 }
500 597
501 if (!pid) { 598 if (!child_pid) {
599 if (pipe_output)
600 dup2(2, 1);
502 close(child_ready_pipe[0]); 601 close(child_ready_pipe[0]);
503 close(go_pipe[1]); 602 close(go_pipe[1]);
504 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 603 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -527,10 +626,8 @@ static int __cmd_record(int argc, const char **argv)
527 exit(-1); 626 exit(-1);
528 } 627 }
529 628
530 child_pid = pid; 629 if (!system_wide && target_tid == -1 && target_pid == -1)
531 630 all_tids[0] = child_pid;
532 if (!system_wide)
533 target_pid = pid;
534 631
535 close(child_ready_pipe[1]); 632 close(child_ready_pipe[1]);
536 close(go_pipe[0]); 633 close(go_pipe[0]);
@@ -544,16 +641,19 @@ static int __cmd_record(int argc, const char **argv)
544 close(child_ready_pipe[0]); 641 close(child_ready_pipe[0]);
545 } 642 }
546 643
547 644 if ((!system_wide && no_inherit) || profile_cpu != -1) {
548 if ((!system_wide && !inherit) || profile_cpu != -1) { 645 open_counters(profile_cpu);
549 open_counters(profile_cpu, target_pid);
550 } else { 646 } else {
551 nr_cpus = read_cpu_map(); 647 nr_cpus = read_cpu_map();
552 for (i = 0; i < nr_cpus; i++) 648 for (i = 0; i < nr_cpus; i++)
553 open_counters(cpumap[i], target_pid); 649 open_counters(cpumap[i]);
554 } 650 }
555 651
556 if (file_new) { 652 if (pipe_output) {
653 err = perf_header__write_pipe(output);
654 if (err < 0)
655 return err;
656 } else if (file_new) {
557 err = perf_header__write(&session->header, output, false); 657 err = perf_header__write(&session->header, output, false);
558 if (err < 0) 658 if (err < 0)
559 return err; 659 return err;
@@ -561,24 +661,70 @@ static int __cmd_record(int argc, const char **argv)
561 661
562 post_processing_offset = lseek(output, 0, SEEK_CUR); 662 post_processing_offset = lseek(output, 0, SEEK_CUR);
563 663
664 if (pipe_output) {
665 err = event__synthesize_attrs(&session->header,
666 process_synthesized_event,
667 session);
668 if (err < 0) {
669 pr_err("Couldn't synthesize attrs.\n");
670 return err;
671 }
672
673 err = event__synthesize_event_types(process_synthesized_event,
674 session);
675 if (err < 0) {
676 pr_err("Couldn't synthesize event_types.\n");
677 return err;
678 }
679
680 if (have_tracepoints(attrs, nr_counters)) {
681 /*
682 * FIXME err <= 0 here actually means that
683 * there were no tracepoints so its not really
684 * an error, just that we don't need to
685 * synthesize anything. We really have to
686 * return this more properly and also
687 * propagate errors that now are calling die()
688 */
689 err = event__synthesize_tracing_data(output, attrs,
690 nr_counters,
691 process_synthesized_event,
692 session);
693 if (err <= 0) {
694 pr_err("Couldn't record tracing data.\n");
695 return err;
696 }
697 advance_output(err);
698 }
699 }
700
701 machine = perf_session__find_host_machine(session);
702 if (!machine) {
703 pr_err("Couldn't find native kernel information.\n");
704 return -1;
705 }
706
564 err = event__synthesize_kernel_mmap(process_synthesized_event, 707 err = event__synthesize_kernel_mmap(process_synthesized_event,
565 session, "_text"); 708 session, machine, "_text");
566 if (err < 0) 709 if (err < 0)
567 err = event__synthesize_kernel_mmap(process_synthesized_event, 710 err = event__synthesize_kernel_mmap(process_synthesized_event,
568 session, "_stext"); 711 session, machine, "_stext");
569 if (err < 0) { 712 if (err < 0) {
570 pr_err("Couldn't record kernel reference relocation symbol.\n"); 713 pr_err("Couldn't record kernel reference relocation symbol.\n");
571 return err; 714 return err;
572 } 715 }
573 716
574 err = event__synthesize_modules(process_synthesized_event, session); 717 err = event__synthesize_modules(process_synthesized_event,
718 session, machine);
575 if (err < 0) { 719 if (err < 0) {
576 pr_err("Couldn't record kernel reference relocation symbol.\n"); 720 pr_err("Couldn't record kernel reference relocation symbol.\n");
577 return err; 721 return err;
578 } 722 }
723 if (perf_guest)
724 perf_session__process_machines(session, event__synthesize_guest_os);
579 725
580 if (!system_wide && profile_cpu == -1) 726 if (!system_wide && profile_cpu == -1)
581 event__synthesize_thread(target_pid, process_synthesized_event, 727 event__synthesize_thread(target_tid, process_synthesized_event,
582 session); 728 session);
583 else 729 else
584 event__synthesize_threads(process_synthesized_event, session); 730 event__synthesize_threads(process_synthesized_event, session);
@@ -601,13 +747,9 @@ static int __cmd_record(int argc, const char **argv)
601 747
602 for (;;) { 748 for (;;) {
603 int hits = samples; 749 int hits = samples;
750 int thread;
604 751
605 for (i = 0; i < nr_cpu; i++) { 752 mmap_read_all();
606 for (counter = 0; counter < nr_counters; counter++) {
607 if (mmap_array[i][counter].base)
608 mmap_read(&mmap_array[i][counter]);
609 }
610 }
611 753
612 if (hits == samples) { 754 if (hits == samples) {
613 if (done) 755 if (done)
@@ -618,8 +760,15 @@ static int __cmd_record(int argc, const char **argv)
618 760
619 if (done) { 761 if (done) {
620 for (i = 0; i < nr_cpu; i++) { 762 for (i = 0; i < nr_cpu; i++) {
621 for (counter = 0; counter < nr_counters; counter++) 763 for (counter = 0;
622 ioctl(fd[i][counter], PERF_EVENT_IOC_DISABLE); 764 counter < nr_counters;
765 counter++) {
766 for (thread = 0;
767 thread < thread_num;
768 thread++)
769 ioctl(fd[i][counter][thread],
770 PERF_EVENT_IOC_DISABLE);
771 }
623 } 772 }
624 } 773 }
625 } 774 }
@@ -644,6 +793,8 @@ static const char * const record_usage[] = {
644 NULL 793 NULL
645}; 794};
646 795
796static bool force, append_file;
797
647static const struct option options[] = { 798static const struct option options[] = {
648 OPT_CALLBACK('e', "event", NULL, "event", 799 OPT_CALLBACK('e', "event", NULL, "event",
649 "event selector. use 'perf list' to list available events", 800 "event selector. use 'perf list' to list available events",
@@ -651,7 +802,9 @@ static const struct option options[] = {
651 OPT_CALLBACK(0, "filter", NULL, "filter", 802 OPT_CALLBACK(0, "filter", NULL, "filter",
652 "event filter", parse_filter), 803 "event filter", parse_filter),
653 OPT_INTEGER('p', "pid", &target_pid, 804 OPT_INTEGER('p', "pid", &target_pid,
654 "record events on existing pid"), 805 "record events on existing process id"),
806 OPT_INTEGER('t', "tid", &target_tid,
807 "record events on existing thread id"),
655 OPT_INTEGER('r', "realtime", &realtime_prio, 808 OPT_INTEGER('r', "realtime", &realtime_prio,
656 "collect data with this RT SCHED_FIFO priority"), 809 "collect data with this RT SCHED_FIFO priority"),
657 OPT_BOOLEAN('R', "raw-samples", &raw_samples, 810 OPT_BOOLEAN('R', "raw-samples", &raw_samples,
@@ -663,20 +816,17 @@ static const struct option options[] = {
663 OPT_INTEGER('C', "profile_cpu", &profile_cpu, 816 OPT_INTEGER('C', "profile_cpu", &profile_cpu,
664 "CPU to profile on"), 817 "CPU to profile on"),
665 OPT_BOOLEAN('f', "force", &force, 818 OPT_BOOLEAN('f', "force", &force,
666 "overwrite existing data file"), 819 "overwrite existing data file (deprecated)"),
667 OPT_LONG('c', "count", &default_interval, 820 OPT_U64('c', "count", &user_interval, "event period to sample"),
668 "event period to sample"),
669 OPT_STRING('o', "output", &output_name, "file", 821 OPT_STRING('o', "output", &output_name, "file",
670 "output file name"), 822 "output file name"),
671 OPT_BOOLEAN('i', "inherit", &inherit, 823 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
672 "child tasks inherit counters"), 824 "child tasks do not inherit counters"),
673 OPT_INTEGER('F', "freq", &freq, 825 OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"),
674 "profile at this frequency"), 826 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
675 OPT_INTEGER('m', "mmap-pages", &mmap_pages,
676 "number of mmap data pages"),
677 OPT_BOOLEAN('g', "call-graph", &call_graph, 827 OPT_BOOLEAN('g', "call-graph", &call_graph,
678 "do call-graph (stack chain/backtrace) recording"), 828 "do call-graph (stack chain/backtrace) recording"),
679 OPT_BOOLEAN('v', "verbose", &verbose, 829 OPT_INCR('v', "verbose", &verbose,
680 "be more verbose (show counter open errors, etc)"), 830 "be more verbose (show counter open errors, etc)"),
681 OPT_BOOLEAN('s', "stat", &inherit_stat, 831 OPT_BOOLEAN('s', "stat", &inherit_stat,
682 "per thread counts"), 832 "per thread counts"),
@@ -691,13 +841,24 @@ static const struct option options[] = {
691 841
692int cmd_record(int argc, const char **argv, const char *prefix __used) 842int cmd_record(int argc, const char **argv, const char *prefix __used)
693{ 843{
694 int counter; 844 int i,j;
695 845
696 argc = parse_options(argc, argv, options, record_usage, 846 argc = parse_options(argc, argv, options, record_usage,
697 PARSE_OPT_STOP_AT_NON_OPTION); 847 PARSE_OPT_STOP_AT_NON_OPTION);
698 if (!argc && target_pid == -1 && !system_wide && profile_cpu == -1) 848 if (!argc && target_pid == -1 && target_tid == -1 &&
849 !system_wide && profile_cpu == -1)
699 usage_with_options(record_usage, options); 850 usage_with_options(record_usage, options);
700 851
852 if (force && append_file) {
853 fprintf(stderr, "Can't overwrite and append at the same time."
854 " You need to choose between -f and -A");
855 usage_with_options(record_usage, options);
856 } else if (append_file) {
857 write_mode = WRITE_APPEND;
858 } else {
859 write_mode = WRITE_FORCE;
860 }
861
701 symbol__init(); 862 symbol__init();
702 863
703 if (!nr_counters) { 864 if (!nr_counters) {
@@ -706,6 +867,42 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
706 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES; 867 attrs[0].config = PERF_COUNT_HW_CPU_CYCLES;
707 } 868 }
708 869
870 if (target_pid != -1) {
871 target_tid = target_pid;
872 thread_num = find_all_tid(target_pid, &all_tids);
873 if (thread_num <= 0) {
874 fprintf(stderr, "Can't find all threads of pid %d\n",
875 target_pid);
876 usage_with_options(record_usage, options);
877 }
878 } else {
879 all_tids=malloc(sizeof(pid_t));
880 if (!all_tids)
881 return -ENOMEM;
882
883 all_tids[0] = target_tid;
884 thread_num = 1;
885 }
886
887 for (i = 0; i < MAX_NR_CPUS; i++) {
888 for (j = 0; j < MAX_COUNTERS; j++) {
889 fd[i][j] = malloc(sizeof(int)*thread_num);
890 mmap_array[i][j] = zalloc(
891 sizeof(struct mmap_data)*thread_num);
892 if (!fd[i][j] || !mmap_array[i][j])
893 return -ENOMEM;
894 }
895 }
896 event_array = malloc(
897 sizeof(struct pollfd)*MAX_NR_CPUS*MAX_COUNTERS*thread_num);
898 if (!event_array)
899 return -ENOMEM;
900
901 if (user_interval != ULLONG_MAX)
902 default_interval = user_interval;
903 if (user_freq != UINT_MAX)
904 freq = user_freq;
905
709 /* 906 /*
710 * User specified count overrides default frequency. 907 * User specified count overrides default frequency.
711 */ 908 */
@@ -718,12 +915,5 @@ int cmd_record(int argc, const char **argv, const char *prefix __used)
718 exit(EXIT_FAILURE); 915 exit(EXIT_FAILURE);
719 } 916 }
720 917
721 for (counter = 0; counter < nr_counters; counter++) {
722 if (attrs[counter].sample_period)
723 continue;
724
725 attrs[counter].sample_period = default_interval;
726 }
727
728 return __cmd_record(argc, argv); 918 return __cmd_record(argc, argv);
729} 919}