linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: tip-bot for Stephane Eranian <eranian@google.com>
To: linux-tip-commits@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, eranian@google.com, hpa@zytor.com,
	mingo@redhat.com, tglx@linutronix.de, mingo@elte.hu
Subject: [tip:perf/hw-branch-sampling] perf tools: Make perf able to read files from older ABIs
Date: Fri, 9 Mar 2012 05:32:31 -0800	[thread overview]
Message-ID: <tip-114382a0aea97974803c942f106d462cbca5c64d@git.kernel.org> (raw)
In-Reply-To: <1328826068-11713-19-git-send-email-eranian@google.com>

Commit-ID:  114382a0aea97974803c942f106d462cbca5c64d
Gitweb:     http://git.kernel.org/tip/114382a0aea97974803c942f106d462cbca5c64d
Author:     Stephane Eranian <eranian@google.com>
AuthorDate: Thu, 9 Feb 2012 23:21:08 +0100
Committer:  Ingo Molnar <mingo@elte.hu>
CommitDate: Fri, 9 Mar 2012 08:26:07 +0100

perf tools: Make perf able to read files from older ABIs

This patches provides a way to handle legacy perf.data
files.  Legacy files are those using the older PERFFILE
signature.

For those, it is still necessary to detect endianness but
without comparing their header->attr_size with the
tool's own version as it may be different. Instead, we use
a reference table for all known sizes from the legacy era.

We try all the combinations for sizes and endianness. If we find
a match, we proceed, otherwise we return: "incompatible file
format".

This is also done for the pipe-mode file format.

Signed-off-by: Stephane Eranian <eranian@google.com>
Cc: peterz@infradead.org
Cc: acme@redhat.com
Cc: robert.richter@amd.com
Cc: ming.m.lin@intel.com
Cc: andi@firstfloor.org
Cc: asharma@fb.com
Cc: ravitillo@lbl.gov
Cc: vweaver1@eecs.utk.edu
Cc: khandual@linux.vnet.ibm.com
Cc: dsahern@gmail.com
Link: http://lkml.kernel.org/r/1328826068-11713-19-git-send-email-eranian@google.com
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
 tools/perf/util/header.c |  122 +++++++++++++++++++++++++++++++++++-----------
 1 files changed, 94 insertions(+), 28 deletions(-)

diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 6d58026..c851495 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -1803,35 +1803,101 @@ out_free:
 	return err;
 }
 
