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

Commit 84b13fd5 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge branch 'perf/live' into perf/core



Conflicts:
	tools/perf/builtin-record.c

Merge reason: add the live tracing feature, resolve conflict.

Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parents f9212819 a0cccc2e
Loading
Loading
Loading
Loading
+61 −7
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ static unsigned int mmap_pages = 128;
static unsigned int		user_freq 			= UINT_MAX;
static int			freq				=   1000;
static int			output;
static int			pipe_output			=      0;
static const char		*output_name			= "perf.data";
static int			group				=      0;
static unsigned int		realtime_prio			=      0;
@@ -109,6 +110,11 @@ static void mmap_write_tail(struct mmap_data *md, unsigned long tail)
	pc->data_tail = tail;
}

static void advance_output(size_t size)
{
	bytes_written += size;
}

static void write_output(void *buf, size_t size)
{
	while (size) {
@@ -435,10 +441,19 @@ static int process_buildids(void)

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

		process_buildids();
		perf_header__write(&session->header, output, true);
	} else {
		int err;

		err = event__synthesize_build_ids(process_synthesized_event,
						  session);
		if (err < 0)
			pr_err("Couldn't synthesize build ids.\n");
	}
}

static int __cmd_record(int argc, const char **argv)
@@ -464,7 +479,9 @@ static int __cmd_record(int argc, const char **argv)
		exit(-1);
	}

	if (!stat(output_name, &st) && st.st_size) {
	if (!strcmp(output_name, "-"))
		pipe_output = 1;
	else if (!stat(output_name, &st) && st.st_size) {
		if (write_mode == WRITE_FORCE) {
			char oldname[PATH_MAX];
			snprintf(oldname, sizeof(oldname), "%s.old",
@@ -482,6 +499,9 @@ static int __cmd_record(int argc, const char **argv)
	else
		flags |= O_TRUNC;

	if (pipe_output)
		output = STDOUT_FILENO;
	else
		output = open(output_name, flags, S_IRUSR | S_IWUSR);
	if (output < 0) {
		perror("failed to create output file");
@@ -496,7 +516,7 @@ static int __cmd_record(int argc, const char **argv)
	}

	if (!file_new) {
		err = perf_header__read(&session->header, output);
		err = perf_header__read(session, output);
		if (err < 0)
			return err;
	}
@@ -522,6 +542,8 @@ static int __cmd_record(int argc, const char **argv)
		}

		if (!child_pid) {
			if (pipe_output)
				dup2(2, 1);
			close(child_ready_pipe[0]);
			close(go_pipe[1]);
			fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -573,7 +595,11 @@ static int __cmd_record(int argc, const char **argv)
			open_counters(cpumap[i]);
	}

	if (file_new) {
	if (pipe_output) {
		err = perf_header__write_pipe(output);
		if (err < 0)
			return err;
	} else if (file_new) {
		err = perf_header__write(&session->header, output, false);
		if (err < 0)
			return err;
@@ -581,6 +607,34 @@ static int __cmd_record(int argc, const char **argv)

	post_processing_offset = lseek(output, 0, SEEK_CUR);

	if (pipe_output) {
		err = event__synthesize_attrs(&session->header,
					      process_synthesized_event,
					      session);
		if (err < 0) {
			pr_err("Couldn't synthesize attrs.\n");
			return err;
		}

		err = event__synthesize_event_types(process_synthesized_event,
						    session);
		if (err < 0) {
			pr_err("Couldn't synthesize event_types.\n");
			return err;
		}

		err = event__synthesize_tracing_data(output, attrs,
						     nr_counters,
						     process_synthesized_event,
						     session);
		if (err <= 0) {
			pr_err("Couldn't record tracing data.\n");
			return err;
		}

		advance_output(err);
	}

	err = event__synthesize_kernel_mmap(process_synthesized_event,
					    session, "_text");
	if (err < 0)
+15 −1
Original line number Diff line number Diff line
@@ -267,8 +267,19 @@ static struct perf_event_ops event_ops = {
	.fork	= event__process_task,
	.lost	= event__process_lost,
	.read	= process_read_event,
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
	.tracing_data = event__process_tracing_data,
	.build_id = event__process_build_id,
};

extern volatile int session_done;

static void sig_handler(int sig __attribute__((__unused__)))
{
	session_done = 1;
}

static int __cmd_report(void)
{
	int ret = -EINVAL;
@@ -276,6 +287,8 @@ static int __cmd_report(void)
	struct rb_node *next;
	const char *help = "For a higher level overview, try: perf report --sort comm,dso";

	signal(SIGINT, sig_handler);

	session = perf_session__new(input_name, O_RDONLY, force);
	if (session == NULL)
		return -ENOMEM;
@@ -465,6 +478,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __used)
{
	argc = parse_options(argc, argv, options, report_usage, 0);

	if (strcmp(input_name, "-") != 0)
		setup_browser();

	if (symbol__init() < 0)
+74 −1
Original line number Diff line number Diff line
@@ -104,10 +104,23 @@ static int process_sample_event(event_t *event, struct perf_session *session)
static struct perf_event_ops event_ops = {
	.sample	= process_sample_event,
	.comm	= event__process_comm,
	.attr	= event__process_attr,
	.event_type = event__process_event_type,
	.tracing_data = event__process_tracing_data,
	.build_id = event__process_build_id,
};

extern volatile int session_done;

static void sig_handler(int sig __unused)
{
	session_done = 1;
}

static int __cmd_trace(struct perf_session *session)
{
	signal(SIGINT, sig_handler);

	return perf_session__process_events(session, &event_ops);
}

@@ -548,6 +561,65 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
		suffix = REPORT_SUFFIX;
	}

	if (!suffix && argc >= 2 && strncmp(argv[1], "-", strlen("-")) != 0) {
		char *record_script_path, *report_script_path;
		int live_pipe[2];
		pid_t pid;

		record_script_path = get_script_path(argv[1], RECORD_SUFFIX);
		if (!record_script_path) {
			fprintf(stderr, "record script not found\n");
			return -1;
		}

		report_script_path = get_script_path(argv[1], REPORT_SUFFIX);
		if (!report_script_path) {
			fprintf(stderr, "report script not found\n");
			return -1;
		}

		if (pipe(live_pipe) < 0) {
			perror("failed to create pipe");
			exit(-1);
		}

		pid = fork();
		if (pid < 0) {
			perror("failed to fork");
			exit(-1);
		}

		if (!pid) {
			dup2(live_pipe[1], 1);
			close(live_pipe[0]);

			__argv = malloc(5 * sizeof(const char *));
			__argv[0] = "/bin/sh";
			__argv[1] = record_script_path;
			__argv[2] = "-o";
			__argv[3] = "-";
			__argv[4] = NULL;

			execvp("/bin/sh", (char **)__argv);
			exit(-1);
		}

		dup2(live_pipe[0], 0);
		close(live_pipe[1]);

		__argv = malloc((argc + 3) * sizeof(const char *));
		__argv[0] = "/bin/sh";
		__argv[1] = report_script_path;
		for (i = 2; i < argc; i++)
			__argv[i] = argv[i];
		__argv[i++] = "-i";
		__argv[i++] = "-";
		__argv[i++] = NULL;

		execvp("/bin/sh", (char **)__argv);
		exit(-1);
	}

	if (suffix) {
		script_path = get_script_path(argv[2], suffix);
		if (!script_path) {
@@ -580,7 +652,8 @@ int cmd_trace(int argc, const char **argv, const char *prefix __used)
	if (session == NULL)
		return -ENOMEM;

	if (!perf_session__has_traces(session, "record -R"))
	if (strcmp(input_name, "-") &&
	    !perf_session__has_traces(session, "record -R"))
		return -EINVAL;

	if (generate_script_lang) {
+6 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@ our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );

our @EXPORT = qw(
avg nsecs nsecs_secs nsecs_nsecs nsecs_usecs print_nsecs
clear_term
);

our $VERSION = '0.01';
@@ -55,6 +56,11 @@ sub nsecs_str {
    return $str;
}

sub clear_term
{
    print "\x1b[H\x1b[2J";
}

1;
__END__
=head1 NAME
+1 −1
Original line number Diff line number Diff line
#!/bin/bash
perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit
perf record -c 1 -f -a -M -R -e raw_syscalls:sys_exit $@
Loading