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

Commit ef0eb2e6 authored by Ingo Molnar's avatar Ingo Molnar
Browse files

Merge tag 'perf-core-for-mingo-4.12-20170411' of...

Merge tag 'perf-core-for-mingo-4.12-20170411' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

 into perf/core

perf/core improvements and fixes:

User visible changes:

- Support s390 jump instructions in perf annotate (Christian Borntraeger)

- When failing to setup multiple events (e.g. '-e irq_vectors:*'), state
  which one caused the failure (Yao Jin)

- Various fixes for pipe mode, where the output of 'perf record' is
  written to stdout instead of to a perf.data file, fixing workloads
  such as: (David Carrillo-Cisneros)

    $ perf record -o - noploop | perf inject -b > perf.data

    $ perf record -o - noploop | perf annotate

Infrastructure changes:

- Simplify ltrim() implementation (Arnaldo Carvalho de Melo)

- Use ltrim() and rtrim() in places where ad-hoc equivalents were being
  used (Taeung Song)

 Conflicts:
	tools/perf/util/annotate.c

Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parents 1c4f8ad8 986a5bc0
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -11,8 +11,8 @@ All fields are in native-endian of the machine that generated the perf.data.

When perf is writing to a pipe it uses a special version of the file
format that does not rely on seeking to adjust data offsets.  This
format is not described here. The pipe version can be converted to
normal perf.data with perf inject.
format is described in "Pipe-mode data" section. The pipe data version can be
augmented with additional events using perf inject.

The file starts with a perf_header:

@@ -411,6 +411,21 @@ An array bound by the perf_file_section size.

ids points to a array of uint64_t defining the ids for event attr attr.

Pipe-mode data

Pipe-mode avoid seeks in the file by removing the perf_file_section and flags
from the struct perf_header. The trimmed header is:

struct perf_pipe_file_header {
	u64				magic;
	u64				size;
};

The information about attrs, data, and event_types is instead in the
synthesized events PERF_RECORD_ATTR, PERF_RECORD_HEADER_TRACING_DATA and
PERF_RECORD_HEADER_EVENT_TYPE that are generated by perf record in pipe-mode.


References:

include/uapi/linux/perf_event.h
+30 −0
Original line number Diff line number Diff line
static struct ins_ops *s390__associate_ins_ops(struct arch *arch, const char *name)
{
	struct ins_ops *ops = NULL;

	/* catch all kind of jumps */
	if (strchr(name, 'j') ||
	    !strncmp(name, "bct", 3) ||
	    !strncmp(name, "br", 2))
		ops = &jump_ops;
	/* override call/returns */
	if (!strcmp(name, "bras") ||
	    !strcmp(name, "brasl") ||
	    !strcmp(name, "basr"))
		ops = &call_ops;
	if (!strcmp(name, "br"))
		ops = &ret_ops;

	arch__associate_ins_ops(arch, name, ops);
	return ops;
}

static int s390__annotate_init(struct arch *arch)
{
	if (!arch->initialized) {
		arch->initialized = true;
		arch->associate_instruction_ops = s390__associate_ins_ops;
	}

	return 0;
}
+2 −0
Original line number Diff line number Diff line
@@ -394,6 +394,8 @@ int cmd_annotate(int argc, const char **argv)
			.exit	= perf_event__process_exit,
			.fork	= perf_event__process_fork,
			.namespaces = perf_event__process_namespaces,
			.attr	= perf_event__process_attr,
			.build_id = perf_event__process_build_id,
			.ordered_events = true,
			.ordering_requires_timestamps = true,
		},
+2 −0
Original line number Diff line number Diff line
@@ -694,6 +694,8 @@ static int __cmd_inject(struct perf_inject *inject)
		lseek(fd, output_data_offset, SEEK_SET);

	ret = perf_session__process_events(session);
	if (ret)
		return ret;

	if (!file_out->is_pipe) {
		if (inject->build_ids)
+2 −2
Original line number Diff line number Diff line
@@ -1708,7 +1708,7 @@ static int parse_scriptname(const struct option *opt __maybe_unused,
static int parse_output_fields(const struct option *opt __maybe_unused,
			    const char *arg, int unset __maybe_unused)
{
	char *tok;
	char *tok, *strtok_saveptr = NULL;
	int i, imax = ARRAY_SIZE(all_output_options);
	int j;
	int rc = 0;
@@ -1769,7 +1769,7 @@ static int parse_output_fields(const struct option *opt __maybe_unused,
		}
	}

	for (tok = strtok(tok, ","); tok; tok = strtok(NULL, ",")) {
	for (tok = strtok_r(tok, ",", &strtok_saveptr); tok; tok = strtok_r(NULL, ",", &strtok_saveptr)) {
		for (i = 0; i < imax; ++i) {
			if (strcmp(tok, all_output_options[i].str) == 0)
				break;
Loading