aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-record.c
diff options
context:
space:
mode:
authorJiri Olsa <jolsa@redhat.com>2013-10-15 10:27:32 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2013-10-21 16:33:24 -0400
commitf5fc14124c5cefdd052a2b2a6a3f0ed531540113 (patch)
tree9cef9b2a75334478486869ff002749679a9e488d /tools/perf/builtin-record.c
parent09600e0f9ebb06235b852a646a3644b7d4a71aca (diff)
perf tools: Add data object to handle perf data file
This patch is adding 'struct perf_data_file' object as a placeholder for all attributes regarding perf.data file handling. Changing perf_session__new to take it as an argument. The rest of the functionality will be added later to keep this change simple enough, because all the places using perf_session are changed now. Signed-off-by: Jiri Olsa <jolsa@redhat.com> Acked-by: Namhyung Kim <namhyung@kernel.org> Cc: Adrian Hunter <adrian.hunter@intel.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Corey Ashford <cjashfor@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Ingo Molnar <mingo@elte.hu> Cc: Namhyung Kim <namhyung@kernel.org> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/1381847254-28809-2-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/builtin-record.c')
-rw-r--r--tools/perf/builtin-record.c61
1 files changed, 32 insertions, 29 deletions
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index d269dfa3ab08..4ea46ffbfc1c 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -24,6 +24,7 @@
24#include "util/symbol.h" 24#include "util/symbol.h"
25#include "util/cpumap.h" 25#include "util/cpumap.h"
26#include "util/thread_map.h" 26#include "util/thread_map.h"
27#include "util/data.h"
27 28
28#include <unistd.h> 29#include <unistd.h>
29#include <sched.h> 30#include <sched.h>
@@ -65,11 +66,10 @@ struct perf_record {
65 struct perf_tool tool; 66 struct perf_tool tool;
66 struct perf_record_opts opts; 67 struct perf_record_opts opts;
67 u64 bytes_written; 68 u64 bytes_written;
68 const char *output_name; 69 struct perf_data_file file;
69 struct perf_evlist *evlist; 70 struct perf_evlist *evlist;
70 struct perf_session *session; 71 struct perf_session *session;
71 const char *progname; 72 const char *progname;
72 int output;
73 int realtime_prio; 73 int realtime_prio;
74 bool no_buildid; 74 bool no_buildid;
75 bool no_buildid_cache; 75 bool no_buildid_cache;
@@ -84,8 +84,10 @@ static void advance_output(struct perf_record *rec, size_t size)
84 84
85static int write_output(struct perf_record *rec, void *buf, size_t size) 85static int write_output(struct perf_record *rec, void *buf, size_t size)
86{ 86{
87 struct perf_data_file *file = &rec->file;
88
87 while (size) { 89 while (size) {
88 int ret = write(rec->output, buf, size); 90 int ret = write(file->fd, buf, size);
89 91
90 if (ret < 0) { 92 if (ret < 0) {
91 pr_err("failed to write perf data, error: %m\n"); 93 pr_err("failed to write perf data, error: %m\n");
@@ -248,13 +250,15 @@ out:
248 250
249static int process_buildids(struct perf_record *rec) 251static int process_buildids(struct perf_record *rec)
250{ 252{
251 u64 size = lseek(rec->output, 0, SEEK_CUR); 253 struct perf_data_file *file = &rec->file;
254 struct perf_session *session = rec->session;
252 255
256 u64 size = lseek(file->fd, 0, SEEK_CUR);
253 if (size == 0) 257 if (size == 0)
254 return 0; 258 return 0;
255 259
256 rec->session->fd = rec->output; 260 session->fd = file->fd;
257 return __perf_session__process_events(rec->session, rec->post_processing_offset, 261 return __perf_session__process_events(session, rec->post_processing_offset,
258 size - rec->post_processing_offset, 262 size - rec->post_processing_offset,
259 size, &build_id__mark_dso_hit_ops); 263 size, &build_id__mark_dso_hit_ops);
260} 264}
@@ -262,17 +266,18 @@ static int process_buildids(struct perf_record *rec)
262static void perf_record__exit(int status, void *arg) 266static void perf_record__exit(int status, void *arg)
263{ 267{
264 struct perf_record *rec = arg; 268 struct perf_record *rec = arg;
269 struct perf_data_file *file = &rec->file;
265 270
266 if (status != 0) 271 if (status != 0)
267 return; 272 return;
268 273
269 if (!rec->opts.pipe_output) { 274 if (!file->is_pipe) {
270 rec->session->header.data_size += rec->bytes_written; 275 rec->session->header.data_size += rec->bytes_written;
271 276
272 if (!rec->no_buildid) 277 if (!rec->no_buildid)
273 process_buildids(rec); 278 process_buildids(rec);
274 perf_session__write_header(rec->session, rec->evlist, 279 perf_session__write_header(rec->session, rec->evlist,
275 rec->output, true); 280 file->fd, true);
276 perf_session__delete(rec->session); 281 perf_session__delete(rec->session);
277 perf_evlist__delete(rec->evlist); 282 perf_evlist__delete(rec->evlist);
278 symbol__exit(); 283 symbol__exit();
@@ -342,14 +347,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
342{ 347{
343 struct stat st; 348 struct stat st;
344 int flags; 349 int flags;
345 int err, output, feat; 350 int err, feat;
346 unsigned long waking = 0; 351 unsigned long waking = 0;
347 const bool forks = argc > 0; 352 const bool forks = argc > 0;
348 struct machine *machine; 353 struct machine *machine;
349 struct perf_tool *tool = &rec->tool; 354 struct perf_tool *tool = &rec->tool;
350 struct perf_record_opts *opts = &rec->opts; 355 struct perf_record_opts *opts = &rec->opts;
351 struct perf_evlist *evsel_list = rec->evlist; 356 struct perf_evlist *evsel_list = rec->evlist;
352 const char *output_name = rec->output_name; 357 struct perf_data_file *file = &rec->file;
358 const char *output_name = file->path;
353 struct perf_session *session; 359 struct perf_session *session;
354 bool disabled = false; 360 bool disabled = false;
355 361
@@ -363,13 +369,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
363 369
364 if (!output_name) { 370 if (!output_name) {
365 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) 371 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
366 opts->pipe_output = true; 372 file->is_pipe = true;
367 else 373 else
368 rec->output_name = output_name = "perf.data"; 374 file->path = output_name = "perf.data";
369 } 375 }
370 if (output_name) { 376 if (output_name) {
371 if (!strcmp(output_name, "-")) 377 if (!strcmp(output_name, "-"))
372 opts->pipe_output = true; 378 file->is_pipe = true;
373 else if (!stat(output_name, &st) && st.st_size) { 379 else if (!stat(output_name, &st) && st.st_size) {
374 char oldname[PATH_MAX]; 380 char oldname[PATH_MAX];
375 snprintf(oldname, sizeof(oldname), "%s.old", 381 snprintf(oldname, sizeof(oldname), "%s.old",
@@ -381,19 +387,16 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
381 387
382 flags = O_CREAT|O_RDWR|O_TRUNC; 388 flags = O_CREAT|O_RDWR|O_TRUNC;
383 389
384 if (opts->pipe_output) 390 if (file->is_pipe)
385 output = STDOUT_FILENO; 391 file->fd = STDOUT_FILENO;
386 else 392 else
387 output = open(output_name, flags, S_IRUSR | S_IWUSR); 393 file->fd = open(output_name, flags, S_IRUSR | S_IWUSR);
388 if (output < 0) { 394 if (file->fd < 0) {
389 perror("failed to create output file"); 395 perror("failed to create output file");
390 return -1; 396 return -1;
391 } 397 }
392 398
393 rec->output = output; 399 session = perf_session__new(file, false, NULL);
394
395 session = perf_session__new(output_name, O_WRONLY,
396 true, false, NULL);
397 if (session == NULL) { 400 if (session == NULL) {
398 pr_err("Not enough memory for reading perf file header\n"); 401 pr_err("Not enough memory for reading perf file header\n");
399 return -1; 402 return -1;
@@ -415,7 +418,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
415 418
416 if (forks) { 419 if (forks) {
417 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 420 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
418 argv, opts->pipe_output, 421 argv, file->is_pipe,
419 true); 422 true);
420 if (err < 0) { 423 if (err < 0) {
421 pr_err("Couldn't run the workload!\n"); 424 pr_err("Couldn't run the workload!\n");
@@ -436,13 +439,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
436 */ 439 */
437 on_exit(perf_record__exit, rec); 440 on_exit(perf_record__exit, rec);
438 441
439 if (opts->pipe_output) { 442 if (file->is_pipe) {
440 err = perf_header__write_pipe(output); 443 err = perf_header__write_pipe(file->fd);
441 if (err < 0) 444 if (err < 0)
442 goto out_delete_session; 445 goto out_delete_session;
443 } else { 446 } else {
444 err = perf_session__write_header(session, evsel_list, 447 err = perf_session__write_header(session, evsel_list,
445 output, false); 448 file->fd, false);
446 if (err < 0) 449 if (err < 0)
447 goto out_delete_session; 450 goto out_delete_session;
448 } 451 }
@@ -455,11 +458,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
455 goto out_delete_session; 458 goto out_delete_session;
456 } 459 }
457 460
458 rec->post_processing_offset = lseek(output, 0, SEEK_CUR); 461 rec->post_processing_offset = lseek(file->fd, 0, SEEK_CUR);
459 462
460 machine = &session->machines.host; 463 machine = &session->machines.host;
461 464
462 if (opts->pipe_output) { 465 if (file->is_pipe) {
463 err = perf_event__synthesize_attrs(tool, session, 466 err = perf_event__synthesize_attrs(tool, session,
464 process_synthesized_event); 467 process_synthesized_event);
465 if (err < 0) { 468 if (err < 0) {
@@ -476,7 +479,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
476 * return this more properly and also 479 * return this more properly and also
477 * propagate errors that now are calling die() 480 * propagate errors that now are calling die()
478 */ 481 */
479 err = perf_event__synthesize_tracing_data(tool, output, evsel_list, 482 err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
480 process_synthesized_event); 483 process_synthesized_event);
481 if (err <= 0) { 484 if (err <= 0) {
482 pr_err("Couldn't record tracing data.\n"); 485 pr_err("Couldn't record tracing data.\n");
@@ -845,7 +848,7 @@ const struct option record_options[] = {
845 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 848 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
846 "list of cpus to monitor"), 849 "list of cpus to monitor"),
847 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 850 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
848 OPT_STRING('o', "output", &record.output_name, "file", 851 OPT_STRING('o', "output", &record.file.path, "file",
849 "output file name"), 852 "output file name"),
850 OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit, 853 OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
851 "child tasks do not inherit counters"), 854 "child tasks do not inherit counters"),