Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 94c744b6 authored by Arnaldo Carvalho de Melo's avatar Arnaldo Carvalho de Melo Committed by Ingo Molnar
Browse files

perf tools: Introduce perf_session class



That does all the initialization boilerplate, opening the file,
reading the header, checking if it is valid, etc.

And that will as well have the threads list, kmap (now) global
variable, etc, so that we can handle two (or more) perf.data files
describing sessions to compare.

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Cc: Frédéric Weisbecker <fweisbec@gmail.com>
Cc: Mike Galbraith <efault@gmx.de>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Paul Mackerras <paulus@samba.org>
LKML-Reference: <1260573842-19720-1-git-send-email-acme@infradead.org>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent ea08d8cb
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -356,7 +356,9 @@ LIB_H += util/parse-options.h
LIB_H += util/parse-events.h
LIB_H += util/quote.h
LIB_H += util/util.h
LIB_H += util/header.h
LIB_H += util/help.h
LIB_H += util/session.h
LIB_H += util/strbuf.h
LIB_H += util/string.h
LIB_H += util/strlist.h
@@ -405,6 +407,7 @@ LIB_OBJS += util/callchain.o
LIB_OBJS += util/values.o
LIB_OBJS += util/debug.o
LIB_OBJS += util/map.o
LIB_OBJS += util/session.o
LIB_OBJS += util/thread.o
LIB_OBJS += util/trace-event-parse.o
LIB_OBJS += util/trace-event-read.o
+10 −5
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#include "util/thread.h"
#include "util/sort.h"
#include "util/hist.h"
#include "util/session.h"
#include "util/data_map.h"

static char		const *input_name = "perf.data";
@@ -462,21 +463,23 @@ static struct perf_file_handler file_handler = {

static int __cmd_annotate(void)
{
	struct perf_header *header;
	struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);
	struct thread *idle;
	int ret;

	if (session == NULL)
		return -ENOMEM;

	idle = register_idle_thread();
	register_perf_file_handler(&file_handler);

	ret = mmap_dispatch_perf_file(&header, input_name, 0, 0,
				      &event__cwdlen, &event__cwd);
	ret = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
	if (ret)
		return ret;
		goto out_delete;

	if (dump_trace) {
		event__print_totals();
		return 0;
		goto out_delete;
	}

	if (verbose > 3)
@@ -489,6 +492,8 @@ static int __cmd_annotate(void)
	output__resort(event__total[0]);

	find_annotations();
out_delete:
	perf_session__delete(session);

	return ret;
}
+8 −47
Original line number Diff line number Diff line
@@ -11,8 +11,8 @@
#include "util/cache.h"
#include "util/data_map.h"
#include "util/debug.h"
#include "util/header.h"
#include "util/parse-options.h"
#include "util/session.h"
#include "util/symbol.h"

