perf session: Separating data file properties from session
Removing 'fd, fd_pipe, filename, size' from struct perf_session and replacing them with struct perf_data_file object. 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-4-git-send-email-jolsa@redhat.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
parent
6a4d98d787
commit
cc9784bd9f
|
@ -259,7 +259,7 @@ static int __cmd_annotate(struct perf_annotate *ann)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total_nr_samples == 0) {
|
if (total_nr_samples == 0) {
|
||||||
ui__error("The %s file has no samples!\n", session->filename);
|
ui__error("The %s file has no samples!\n", file.path);
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ static int perf_session__list_build_ids(bool force, bool with_hits)
|
||||||
* in pipe-mode, the only way to get the buildids is to parse
|
* in pipe-mode, the only way to get the buildids is to parse
|
||||||
* the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
|
* the record stream. Buildids are stored as RECORD_HEADER_BUILD_ID
|
||||||
*/
|
*/
|
||||||
if (with_hits || session->fd_pipe)
|
if (with_hits || perf_data_file__is_pipe(&file))
|
||||||
perf_session__process_events(session, &build_id__mark_dso_hit_ops);
|
perf_session__process_events(session, &build_id__mark_dso_hit_ops);
|
||||||
|
|
||||||
perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
|
perf_session__fprintf_dsos_buildid(session, stdout, dso__skip_buildid, with_hits);
|
||||||
|
|
|
@ -257,7 +257,6 @@ static int process_buildids(struct perf_record *rec)
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
session->fd = file->fd;
|
|
||||||
return __perf_session__process_events(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);
|
||||||
|
|
|
@ -368,8 +368,9 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
|
||||||
{
|
{
|
||||||
struct perf_session *self = rep->session;
|
struct perf_session *self = rep->session;
|
||||||
u64 sample_type = perf_evlist__combined_sample_type(self->evlist);
|
u64 sample_type = perf_evlist__combined_sample_type(self->evlist);
|
||||||
|
bool is_pipe = perf_data_file__is_pipe(self->file);
|
||||||
|
|
||||||
if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
|
if (!is_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) {
|
||||||
if (sort__has_parent) {
|
if (sort__has_parent) {
|
||||||
ui__error("Selected --sort parent, but no "
|
ui__error("Selected --sort parent, but no "
|
||||||
"callchain data. Did you call "
|
"callchain data. Did you call "
|
||||||
|
@ -392,7 +393,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sort__mode == SORT_MODE__BRANCH) {
|
if (sort__mode == SORT_MODE__BRANCH) {
|
||||||
if (!self->fd_pipe &&
|
if (!is_pipe &&
|
||||||
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
|
!(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
|
||||||
ui__error("Selected -b but no branch data. "
|
ui__error("Selected -b but no branch data. "
|
||||||
"Did you call perf record without -b?\n");
|
"Did you call perf record without -b?\n");
|
||||||
|
@ -488,6 +489,7 @@ static int __cmd_report(struct perf_report *rep)
|
||||||
struct map *kernel_map;
|
struct map *kernel_map;
|
||||||
struct kmap *kernel_kmap;
|
struct kmap *kernel_kmap;
|
||||||
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
|
const char *help = "For a higher level overview, try: perf report --sort comm,dso";
|
||||||
|
struct perf_data_file *file = session->file;
|
||||||
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
|
||||||
|
@ -572,7 +574,7 @@ static int __cmd_report(struct perf_report *rep)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (nr_samples == 0) {
|
if (nr_samples == 0) {
|
||||||
ui__error("The %s file has no samples!\n", session->filename);
|
ui__error("The %s file has no samples!\n", file->path);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1525,7 +1525,7 @@ int cmd_script(int argc, const char **argv, const char *prefix __maybe_unused)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
input = open(session->filename, O_RDONLY); /* input_name */
|
input = open(file.path, O_RDONLY); /* input_name */
|
||||||
if (input < 0) {
|
if (input < 0) {
|
||||||
perror("failed to open file");
|
perror("failed to open file");
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -27,6 +27,21 @@ static inline bool perf_data_file__is_write(struct perf_data_file *file)
|
||||||
return file->mode == PERF_DATA_MODE_WRITE;
|
return file->mode == PERF_DATA_MODE_WRITE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int perf_data_file__is_pipe(struct perf_data_file *file)
|
||||||
|
{
|
||||||
|
return file->is_pipe;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int perf_data_file__fd(struct perf_data_file *file)
|
||||||
|
{
|
||||||
|
return file->fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long perf_data_file__size(struct perf_data_file *file)
|
||||||
|
{
|
||||||
|
return file->size;
|
||||||
|
}
|
||||||
|
|
||||||
int perf_data_file__open(struct perf_data_file *file);
|
int perf_data_file__open(struct perf_data_file *file);
|
||||||
void perf_data_file__close(struct perf_data_file *file);
|
void perf_data_file__close(struct perf_data_file *file);
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#include "vdso.h"
|
#include "vdso.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
#include "build-id.h"
|
#include "build-id.h"
|
||||||
|
#include "data.h"
|
||||||
|
|
||||||
static bool no_buildid_cache = false;
|
static bool no_buildid_cache = false;
|
||||||
|
|
||||||
|
@ -2189,7 +2190,7 @@ int perf_header__fprintf_info(struct perf_session *session, FILE *fp, bool full)
|
||||||
{
|
{
|
||||||
struct header_print_data hd;
|
struct header_print_data hd;
|
||||||
struct perf_header *header = &session->header;
|
struct perf_header *header = &session->header;
|
||||||
int fd = session->fd;
|
int fd = perf_data_file__fd(session->file);
|
||||||
hd.fp = fp;
|
hd.fp = fp;
|
||||||
hd.full = full;
|
hd.full = full;
|
||||||
|
|
||||||
|
@ -2650,7 +2651,8 @@ static int perf_header__read_pipe(struct perf_session *session)
|
||||||
struct perf_header *header = &session->header;
|
struct perf_header *header = &session->header;
|
||||||
struct perf_pipe_file_header f_header;
|
struct perf_pipe_file_header f_header;
|
||||||
|
|
||||||
if (perf_file_header__read_pipe(&f_header, header, session->fd,
|
if (perf_file_header__read_pipe(&f_header, header,
|
||||||
|
perf_data_file__fd(session->file),
|
||||||
session->repipe) < 0) {
|
session->repipe) < 0) {
|
||||||
pr_debug("incompatible file format\n");
|
pr_debug("incompatible file format\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -2751,18 +2753,19 @@ static int perf_evlist__prepare_tracepoint_events(struct perf_evlist *evlist,
|
||||||
|
|
||||||
int perf_session__read_header(struct perf_session *session)
|
int perf_session__read_header(struct perf_session *session)
|
||||||
{
|
{
|
||||||
|
struct perf_data_file *file = session->file;
|
||||||
struct perf_header *header = &session->header;
|
struct perf_header *header = &session->header;
|
||||||
struct perf_file_header f_header;
|
struct perf_file_header f_header;
|
||||||
struct perf_file_attr f_attr;
|
struct perf_file_attr f_attr;
|
||||||
u64 f_id;
|
u64 f_id;
|
||||||
int nr_attrs, nr_ids, i, j;
|
int nr_attrs, nr_ids, i, j;
|
||||||
int fd = session->fd;
|
int fd = perf_data_file__fd(file);
|
||||||
|
|
||||||
session->evlist = perf_evlist__new();
|
session->evlist = perf_evlist__new();
|
||||||
if (session->evlist == NULL)
|
if (session->evlist == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (session->fd_pipe)
|
if (perf_data_file__is_pipe(file))
|
||||||
return perf_header__read_pipe(session);
|
return perf_header__read_pipe(session);
|
||||||
|
|
||||||
if (perf_file_header__read(&f_header, header, fd) < 0)
|
if (perf_file_header__read(&f_header, header, fd) < 0)
|
||||||
|
@ -2777,7 +2780,7 @@ int perf_session__read_header(struct perf_session *session)
|
||||||
if (f_header.data.size == 0) {
|
if (f_header.data.size == 0) {
|
||||||
pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
|
pr_warning("WARNING: The %s file's data size field is 0 which is unexpected.\n"
|
||||||
"Was the 'perf record' command properly terminated?\n",
|
"Was the 'perf record' command properly terminated?\n",
|
||||||
session->filename);
|
file->path);
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_attrs = f_header.attrs.size / f_header.attr_size;
|
nr_attrs = f_header.attrs.size / f_header.attr_size;
|
||||||
|
@ -2990,18 +2993,19 @@ int perf_event__process_tracing_data(struct perf_tool *tool __maybe_unused,
|
||||||
struct perf_session *session)
|
struct perf_session *session)
|
||||||
{
|
{
|
||||||
ssize_t size_read, padding, size = event->tracing_data.size;
|
ssize_t size_read, padding, size = event->tracing_data.size;
|
||||||
off_t offset = lseek(session->fd, 0, SEEK_CUR);
|
int fd = perf_data_file__fd(session->file);
|
||||||
|
off_t offset = lseek(fd, 0, SEEK_CUR);
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
|
|
||||||
/* setup for reading amidst mmap */
|
/* setup for reading amidst mmap */
|
||||||
lseek(session->fd, offset + sizeof(struct tracing_data_event),
|
lseek(fd, offset + sizeof(struct tracing_data_event),
|
||||||
SEEK_SET);
|
SEEK_SET);
|
||||||
|
|
||||||
size_read = trace_report(session->fd, &session->pevent,
|
size_read = trace_report(fd, &session->pevent,
|
||||||
session->repipe);
|
session->repipe);
|
||||||
padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
|
padding = PERF_ALIGN(size_read, sizeof(u64)) - size_read;
|
||||||
|
|
||||||
if (readn(session->fd, buf, padding) < 0) {
|
if (readn(fd, buf, padding) < 0) {
|
||||||
pr_err("%s: reading input file", __func__);
|
pr_err("%s: reading input file", __func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,17 +18,16 @@
|
||||||
|
|
||||||
static int perf_session__open(struct perf_session *self)
|
static int perf_session__open(struct perf_session *self)
|
||||||
{
|
{
|
||||||
if (self->fd_pipe) {
|
struct perf_data_file *file = self->file;
|
||||||
if (perf_session__read_header(self) < 0)
|
|
||||||
pr_err("incompatible file format (rerun with -v to learn more)");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (perf_session__read_header(self) < 0) {
|
if (perf_session__read_header(self) < 0) {
|
||||||
pr_err("incompatible file format (rerun with -v to learn more)");
|
pr_err("incompatible file format (rerun with -v to learn more)");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (perf_data_file__is_pipe(file))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!perf_evlist__valid_sample_type(self->evlist)) {
|
if (!perf_evlist__valid_sample_type(self->evlist)) {
|
||||||
pr_err("non matching sample_type");
|
pr_err("non matching sample_type");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -87,10 +86,7 @@ struct perf_session *perf_session__new(struct perf_data_file *file,
|
||||||
if (perf_data_file__open(file))
|
if (perf_data_file__open(file))
|
||||||
goto out_delete;
|
goto out_delete;
|
||||||
|
|
||||||
self->fd = file->fd;
|
self->file = file;
|
||||||
self->fd_pipe = file->is_pipe;
|
|
||||||
self->filename = file->path;
|
|
||||||
self->size = file->size;
|
|
||||||
|
|
||||||
if (perf_data_file__is_read(file)) {
|
if (perf_data_file__is_read(file)) {
|
||||||
if (perf_session__open(self) < 0)
|
if (perf_session__open(self) < 0)
|
||||||
|
@ -158,7 +154,8 @@ void perf_session__delete(struct perf_session *self)
|
||||||
perf_session__delete_threads(self);
|
perf_session__delete_threads(self);
|
||||||
perf_session_env__delete(&self->header.env);
|
perf_session_env__delete(&self->header.env);
|
||||||
machines__exit(&self->machines);
|
machines__exit(&self->machines);
|
||||||
close(self->fd);
|
if (self->file)
|
||||||
|
perf_data_file__close(self->file);
|
||||||
free(self);
|
free(self);
|
||||||
vdso__exit();
|
vdso__exit();
|
||||||
}
|
}
|
||||||
|
@ -1015,6 +1012,7 @@ static int perf_session_deliver_event(struct perf_session *session,
|
||||||
static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
|
static int perf_session__process_user_event(struct perf_session *session, union perf_event *event,
|
||||||
struct perf_tool *tool, u64 file_offset)
|
struct perf_tool *tool, u64 file_offset)
|
||||||
{
|
{
|
||||||
|
int fd = perf_data_file__fd(session->file);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
dump_event(session, event, file_offset, NULL);
|
dump_event(session, event, file_offset, NULL);
|
||||||
|
@ -1028,7 +1026,7 @@ static int perf_session__process_user_event(struct perf_session *session, union
|
||||||
return err;
|
return err;
|
||||||
case PERF_RECORD_HEADER_TRACING_DATA:
|
case PERF_RECORD_HEADER_TRACING_DATA:
|
||||||
/* setup for reading amidst mmap */
|
/* setup for reading amidst mmap */
|
||||||
lseek(session->fd, file_offset, SEEK_SET);
|
lseek(fd, file_offset, SEEK_SET);
|
||||||
return tool->tracing_data(tool, event, session);
|
return tool->tracing_data(tool, event, session);
|
||||||
case PERF_RECORD_HEADER_BUILD_ID:
|
case PERF_RECORD_HEADER_BUILD_ID:
|
||||||
return tool->build_id(tool, event, session);
|
return tool->build_id(tool, event, session);
|
||||||
|
@ -1154,6 +1152,7 @@ volatile int session_done;
|
||||||
static int __perf_session__process_pipe_events(struct perf_session *self,
|
static int __perf_session__process_pipe_events(struct perf_session *self,
|
||||||
struct perf_tool *tool)
|
struct perf_tool *tool)
|
||||||
{
|
{
|
||||||
|
int fd = perf_data_file__fd(self->file);
|
||||||
union perf_event *event;
|
union perf_event *event;
|
||||||
uint32_t size, cur_size = 0;
|
uint32_t size, cur_size = 0;
|
||||||
void *buf = NULL;
|
void *buf = NULL;
|
||||||
|
@ -1172,7 +1171,7 @@ static int __perf_session__process_pipe_events(struct perf_session *self,
|
||||||
return -errno;
|
return -errno;
|
||||||
more:
|
more:
|
||||||
event = buf;
|
event = buf;
|
||||||
err = readn(self->fd, event, sizeof(struct perf_event_header));
|
err = readn(fd, event, sizeof(struct perf_event_header));
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
if (err == 0)
|
if (err == 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -1204,7 +1203,7 @@ more:
|
||||||
p += sizeof(struct perf_event_header);
|
p += sizeof(struct perf_event_header);
|
||||||
|
|
||||||
if (size - sizeof(struct perf_event_header)) {
|
if (size - sizeof(struct perf_event_header)) {
|
||||||
err = readn(self->fd, p, size - sizeof(struct perf_event_header));
|
err = readn(fd, p, size - sizeof(struct perf_event_header));
|
||||||
if (err <= 0) {
|
if (err <= 0) {
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
pr_err("unexpected end of event stream\n");
|
pr_err("unexpected end of event stream\n");
|
||||||
|
@ -1285,6 +1284,7 @@ int __perf_session__process_events(struct perf_session *session,
|
||||||
u64 data_offset, u64 data_size,
|
u64 data_offset, u64 data_size,
|
||||||
u64 file_size, struct perf_tool *tool)
|
u64 file_size, struct perf_tool *tool)
|
||||||
{
|
{
|
||||||
|
int fd = perf_data_file__fd(session->file);
|
||||||
u64 head, page_offset, file_offset, file_pos, progress_next;
|
u64 head, page_offset, file_offset, file_pos, progress_next;
|
||||||
int err, mmap_prot, mmap_flags, map_idx = 0;
|
int err, mmap_prot, mmap_flags, map_idx = 0;
|
||||||
size_t mmap_size;
|
size_t mmap_size;
|
||||||
|
@ -1317,7 +1317,7 @@ int __perf_session__process_events(struct perf_session *session,
|
||||||
mmap_flags = MAP_PRIVATE;
|
mmap_flags = MAP_PRIVATE;
|
||||||
}
|
}
|
||||||
remap:
|
remap:
|
||||||
buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, session->fd,
|
buf = mmap(NULL, mmap_size, mmap_prot, mmap_flags, fd,
|
||||||
file_offset);
|
file_offset);
|
||||||
if (buf == MAP_FAILED) {
|
if (buf == MAP_FAILED) {
|
||||||
pr_err("failed to mmap file\n");
|
pr_err("failed to mmap file\n");
|
||||||
|
@ -1382,16 +1382,17 @@ out_err:
|
||||||
int perf_session__process_events(struct perf_session *self,
|
int perf_session__process_events(struct perf_session *self,
|
||||||
struct perf_tool *tool)
|
struct perf_tool *tool)
|
||||||
{
|
{
|
||||||
|
u64 size = perf_data_file__size(self->file);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (perf_session__register_idle_thread(self) == NULL)
|
if (perf_session__register_idle_thread(self) == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (!self->fd_pipe)
|
if (!perf_data_file__is_pipe(self->file))
|
||||||
err = __perf_session__process_events(self,
|
err = __perf_session__process_events(self,
|
||||||
self->header.data_offset,
|
self->header.data_offset,
|
||||||
self->header.data_size,
|
self->header.data_size,
|
||||||
self->size, tool);
|
size, tool);
|
||||||
else
|
else
|
||||||
err = __perf_session__process_pipe_events(self, tool);
|
err = __perf_session__process_pipe_events(self, tool);
|
||||||
|
|
||||||
|
@ -1615,13 +1616,14 @@ int perf_session__cpu_bitmap(struct perf_session *session,
|
||||||
void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
|
void perf_session__fprintf_info(struct perf_session *session, FILE *fp,
|
||||||
bool full)
|
bool full)
|
||||||
{
|
{
|
||||||
|
int fd = perf_data_file__fd(session->file);
|
||||||
struct stat st;
|
struct stat st;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (session == NULL || fp == NULL)
|
if (session == NULL || fp == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ret = fstat(session->fd, &st);
|
ret = fstat(fd, &st);
|
||||||
if (ret == -1)
|
if (ret == -1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -30,16 +30,13 @@ struct ordered_samples {
|
||||||
|
|
||||||
struct perf_session {
|
struct perf_session {
|
||||||
struct perf_header header;
|
struct perf_header header;
|
||||||
unsigned long size;
|
|
||||||
struct machines machines;
|
struct machines machines;
|
||||||
struct perf_evlist *evlist;
|
struct perf_evlist *evlist;
|
||||||
struct pevent *pevent;
|
struct pevent *pevent;
|
||||||
struct events_stats stats;
|
struct events_stats stats;
|
||||||
int fd;
|
|
||||||
bool fd_pipe;
|
|
||||||
bool repipe;
|
bool repipe;
|
||||||
struct ordered_samples ordered_samples;
|
struct ordered_samples ordered_samples;
|
||||||
const char *filename;
|
struct perf_data_file *file;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PRINT_IP_OPT_IP (1<<0)
|
#define PRINT_IP_OPT_IP (1<<0)
|
||||||
|
|
Loading…
Reference in a new issue