-static int check_magic_endian(u64 *magic, struct perf_file_header *header,
-			      struct perf_header *ph)
+static const int attr_file_abi_sizes[] = {
+	[0] = PERF_ATTR_SIZE_VER0,
+	[1] = PERF_ATTR_SIZE_VER1,
+	0,
+};
+
+/*
+ * In the legacy file format, the magic number is not used to encode endianness.
+ * hdr_sz was used to encode endianness. But given that hdr_sz can vary based
+ * on ABI revisions, we need to try all combinations for all endianness to
+ * detect the endianness.
+ */
+static int try_all_file_abis(uint64_t hdr_sz, struct perf_header *ph)
 {
-	int ret;
+	uint64_t ref_size, attr_size;
+	int i;
 
-	/* check for legacy format */
-	ret = memcmp(magic, __perf_magic1, sizeof(*magic));
-	if (ret == 0) {
-		pr_debug("legacy perf.data format\n");
-		if (!header)
-			return -1;
+	for (i = 0 ; attr_file_abi_sizes[i]; i++) {
+		ref_size = attr_file_abi_sizes[i]
+			 + sizeof(struct perf_file_section);
+		if (hdr_sz != ref_size) {
+			attr_size = bswap_64(hdr_sz);
+			if (attr_size != ref_size)
+				continue;
 
-		if (header->attr_size != sizeof(struct perf_file_attr)) {
-			u64 attr_size = bswap_64(header->attr_size);
+			ph->needs_swap = true;
+		}
+		pr_debug("ABI%d perf.data file detected, need_swap=%d\n",
+			 i,
+			 ph->needs_swap);
+		return 0;
+	}
+	/* could not determine endianness */
+	return -1;
+}
 
-			if (attr_size != sizeof(struct perf_file_attr))
-				return -1;
+#define PERF_PIPE_HDR_VER0	16
+
+static const size_t attr_pipe_abi_sizes[] = {
+	[0] = PERF_PIPE_HDR_VER0,
+	0,
+};
+
+/*
+ * In the legacy pipe format, there is an implicit assumption that endiannesss
+ * between host recording the samples, and host parsing the samples is the
+ * same. This is not always the case given that the pipe output may always be
+ * redirected into a file and analyzed on a different machine with possibly a
+ * different endianness and perf_event ABI revsions in the perf tool itself.
+ */
+static int try_all_pipe_abis(uint64_t hdr_sz, struct perf_header *ph)
+{
+	u64 attr_size;
+	int i;
+
+	for (i = 0 ; attr_pipe_abi_sizes[i]; i++) {
+		if (hdr_sz != attr_pipe_abi_sizes[i]) {
+			attr_size = bswap_64(hdr_sz);
+			if (attr_size != hdr_sz)
+				continue;
 
 			ph->needs_swap = true;
 		}
+		pr_debug("Pipe ABI%d perf.data file detected\n", i);
 		return 0;
 	}
+	return -1;
+}
+
+static int check_magic_endian(u64 magic, uint64_t hdr_sz,
+			      bool is_pipe, struct perf_header *ph)
+{
+	int ret;
+
+	/* check for legacy format */
+	ret = memcmp(&magic, __perf_magic1, sizeof(magic));
+	if (ret == 0) {
+		pr_debug("legacy perf.data format\n");
+		if (is_pipe)
+			return try_all_pipe_abis(hdr_sz, ph);
+
+		return try_all_file_abis(hdr_sz, ph);
+	}
+	/*
+	 * the new magic number serves two purposes:
+	 * - unique number to identify actual perf.data files
+	 * - encode endianness of file
+	 */
 
-	/* check magic number with same endianness */
-	if (*magic == __perf_magic2)
+	/* check magic number with one endianness */
+	if (magic == __perf_magic2)
 		return 0;
 
-	/* check magic number but opposite endianness */
-	if (*magic != __perf_magic2_sw)
+	/* check magic number with opposite endianness */
+	if (magic != __perf_magic2_sw)
 		return -1;
 
 	ph->needs_swap = true;
@@ -1850,8 +1916,11 @@ int perf_file_header__read(struct perf_file_header *header,
 	if (ret <= 0)
 		return -1;
 
-	if (check_magic_endian(&header->magic, header, ph) < 0)
+	if (check_magic_endian(header->magic,
+			       header->attr_size, false, ph) < 0) {
+		pr_debug("magic/endian check failed\n");
 		return -1;
+	}
 
 	if (ph->needs_swap) {
 		mem_bswap_64(header, offsetof(struct perf_file_header,
@@ -1938,21 +2007,17 @@ static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
 	if (ret <= 0)
 		return -1;
 
-	 if (check_magic_endian(&header->magic, NULL, ph) < 0)
+	if (check_magic_endian(header->magic, header->size, true, ph) < 0) {
+		pr_debug("endian/magic failed\n");
 		return -1;
+	}
+
+	if (ph->needs_swap)
+		header->size = bswap_64(header->size);
 
 	if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0)
 		return -1;
 
-	if (header->size != sizeof(*header)) {
-		u64 size = bswap_64(header->size);
-
-		if (size != sizeof(*header))
-			return -1;
-
-		ph->needs_swap = true;
-	}
-
 	return 0;
 }
 
@@ -1992,6 +2057,7 @@ static int read_attr(int fd, struct perf_header *ph,
 
 	/* on file perf_event_attr size */
 	sz = attr->size;
+
 	if (ph->needs_swap)
 		sz = bswap_32(sz);
 

  reply	other threads:[~2012-03-09 13:32 UTC|newest]

Thread overview: 51+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-02-09 22:20 [PATCH v6 00/18] perf: add support for sampling taken branches Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 01/18] perf: add generic taken branch sampling support Stephane Eranian
2012-03-09 13:19   ` [tip:perf/hw-branch-sampling] perf: Add " tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 02/18] perf: add Intel LBR MSR definitions Stephane Eranian
2012-03-09 13:20   ` [tip:perf/hw-branch-sampling] perf/x86: Add " tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 03/18] perf: add Intel X86 LBR sharing logic Stephane Eranian
2012-03-09 13:21   ` [tip:perf/hw-branch-sampling] perf/x86: Add Intel " tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 04/18] perf: sync branch stack sampling with X86 precise_sampling Stephane Eranian
2012-03-09 13:21   ` [tip:perf/hw-branch-sampling] perf/x86: Sync branch stack sampling with precise_sampling tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 05/18] perf: add Intel X86 LBR mappings for PERF_SAMPLE_BRANCH filters Stephane Eranian
2012-03-09 13:22   ` [tip:perf/hw-branch-sampling] perf/x86: Add Intel " tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 06/18] perf: disable LBR support for older Intel Atom processors Stephane Eranian
2012-03-09 13:23   ` [tip:perf/hw-branch-sampling] perf/x86: Disable " tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 07/18] perf: implement PERF_SAMPLE_BRANCH for Intel X86 Stephane Eranian
2012-03-09 13:24   ` [tip:perf/hw-branch-sampling] perf/x86: Implement PERF_SAMPLE_BRANCH for Intel CPUs tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 08/18] perf: add LBR software filter support for Intel X86 Stephane Eranian
2012-03-09 13:25   ` [tip:perf/hw-branch-sampling] perf/x86: Add LBR software filter support for Intel CPUs tip-bot for Stephane Eranian
2012-02-09 22:20 ` [PATCH v6 09/18] perf: disable PERF_SAMPLE_BRANCH_* when not supported Stephane Eranian
2012-03-09 13:26   ` [tip:perf/hw-branch-sampling] perf: Disable " tip-bot for Stephane Eranian
2012-02-09 22:21 ` [PATCH v6 10/18] perf: add hook to flush branch_stack on context switch Stephane Eranian
2012-03-09 13:26   ` [tip:perf/hw-branch-sampling] perf: Add callback " tip-bot for Stephane Eranian
2012-02-09 22:21 ` [PATCH v6 11/18] perf: add code to support PERF_SAMPLE_BRANCH_STACK Stephane Eranian
2012-03-09 13:27   ` [tip:perf/hw-branch-sampling] perf tools: Add " tip-bot for Roberto Agostino Vitillo
2012-02-09 22:21 ` [PATCH v6 12/18] perf: add support for sampling taken branch to perf record Stephane Eranian
2012-03-09 13:28   ` [tip:perf/hw-branch-sampling] perf record: Add support for sampling taken branch tip-bot for Roberto Agostino Vitillo
2012-02-09 22:21 ` [PATCH v6 13/18] perf: add support for taken branch sampling to perf report Stephane Eranian
2012-02-14 21:47   ` Arnaldo Carvalho de Melo
2012-02-22 11:15   ` Ingo Molnar
2012-02-22 16:18     ` Stephane Eranian
2012-02-23  9:59       ` Ingo Molnar
2012-02-23 16:53         ` Stephane Eranian
2012-02-23 18:11           ` Arnaldo Carvalho de Melo
2012-02-23 20:48             ` Stephane Eranian
2012-03-09 13:29   ` [tip:perf/hw-branch-sampling] perf report: Add support for taken branch sampling tip-bot for Roberto Agostino Vitillo
2012-02-09 22:21 ` [PATCH v6 14/18] perf: fix endianness detection in perf.data Stephane Eranian
2012-02-09 22:32   ` David Ahern
2012-02-09 22:21 ` [PATCH v6 15/18] perf: add ABI reference sizes Stephane Eranian
2012-03-09 13:30   ` [tip:perf/hw-branch-sampling] perf: Add " tip-bot for Stephane Eranian
2012-02-09 22:21 ` [PATCH v6 16/18] perf: enable reading of perf.data files from different ABI rev Stephane Eranian
2012-02-09 22:39   ` David Ahern
2012-02-09 22:41     ` Stephane Eranian
2012-02-09 22:46       ` David Ahern
2012-02-09 22:49         ` Stephane Eranian
2012-02-10  0:37   ` David Ahern
2012-03-09 13:30   ` [tip:perf/hw-branch-sampling] perf tools: Enable reading of perf. data " tip-bot for Stephane Eranian
2012-02-09 22:21 ` [PATCH v6 17/18] perf: fix bug print_event_desc() Stephane Eranian
2012-03-09 13:31   ` [tip:perf/hw-branch-sampling] perf tools: Fix ABI compatibility bug in print_event_desc() tip-bot for Stephane Eranian
2012-02-09 22:21 ` [PATCH v6 18/18] perf: make perf able to read file from older ABIs Stephane Eranian
2012-03-09 13:32   ` tip-bot for Stephane Eranian [this message]
2012-02-27  7:50 ` [PATCH v6 00/18] perf: add support for sampling taken branches Anshuman Khandual
2012-02-27  8:45   ` Stephane Eranian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=tip-114382a0aea97974803c942f106d462cbca5c64d@git.kernel.org \
    --to=eranian@google.com \
    --cc=hpa@zytor.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=mingo@elte.hu \
    --cc=mingo@redhat.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).