static char const *input_name = "perf.data";
@@ -55,56 +55,17 @@ static int perf_file_section__process_buildids(struct perf_file_section *self,
static int __cmd_buildid_list(void)
{
	int err = -1;
	struct perf_header *header;
	struct perf_file_header f_header;
	struct stat input_stat;
	int input = open(input_name, O_RDONLY);
	struct perf_session *session = perf_session__new(input_name, O_RDONLY, force);

	if (input < 0) {
		pr_err("failed to open file: %s", input_name);
		if (!strcmp(input_name, "perf.data"))
			pr_err("  (try 'perf record' first)");
		pr_err("\n");
		goto out;
	}

	err = fstat(input, &input_stat);
	if (err < 0) {
		perror("failed to stat file");
		goto out_close;
	}

	if (!force && input_stat.st_uid && (input_stat.st_uid != geteuid())) {
		pr_err("file %s not owned by current user or root\n",
		       input_name);
		goto out_close;
	}

	if (!input_stat.st_size) {
		pr_info("zero-sized file, nothing to do!\n");
		goto out_close;
	}

	err = -1;
	header = perf_header__new();
	if (header == NULL)
		goto out_close;

	if (perf_file_header__read(&f_header, header, input) < 0) {
		pr_warning("incompatible file format");
		goto out_close;
	}
	if (session == NULL)
		return -1;

	err = perf_header__process_sections(header, input,
	err = perf_header__process_sections(&session->header, session->fd,
				         perf_file_section__process_buildids);

	if (err < 0)
		goto out_close;

	if (err >= 0)
		dsos__fprintf_buildid(stdout);
out_close:
	close(input);
out:

	perf_session__delete(session);
	return err;
}

+10 −3
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#include "util/symbol.h"
#include "util/thread.h"
#include "util/header.h"
#include "util/session.h"

#include "util/parse-options.h"
#include "util/trace-event.h"
@@ -20,7 +21,6 @@ typedef int (*sort_fn_t)(struct alloc_stat *, struct alloc_stat *);

static char const		*input_name = "perf.data";

static struct perf_header	*header;
static u64			sample_type;

static int			alloc_flag;
@@ -367,11 +367,18 @@ static struct perf_file_handler file_handler = {

static int read_events(void)
{
	int err;
	struct perf_session *session = perf_session__new(input_name, O_RDONLY, 0);

	if (session == NULL)
		return -ENOMEM;

	register_idle_thread();
	register_perf_file_handler(&file_handler);

	return mmap_dispatch_perf_file(&header, input_name, 0, 0,
				       &event__cwdlen, &event__cwd);
	err = perf_session__process_events(session, 0, &event__cwdlen, &event__cwd);
	perf_session__delete(session);
	return err;
}

static double fragmentation(unsigned long n_req, unsigned long n_alloc)
+13 −12
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "util/header.h"
#include "util/event.h"
#include "util/debug.h"
#include "util/session.h"
#include "util/symbol.h"

#include <unistd.h>
@@ -62,7 +63,7 @@ static int nr_cpu = 0;

static int			file_new			=      1;

struct perf_header		*header				=   NULL;
static struct perf_session	*session;

struct mmap_data {
	int			counter;
@@ -216,12 +217,12 @@ static struct perf_header_attr *get_header_attr(struct perf_event_attr *a, int n
{
	struct perf_header_attr *h_attr;

	if (nr < header->attrs) {
		h_attr = header->attr[nr];
	if (nr < session->header.attrs) {
		h_attr = session->header.attr[nr];
	} else {
		h_attr = perf_header_attr__new(a);
		if (h_attr != NULL)
			if (perf_header__add_attr(header, h_attr) < 0) {
			if (perf_header__add_attr(&session->header, h_attr) < 0) {
				perf_header_attr__delete(h_attr);
				h_attr = NULL;
			}
@@ -395,9 +396,9 @@ static void open_counters(int cpu, pid_t pid)

static void atexit_header(void)
{
	header->data_size += bytes_written;
	session->header.data_size += bytes_written;

	perf_header__write(header, output, true);
	perf_header__write(&session->header, output, true);
}

static int __cmd_record(int argc, const char **argv)
@@ -440,24 +441,24 @@ static int __cmd_record(int argc, const char **argv)
		exit(-1);
	}

	header = perf_header__new();
	if (header == NULL) {
	session = perf_session__new(output_name, O_WRONLY, force);
	if (session == NULL) {
		pr_err("Not enough memory for reading perf file header\n");
		return -1;
	}

	if (!file_new) {
		err = perf_header__read(header, output);
		err = perf_header__read(&session->header, output);
		if (err < 0)
			return err;
	}

	if (raw_samples) {
		perf_header__set_feat(header, HEADER_TRACE_INFO);
		perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
	} else {
		for (i = 0; i < nr_counters; i++) {
			if (attrs[i].sample_type & PERF_SAMPLE_RAW) {
				perf_header__set_feat(header, HEADER_TRACE_INFO);
				perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
				break;
			}
		}
@@ -481,7 +482,7 @@ static int __cmd_record(int argc, const char **argv)
	}

	if (file_new) {
		err = perf_header__write(header, output, false);
		err = perf_header__write(&session->header, output, false);
		if (err < 0)
			return err;
	}
Loading