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>
This commit is contained in:
Родитель
09600e0f9e
Коммит
f5fc14124c
|
@ -28,6 +28,7 @@
|
||||||
#include "util/hist.h"
|
#include "util/hist.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
|
#include "util/data.h"
|
||||||
#include "arch/common.h"
|
#include "arch/common.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -199,9 +200,13 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
struct perf_evsel *pos;
|
struct perf_evsel *pos;
|
||||||
u64 total_nr_samples;
|
u64 total_nr_samples;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = ann->force,
|
||||||
|
};
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY,
|
session = perf_session__new(&file, false, &ann->tool);
|
||||||
ann->force, false, &ann->tool);
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -221,8 +221,12 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)
|
||||||
|
|
||||||
static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp)
|
static int build_id_cache__fprintf_missing(const char *filename, bool force, FILE *fp)
|
||||||
{
|
{
|
||||||
struct perf_session *session = perf_session__new(filename, O_RDONLY,
|
struct perf_data_file file = {
|
||||||
force, false, NULL);
|
.path = filename,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = force,
|
||||||
|
};
|
||||||
|
struct perf_session *session = perf_session__new(&file, false, NULL);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "util/parse-options.h"
|
#include "util/parse-options.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
static int sysfs__fprintf_build_id(FILE *fp)
|
static int sysfs__fprintf_build_id(FILE *fp)
|
||||||
{
|
{
|
||||||
|
@ -52,6 +53,11 @@ static bool dso__skip_buildid(struct dso *dso, int with_hits)
|
||||||
static int perf_session__list_build_ids(bool force, bool with_hits)
|
static int perf_session__list_build_ids(bool force, bool with_hits)
|
||||||
{
|
{
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
.force = force,
|
||||||
|
};
|
||||||
|
|
||||||
symbol__elf_init();
|
symbol__elf_init();
|
||||||
/*
|
/*
|
||||||
|
@ -60,8 +66,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
|
||||||
if (filename__fprintf_build_id(input_name, stdout))
|
if (filename__fprintf_build_id(input_name, stdout))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, force, false,
|
session = perf_session__new(&file, false, &build_id__mark_dso_hit_ops);
|
||||||
&build_id__mark_dso_hit_ops);
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
#include "util/util.h"
|
#include "util/util.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -42,7 +43,7 @@ struct diff_hpp_fmt {
|
||||||
|
|
||||||
struct data__file {
|
struct data__file {
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
const char *file;
|
struct perf_data_file file;
|
||||||
int idx;
|
int idx;
|
||||||
struct hists *hists;
|
struct hists *hists;
|
||||||
struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX];
|
struct diff_hpp_fmt fmt[PERF_HPP_DIFF__MAX_INDEX];
|
||||||
|
@ -601,7 +602,7 @@ static void data__fprintf(void)
|
||||||
|
|
||||||
data__for_each_file(i, d)
|
data__for_each_file(i, d)
|
||||||
fprintf(stdout, "# [%d] %s %s\n",
|
fprintf(stdout, "# [%d] %s %s\n",
|
||||||
d->idx, d->file,
|
d->idx, d->file.path,
|
||||||
!d->idx ? "(Baseline)" : "");
|
!d->idx ? "(Baseline)" : "");
|
||||||
|
|
||||||
fprintf(stdout, "#\n");
|
fprintf(stdout, "#\n");
|
||||||
|
@ -663,17 +664,16 @@ static int __cmd_diff(void)
|
||||||
int ret = -EINVAL, i;
|
int ret = -EINVAL, i;
|
||||||
|
|
||||||
data__for_each_file(i, d) {
|
data__for_each_file(i, d) {
|
||||||
d->session = perf_session__new(d->file, O_RDONLY, force,
|
d->session = perf_session__new(&d->file, false, &tool);
|
||||||
false, &tool);
|
|
||||||
if (!d->session) {
|
if (!d->session) {
|
||||||
pr_err("Failed to open %s\n", d->file);
|
pr_err("Failed to open %s\n", d->file.path);
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = perf_session__process_events(d->session, &tool);
|
ret = perf_session__process_events(d->session, &tool);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pr_err("Failed to process %s\n", d->file);
|
pr_err("Failed to process %s\n", d->file.path);
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1016,7 +1016,12 @@ static int data_init(int argc, const char **argv)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
data__for_each_file(i, d) {
|
data__for_each_file(i, d) {
|
||||||
d->file = use_default ? defaults[i] : argv[i];
|
struct perf_data_file *file = &d->file;
|
||||||
|
|
||||||
|
file->path = use_default ? defaults[i] : argv[i];
|
||||||
|
file->mode = PERF_DATA_MODE_READ,
|
||||||
|
file->force = force,
|
||||||
|
|
||||||
d->idx = i;
|
d->idx = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,13 +14,18 @@
|
||||||
#include "util/parse-events.h"
|
#include "util/parse-events.h"
|
||||||
#include "util/parse-options.h"
|
#include "util/parse-options.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
|
static int __cmd_evlist(const char *file_name, struct perf_attr_details *details)
|
||||||
{
|
{
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
struct perf_evsel *pos;
|
struct perf_evsel *pos;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = file_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
session = perf_session__new(file_name, O_RDONLY, 0, false, NULL);
|
session = perf_session__new(&file, 0, NULL);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/build-id.h"
|
#include "util/build-id.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include "util/parse-options.h"
|
#include "util/parse-options.h"
|
||||||
|
|
||||||
|
@ -345,6 +346,10 @@ static int __cmd_inject(struct perf_inject *inject)
|
||||||
{
|
{
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = inject->input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
|
||||||
|
@ -355,7 +360,7 @@ static int __cmd_inject(struct perf_inject *inject)
|
||||||
inject->tool.tracing_data = perf_event__repipe_tracing_data;
|
inject->tool.tracing_data = perf_event__repipe_tracing_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
session = perf_session__new(inject->input_name, O_RDONLY, false, true, &inject->tool);
|
session = perf_session__new(&file, true, &inject->tool);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "util/parse-options.h"
|
#include "util/parse-options.h"
|
||||||
#include "util/trace-event.h"
|
#include "util/trace-event.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
|
|
||||||
|
@ -486,8 +487,12 @@ static int __cmd_kmem(void)
|
||||||
{ "kmem:kfree", perf_evsel__process_free_event, },
|
{ "kmem:kfree", perf_evsel__process_free_event, },
|
||||||
{ "kmem:kmem_cache_free", perf_evsel__process_free_event, },
|
{ "kmem:kmem_cache_free", perf_evsel__process_free_event, },
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false, &perf_kmem);
|
session = perf_session__new(&file, false, &perf_kmem);
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/stat.h"
|
#include "util/stat.h"
|
||||||
#include "util/top.h"
|
#include "util/top.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#include <sys/timerfd.h>
|
#include <sys/timerfd.h>
|
||||||
|
@ -1215,10 +1216,13 @@ static int read_events(struct perf_kvm_stat *kvm)
|
||||||
.comm = perf_event__process_comm,
|
.comm = perf_event__process_comm,
|
||||||
.ordered_samples = true,
|
.ordered_samples = true,
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
kvm->tool = eops;
|
kvm->tool = eops;
|
||||||
kvm->session = perf_session__new(kvm->file_name, O_RDONLY, 0, false,
|
kvm->session = perf_session__new(&file, false, &kvm->tool);
|
||||||
&kvm->tool);
|
|
||||||
if (!kvm->session) {
|
if (!kvm->session) {
|
||||||
pr_err("Initializing perf session failed\n");
|
pr_err("Initializing perf session failed\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1450,6 +1454,9 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
||||||
"perf kvm stat live [<options>]",
|
"perf kvm stat live [<options>]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.mode = PERF_DATA_MODE_WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* event handling */
|
/* event handling */
|
||||||
|
@ -1514,7 +1521,7 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
|
||||||
/*
|
/*
|
||||||
* perf session
|
* perf session
|
||||||
*/
|
*/
|
||||||
kvm->session = perf_session__new(NULL, O_WRONLY, false, false, &kvm->tool);
|
kvm->session = perf_session__new(&file, false, &kvm->tool);
|
||||||
if (kvm->session == NULL) {
|
if (kvm->session == NULL) {
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "util/debug.h"
|
#include "util/debug.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
|
@ -853,8 +854,12 @@ static int __cmd_report(bool display_info)
|
||||||
.comm = perf_event__process_comm,
|
.comm = perf_event__process_comm,
|
||||||
.ordered_samples = true,
|
.ordered_samples = true,
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
|
session = perf_session__new(&file, false, &eops);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
pr_err("Initializing perf session failed\n");
|
pr_err("Initializing perf session failed\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "util/trace-event.h"
|
#include "util/trace-event.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#define MEM_OPERATION_LOAD "load"
|
#define MEM_OPERATION_LOAD "load"
|
||||||
#define MEM_OPERATION_STORE "store"
|
#define MEM_OPERATION_STORE "store"
|
||||||
|
@ -119,10 +120,14 @@ static int process_sample_event(struct perf_tool *tool,
|
||||||
|
|
||||||
static int report_raw_events(struct perf_mem *mem)
|
static int report_raw_events(struct perf_mem *mem)
|
||||||
{
|
{
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
int ret;
|
int ret;
|
||||||
struct perf_session *session = perf_session__new(input_name, O_RDONLY,
|
struct perf_session *session = perf_session__new(&file, false,
|
||||||
0, false, &mem->tool);
|
&mem->tool);
|
||||||
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "util/symbol.h"
|
#include "util/symbol.h"
|
||||||
#include "util/cpumap.h"
|
#include "util/cpumap.h"
|
||||||
#include "util/thread_map.h"
|
#include "util/thread_map.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
|
@ -65,11 +66,10 @@ struct perf_record {
|
||||||
struct perf_tool tool;
|
struct perf_tool tool;
|
||||||
struct perf_record_opts opts;
|
struct perf_record_opts opts;
|
||||||
u64 bytes_written;
|
u64 bytes_written;
|
||||||
const char *output_name;
|
struct perf_data_file file;
|
||||||
struct perf_evlist *evlist;
|
struct perf_evlist *evlist;
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
const char *progname;
|
const char *progname;
|
||||||
int output;
|
|
||||||
int realtime_prio;
|
int realtime_prio;
|
||||||
bool no_buildid;
|
bool no_buildid;
|
||||||
bool no_buildid_cache;
|
bool no_buildid_cache;
|
||||||
|
@ -84,8 +84,10 @@ static void advance_output(struct perf_record *rec, size_t size)
|
||||||
|
|
||||||
static int write_output(struct perf_record *rec, void *buf, size_t size)
|
static int write_output(struct perf_record *rec, void *buf, size_t size)
|
||||||
{
|
{
|
||||||
|
struct perf_data_file *file = &rec->file;
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
int ret = write(rec->output, buf, size);
|
int ret = write(file->fd, buf, size);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
pr_err("failed to write perf data, error: %m\n");
|
pr_err("failed to write perf data, error: %m\n");
|
||||||
|
@ -248,13 +250,15 @@ out:
|
||||||
|
|
||||||
static int process_buildids(struct perf_record *rec)
|
static int process_buildids(struct perf_record *rec)
|
||||||
{
|
{
|
||||||
u64 size = lseek(rec->output, 0, SEEK_CUR);
|
struct perf_data_file *file = &rec->file;
|
||||||
|
struct perf_session *session = rec->session;
|
||||||
|
|
||||||
|
u64 size = lseek(file->fd, 0, SEEK_CUR);
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
rec->session->fd = rec->output;
|
session->fd = file->fd;
|
||||||
return __perf_session__process_events(rec->session, rec->post_processing_offset,
|
return __perf_session__process_events(session, rec->post_processing_offset,
|
||||||
size - rec->post_processing_offset,
|
size - rec->post_processing_offset,
|
||||||
size, &build_id__mark_dso_hit_ops);
|
size, &build_id__mark_dso_hit_ops);
|
||||||
}
|
}
|
||||||
|
@ -262,17 +266,18 @@ static int process_buildids(struct perf_record *rec)
|
||||||
static void perf_record__exit(int status, void *arg)
|
static void perf_record__exit(int status, void *arg)
|
||||||
{
|
{
|
||||||
struct perf_record *rec = arg;
|
struct perf_record *rec = arg;
|
||||||
|
struct perf_data_file *file = &rec->file;
|
||||||
|
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!rec->opts.pipe_output) {
|
if (!file->is_pipe) {
|
||||||
rec->session->header.data_size += rec->bytes_written;
|
rec->session->header.data_size += rec->bytes_written;
|
||||||
|
|
||||||
if (!rec->no_buildid)
|
if (!rec->no_buildid)
|
||||||
process_buildids(rec);
|
process_buildids(rec);
|
||||||
perf_session__write_header(rec->session, rec->evlist,
|
perf_session__write_header(rec->session, rec->evlist,
|
||||||
rec->output, true);
|
file->fd, true);
|
||||||
perf_session__delete(rec->session);
|
perf_session__delete(rec->session);
|
||||||
perf_evlist__delete(rec->evlist);
|
perf_evlist__delete(rec->evlist);
|
||||||
symbol__exit();
|
symbol__exit();
|
||||||
|
@ -342,14 +347,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int flags;
|
int flags;
|
||||||
int err, output, feat;
|
int err, feat;
|
||||||
unsigned long waking = 0;
|
unsigned long waking = 0;
|
||||||
const bool forks = argc > 0;
|
const bool forks = argc > 0;
|
||||||
struct machine *machine;
|
struct machine *machine;
|
||||||
struct perf_tool *tool = &rec->tool;
|
struct perf_tool *tool = &rec->tool;
|
||||||
struct perf_record_opts *opts = &rec->opts;
|
struct perf_record_opts *opts = &rec->opts;
|
||||||
struct perf_evlist *evsel_list = rec->evlist;
|
struct perf_evlist *evsel_list = rec->evlist;
|
||||||
const char *output_name = rec->output_name;
|
struct perf_data_file *file = &rec->file;
|
||||||
|
const char *output_name = file->path;
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
|
||||||
|
@ -363,13 +369,13 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
|
|
||||||
if (!output_name) {
|
if (!output_name) {
|
||||||
if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
|
if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
|
||||||
opts->pipe_output = true;
|
file->is_pipe = true;
|
||||||
else
|
else
|
||||||
rec->output_name = output_name = "perf.data";
|
file->path = output_name = "perf.data";
|
||||||
}
|
}
|
||||||
if (output_name) {
|
if (output_name) {
|
||||||
if (!strcmp(output_name, "-"))
|
if (!strcmp(output_name, "-"))
|
||||||
opts->pipe_output = true;
|
file->is_pipe = true;
|
||||||
else if (!stat(output_name, &st) && st.st_size) {
|
else if (!stat(output_name, &st) && st.st_size) {
|
||||||
char oldname[PATH_MAX];
|
char oldname[PATH_MAX];
|
||||||
snprintf(oldname, sizeof(oldname), "%s.old",
|
snprintf(oldname, sizeof(oldname), "%s.old",
|
||||||
|
@ -381,19 +387,16 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
|
|
||||||
flags = O_CREAT|O_RDWR|O_TRUNC;
|
flags = O_CREAT|O_RDWR|O_TRUNC;
|
||||||
|
|
||||||
if (opts->pipe_output)
|
if (file->is_pipe)
|
||||||
output = STDOUT_FILENO;
|
file->fd = STDOUT_FILENO;
|
||||||
else
|
else
|
||||||
output = open(output_name, flags, S_IRUSR | S_IWUSR);
|
file->fd = open(output_name, flags, S_IRUSR | S_IWUSR);
|
||||||
if (output < 0) {
|
if (file->fd < 0) {
|
||||||
perror("failed to create output file");
|
perror("failed to create output file");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec->output = output;
|
session = perf_session__new(file, false, NULL);
|
||||||
|
|
||||||
session = perf_session__new(output_name, O_WRONLY,
|
|
||||||
true, false, NULL);
|
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
pr_err("Not enough memory for reading perf file header\n");
|
pr_err("Not enough memory for reading perf file header\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -415,7 +418,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
|
|
||||||
if (forks) {
|
if (forks) {
|
||||||
err = perf_evlist__prepare_workload(evsel_list, &opts->target,
|
err = perf_evlist__prepare_workload(evsel_list, &opts->target,
|
||||||
argv, opts->pipe_output,
|
argv, file->is_pipe,
|
||||||
true);
|
true);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
pr_err("Couldn't run the workload!\n");
|
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)
|
||||||
*/
|
*/
|
||||||
on_exit(perf_record__exit, rec);
|
on_exit(perf_record__exit, rec);
|
||||||
|
|
||||||
if (opts->pipe_output) {
|
if (file->is_pipe) {
|
||||||
err = perf_header__write_pipe(output);
|
err = perf_header__write_pipe(file->fd);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_delete_session;
|
goto out_delete_session;
|
||||||
} else {
|
} else {
|
||||||
err = perf_session__write_header(session, evsel_list,
|
err = perf_session__write_header(session, evsel_list,
|
||||||
output, false);
|
file->fd, false);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto out_delete_session;
|
goto out_delete_session;
|
||||||
}
|
}
|
||||||
|
@ -455,11 +458,11 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
goto out_delete_session;
|
goto out_delete_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
rec->post_processing_offset = lseek(output, 0, SEEK_CUR);
|
rec->post_processing_offset = lseek(file->fd, 0, SEEK_CUR);
|
||||||
|
|
||||||
machine = &session->machines.host;
|
machine = &session->machines.host;
|
||||||
|
|
||||||
if (opts->pipe_output) {
|
if (file->is_pipe) {
|
||||||
err = perf_event__synthesize_attrs(tool, session,
|
err = perf_event__synthesize_attrs(tool, session,
|
||||||
process_synthesized_event);
|
process_synthesized_event);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -476,7 +479,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
|
||||||
* return this more properly and also
|
* return this more properly and also
|
||||||
* propagate errors that now are calling die()
|
* propagate errors that now are calling die()
|
||||||
*/
|
*/
|
||||||
err = perf_event__synthesize_tracing_data(tool, output, evsel_list,
|
err = perf_event__synthesize_tracing_data(tool, file->fd, evsel_list,
|
||||||
process_synthesized_event);
|
process_synthesized_event);
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
pr_err("Couldn't record tracing data.\n");
|
pr_err("Couldn't record tracing data.\n");
|
||||||
|
@ -845,7 +848,7 @@ const struct option record_options[] = {
|
||||||
OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
|
OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
|
||||||
"list of cpus to monitor"),
|
"list of cpus to monitor"),
|
||||||
OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
|
OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
|
||||||
OPT_STRING('o', "output", &record.output_name, "file",
|
OPT_STRING('o', "output", &record.file.path, "file",
|
||||||
"output file name"),
|
"output file name"),
|
||||||
OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
|
OPT_BOOLEAN('i', "no-inherit", &record.opts.no_inherit,
|
||||||
"child tasks do not inherit counters"),
|
"child tasks do not inherit counters"),
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
#include "util/hist.h"
|
#include "util/hist.h"
|
||||||
|
#include "util/data.h"
|
||||||
#include "arch/common.h"
|
#include "arch/common.h"
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
@ -857,6 +858,9 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"Don't show entries under that percent", parse_percent_limit),
|
"Don't show entries under that percent", parse_percent_limit),
|
||||||
OPT_END()
|
OPT_END()
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
perf_config(perf_report_config, &report);
|
perf_config(perf_report_config, &report);
|
||||||
|
|
||||||
|
@ -886,9 +890,11 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
perf_hpp__init();
|
perf_hpp__init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
file.path = input_name;
|
||||||
|
file.force = report.force;
|
||||||
|
|
||||||
repeat:
|
repeat:
|
||||||
session = perf_session__new(input_name, O_RDONLY,
|
session = perf_session__new(&file, false, &report.tool);
|
||||||
report.force, false, &report.tool);
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -1446,8 +1446,12 @@ static int perf_sched__read_events(struct perf_sched *sched,
|
||||||
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
|
{ "sched:sched_migrate_task", process_sched_migrate_task_event, },
|
||||||
};
|
};
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false, &sched->tool);
|
session = perf_session__new(&file, false, &sched->tool);
|
||||||
if (session == NULL) {
|
if (session == NULL) {
|
||||||
pr_debug("No Memory for session\n");
|
pr_debug("No Memory for session\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "util/evlist.h"
|
#include "util/evlist.h"
|
||||||
#include "util/evsel.h"
|
#include "util/evsel.h"
|
||||||
#include "util/sort.h"
|
#include "util/sort.h"
|
||||||
|
#include "util/data.h"
|
||||||
#include <linux/bitmap.h>
|
#include <linux/bitmap.h>
|
||||||
|
|
||||||
static char const *script_name;
|
static char const *script_name;
|
||||||
|
@ -1115,10 +1116,14 @@ int find_scripts(char **scripts_array, char **scripts_path_array)
|
||||||
char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
|
char scripts_path[MAXPATHLEN], lang_path[MAXPATHLEN];
|
||||||
DIR *scripts_dir, *lang_dir;
|
DIR *scripts_dir, *lang_dir;
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
char *temp;
|
char *temp;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false, NULL);
|
session = perf_session__new(&file, false, NULL);
|
||||||
if (!session)
|
if (!session)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -1319,12 +1324,17 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
"perf script [<options>] <top-script> [script-args]",
|
"perf script [<options>] <top-script> [script-args]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
setup_scripting();
|
setup_scripting();
|
||||||
|
|
||||||
argc = parse_options(argc, argv, options, script_usage,
|
argc = parse_options(argc, argv, options, script_usage,
|
||||||
PARSE_OPT_STOP_AT_NON_OPTION);
|
PARSE_OPT_STOP_AT_NON_OPTION);
|
||||||
|
|
||||||
|
file.path = input_name;
|
||||||
|
|
||||||
if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
|
if (argc > 1 && !strncmp(argv[0], "rec", strlen("rec"))) {
|
||||||
rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
|
rec_script_path = get_script_path(argv[1], RECORD_SUFFIX);
|
||||||
if (!rec_script_path)
|
if (!rec_script_path)
|
||||||
|
@ -1488,8 +1498,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
if (!script_name)
|
if (!script_name)
|
||||||
setup_pager();
|
setup_pager();
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false,
|
session = perf_session__new(&file, false, &perf_script);
|
||||||
&perf_script);
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "util/session.h"
|
#include "util/session.h"
|
||||||
#include "util/svghelper.h"
|
#include "util/svghelper.h"
|
||||||
#include "util/tool.h"
|
#include "util/tool.h"
|
||||||
|
#include "util/data.h"
|
||||||
|
|
||||||
#define SUPPORT_OLD_POWER_EVENTS 1
|
#define SUPPORT_OLD_POWER_EVENTS 1
|
||||||
#define PWR_EVENT_EXIT -1
|
#define PWR_EVENT_EXIT -1
|
||||||
|
@ -990,8 +991,13 @@ static int __cmd_timechart(const char *output_name)
|
||||||
{ "power:power_frequency", process_sample_power_frequency },
|
{ "power:power_frequency", process_sample_power_frequency },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
struct perf_session *session = perf_session__new(input_name, O_RDONLY,
|
struct perf_data_file file = {
|
||||||
0, false, &perf_timechart);
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct perf_session *session = perf_session__new(&file, false,
|
||||||
|
&perf_timechart);
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
|
|
|
@ -929,11 +929,15 @@ static int __cmd_top(struct perf_top *top)
|
||||||
struct perf_record_opts *opts = &top->record_opts;
|
struct perf_record_opts *opts = &top->record_opts;
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.mode = PERF_DATA_MODE_WRITE,
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME: perf_session__new should allow passing a O_MMAP, so that all this
|
* FIXME: perf_session__new should allow passing a O_MMAP, so that all this
|
||||||
* mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
|
* mmap reading, etc is encapsulated in it. Use O_WRONLY for now.
|
||||||
*/
|
*/
|
||||||
top->session = perf_session__new(NULL, O_WRONLY, false, false, NULL);
|
top->session = perf_session__new(&file, false, NULL);
|
||||||
if (top->session == NULL)
|
if (top->session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -1834,7 +1834,10 @@ static int trace__replay(struct trace *trace)
|
||||||
{ "raw_syscalls:sys_exit", trace__sys_exit, },
|
{ "raw_syscalls:sys_exit", trace__sys_exit, },
|
||||||
{ "probe:vfs_getname", trace__vfs_getname, },
|
{ "probe:vfs_getname", trace__vfs_getname, },
|
||||||
};
|
};
|
||||||
|
struct perf_data_file file = {
|
||||||
|
.path = input_name,
|
||||||
|
.mode = PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
struct perf_session *session;
|
struct perf_session *session;
|
||||||
int err = -1;
|
int err = -1;
|
||||||
|
|
||||||
|
@ -1857,8 +1860,7 @@ static int trace__replay(struct trace *trace)
|
||||||
if (symbol__init() < 0)
|
if (symbol__init() < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
session = perf_session__new(input_name, O_RDONLY, 0, false,
|
session = perf_session__new(&file, false, &trace->tool);
|
||||||
&trace->tool);
|
|
||||||
if (session == NULL)
|
if (session == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
|
|
@ -220,7 +220,6 @@ struct perf_record_opts {
|
||||||
bool no_delay;
|
bool no_delay;
|
||||||
bool no_inherit;
|
bool no_inherit;
|
||||||
bool no_samples;
|
bool no_samples;
|
||||||
bool pipe_output;
|
|
||||||
bool raw_samples;
|
bool raw_samples;
|
||||||
bool sample_address;
|
bool sample_address;
|
||||||
bool sample_weight;
|
bool sample_weight;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef __PERF_DATA_H
|
||||||
|
#define __PERF_DATA_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
enum perf_data_mode {
|
||||||
|
PERF_DATA_MODE_WRITE,
|
||||||
|
PERF_DATA_MODE_READ,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct perf_data_file {
|
||||||
|
const char *path;
|
||||||
|
int fd;
|
||||||
|
bool is_pipe;
|
||||||
|
bool force;
|
||||||
|
enum perf_data_mode mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline bool perf_data_file__is_read(struct perf_data_file *file)
|
||||||
|
{
|
||||||
|
return file->mode == PERF_DATA_MODE_READ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool perf_data_file__is_write(struct perf_data_file *file)
|
||||||
|
{
|
||||||
|
return file->mode == PERF_DATA_MODE_WRITE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __PERF_DATA_H */
|
|
@ -106,11 +106,11 @@ static void perf_session__destroy_kernel_maps(struct perf_session *self)
|
||||||
machines__destroy_kernel_maps(&self->machines);
|
machines__destroy_kernel_maps(&self->machines);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct perf_session *perf_session__new(const char *filename, int mode,
|
struct perf_session *perf_session__new(struct perf_data_file *file,
|
||||||
bool force, bool repipe,
|
bool repipe, struct perf_tool *tool)
|
||||||
struct perf_tool *tool)
|
|
||||||
{
|
{
|
||||||
struct perf_session *self;
|
struct perf_session *self;
|
||||||
|
const char *filename = file->path;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
||||||
|
@ -134,11 +134,11 @@ struct perf_session *perf_session__new(const char *filename, int mode,
|
||||||
INIT_LIST_HEAD(&self->ordered_samples.to_free);
|
INIT_LIST_HEAD(&self->ordered_samples.to_free);
|
||||||
machines__init(&self->machines);
|
machines__init(&self->machines);
|
||||||
|
|
||||||
if (mode == O_RDONLY) {
|
if (perf_data_file__is_read(file)) {
|
||||||
if (perf_session__open(self, force) < 0)
|
if (perf_session__open(self, file->force) < 0)
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
perf_session__set_id_hdr_size(self);
|
perf_session__set_id_hdr_size(self);
|
||||||
} else if (mode == O_WRONLY) {
|
} else if (perf_data_file__is_write(file)) {
|
||||||
/*
|
/*
|
||||||
* In O_RDONLY mode this will be performed when reading the
|
* In O_RDONLY mode this will be performed when reading the
|
||||||
* kernel MMAP event, in perf_event__process_mmap().
|
* kernel MMAP event, in perf_event__process_mmap().
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include "machine.h"
|
#include "machine.h"
|
||||||
#include "symbol.h"
|
#include "symbol.h"
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
#include "data.h"
|
||||||
#include <linux/rbtree.h>
|
#include <linux/rbtree.h>
|
||||||
#include <linux/perf_event.h>
|
#include <linux/perf_event.h>
|
||||||
|
|
||||||
|
@ -49,9 +50,8 @@ struct perf_session {
|
||||||
|
|
||||||
struct perf_tool;
|
struct perf_tool;
|
||||||
|
|
||||||
struct perf_session *perf_session__new(const char *filename, int mode,
|
struct perf_session *perf_session__new(struct perf_data_file *file,
|
||||||
bool force, bool repipe,
|
bool repipe, struct perf_tool *tool);
|
||||||
struct perf_tool *tool);
|
|
||||||
void perf_session__delete(struct perf_session *session);
|
void perf_session__delete(struct perf_session *session);
|
||||||
|
|
||||||
void perf_event_header__bswap(struct perf_event_header *self);
|
void perf_event_header__bswap(struct perf_event_header *self);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче