Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1213141 > unrolled thread

[GIT PULL 00/16] perf/core improvements and fixes

Started byArnaldo Carvalho de Melo <acme@kernel.org>
First post2015-08-25 18:20 +0200
Last post2015-08-26 15:40 +0200
Articles 15 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [GIT PULL 00/16] perf/core improvements and fixes Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 01/16] perf tools: Fix tarball build broken by pt/bts Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 06/16] perf tools: Add Intel PT support for PSB periods Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 04/16] perf ordered_events: Clear the progress bar at the end of a flush Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 02/16] perf annotate: Reset the dso find_symbol cache when removing symbols Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 16/16] perf probe: Support probing at absolute addresses Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
      RE: [PATCH 16/16] perf probe: Support probing at absolute  addresses 平松雅巳 / HIRAMATU,MASAMI   <masami.hiramatsu.pt@hitachi.com> - 2015-08-26 02:10 +0200
        Re: [PATCH 16/16] perf probe: Support probing at absolute addresses Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-26 15:00 +0200
    [PATCH 14/16] perf tools: Update Intel PT documentation Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 12/16] perf tools: Add Intel PT support for using CYC packets Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 09/16] perf tools: Add Intel PT support for decoding MTC packets Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 07/16] perf tools: Add new Intel PT packet definitions Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 10/16] perf tools: Add Intel PT support for using MTC packets Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    [PATCH 03/16] perf ui tui progress: Implement the ui_progress_ops->finish() method Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-25 18:20 +0200
    Re: [GIT PULL 00/16] perf/core improvements and fixes Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-08-26 15:40 +0200

#1213141 — [GIT PULL 00/16] perf/core improvements and fixes

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[GIT PULL 00/16] perf/core improvements and fixes
Message-ID<q1p73-3gB-5@gated-at.bofh.it>
Hi Ingo,

	Please consider pulling, now to get back looking at eBPF :-)

- Arnaldo

The following changes since commit 0e53909a1cf0153736fb52c216558a65530d8c40:

  Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-08-22 08:45:46 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to 1cbebfc7abb549ed3f4080e12c4d7b07d1f16637:

  perf probe: Support probing at absolute addresses (2015-08-25 12:36:22 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

User visible:

- Add support for using several Intel PT features (CYC, MTC packets), the
  relevant documentation was updated: tools/perf/Documentation/intel-pt.txt,
  briefly describing those packets, its purposes, how to configure them in
  the event config terms and relevant external documentation for further
  reading. (Adrian Hunter)

- Introduce support for probing at an absolut address, for user and kernel
  'perf probe's, useful when one have the symbol maps on a developer machine
  but not on an embedded system (Wang Nan)

- Clear the progress bar at the end of a ordered_events flush, fixing
  an UI artifact when, after ordering the events the screen doesn't get
  completely redraw, for instance, when an error window covers just the
  center of the screen and waits for user input. (Arnaldo Carvalho de Melo)

- Fix 'annotate' segfault by resetting the dso find_symbol cache when removing
  symbols (Arnaldo Carvalho de Melo)

Infrastructure:

- Fix Intel PT 'instructions' sample period (Adrian Hunter)

- Prevent segfault when reading probe point with absolute address (Wang Nan)

Build fixes:

- Fix tarball build broken by pt/bts (Adrian Hunter)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

----------------------------------------------------------------
Adrian Hunter (11):
      perf tools: Fix tarball build broken by pt/bts
      perf tools: Fix Intel PT 'instructions' sample period
      perf tools: Add Intel PT support for PSB periods
      perf tools: Add new Intel PT packet definitions
      perf tools: Pass Intel PT information for decoding MTC and CYC
      perf tools: Add Intel PT support for decoding MTC packets
      perf tools: Add Intel PT support for using MTC packets
      perf tools: Add Intel PT support for decoding CYC packets
      perf tools: Add Intel PT support for using CYC packets
      perf tools: Add Intel PT support for decoding TRACESTOP packets
      perf tools: Update Intel PT documentation

Arnaldo Carvalho de Melo (3):
      perf annotate: Reset the dso find_symbol cache when removing symbols
      perf ui tui progress: Implement the ui_progress_ops->finish() method
      perf ordered_events: Clear the progress bar at the end of a flush

Wang Nan (2):
      perf probe: Prevent segfault when reading probe point with absolute address
      perf probe: Support probing at absolute addresses

 tools/perf/Documentation/intel-pt.txt              | 194 ++++++-
 tools/perf/arch/x86/util/intel-pt.c                | 271 +++++++++-
 tools/perf/builtin-annotate.c                      |   1 +
 tools/perf/ui/tui/progress.c                       |  19 +-
 tools/perf/util/dso.h                              |   2 +
 tools/perf/util/intel-pt-decoder/inat.c            |   2 +-
 tools/perf/util/intel-pt-decoder/inat.h            |   2 +-
 tools/perf/util/intel-pt-decoder/inat_types.h      |  29 ++
 tools/perf/util/intel-pt-decoder/insn.c            |   4 +-
 tools/perf/util/intel-pt-decoder/insn.h            |   2 +-
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 555 ++++++++++++++++++++-
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |   5 +
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |   2 +-
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   | 142 +++++-
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   6 +
 tools/perf/util/intel-pt.c                         |  67 ++-
 tools/perf/util/intel-pt.h                         |   5 +
 tools/perf/util/ordered-events.c                   |   3 +
 tools/perf/util/probe-event.c                      | 152 +++++-
 tools/perf/util/probe-event.h                      |   3 +
 tools/perf/util/probe-finder.c                     |  21 +-
 tools/perf/util/symbol.c                           |  10 +
 22 files changed, 1404 insertions(+), 93 deletions(-)
 create mode 100644 tools/perf/util/intel-pt-decoder/inat_types.h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1213143 — [PATCH 01/16] perf tools: Fix tarball build broken by pt/bts

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 01/16] perf tools: Fix tarball build broken by pt/bts
Message-ID<q1p74-3gB-27@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

Fix some include paths and add missing inat_types.h.

Reported-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Link: http://lkml.kernel.org/r/55D77696.60102@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/intel-pt-decoder/inat.c            |  2 +-
 tools/perf/util/intel-pt-decoder/inat.h            |  2 +-
 tools/perf/util/intel-pt-decoder/inat_types.h      | 29 ++++++++++++++++++++++
 tools/perf/util/intel-pt-decoder/insn.c            |  4 +--
 tools/perf/util/intel-pt-decoder/insn.h            |  2 +-
 .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |  2 +-
 6 files changed, 35 insertions(+), 6 deletions(-)
 create mode 100644 tools/perf/util/intel-pt-decoder/inat_types.h

diff --git a/tools/perf/util/intel-pt-decoder/inat.c b/tools/perf/util/intel-pt-decoder/inat.c
index feeaa509dfe4..906d94aa0a24 100644
--- a/tools/perf/util/intel-pt-decoder/inat.c
+++ b/tools/perf/util/intel-pt-decoder/inat.c
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include <asm/insn.h>
+#include "insn.h"
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
diff --git a/tools/perf/util/intel-pt-decoder/inat.h b/tools/perf/util/intel-pt-decoder/inat.h
index 74a2e312e8a2..611645e903a8 100644
--- a/tools/perf/util/intel-pt-decoder/inat.h
+++ b/tools/perf/util/intel-pt-decoder/inat.h
@@ -20,7 +20,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  *
  */
-#include <asm/inat_types.h>
+#include "inat_types.h"
 
 /*
  * Internal bits. Don't use bitmasks directly, because these bits are
diff --git a/tools/perf/util/intel-pt-decoder/inat_types.h b/tools/perf/util/intel-pt-decoder/inat_types.h
new file mode 100644
index 000000000000..cb3c20ce39cf
--- /dev/null
+++ b/tools/perf/util/intel-pt-decoder/inat_types.h
@@ -0,0 +1,29 @@
+#ifndef _ASM_X86_INAT_TYPES_H
+#define _ASM_X86_INAT_TYPES_H
+/*
+ * x86 instruction attributes
+ *
+ * Written by Masami Hiramatsu <mhiramat@redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+/* Instruction attributes */
+typedef unsigned int insn_attr_t;
+typedef unsigned char insn_byte_t;
+typedef signed int insn_value_t;
+
+#endif
diff --git a/tools/perf/util/intel-pt-decoder/insn.c b/tools/perf/util/intel-pt-decoder/insn.c
index 8f72b334aea0..47314a64399c 100644
--- a/tools/perf/util/intel-pt-decoder/insn.c
+++ b/tools/perf/util/intel-pt-decoder/insn.c
@@ -23,8 +23,8 @@
 #else
 #include <string.h>
 #endif
-#include <asm/inat.h>
-#include <asm/insn.h>
+#include "inat.h"
+#include "insn.h"
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)	\
diff --git a/tools/perf/util/intel-pt-decoder/insn.h b/tools/perf/util/intel-pt-decoder/insn.h
index e7814b74caf8..dd12da0f4593 100644
--- a/tools/perf/util/intel-pt-decoder/insn.h
+++ b/tools/perf/util/intel-pt-decoder/insn.h
@@ -21,7 +21,7 @@
  */
 
 /* insn_attr_t is defined in inat.h */
-#include <asm/inat.h>
+#include "inat.h"
 
 struct insn_field {
 	union {
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
index 46980fc663ac..9e4eb8fcd559 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
@@ -20,7 +20,7 @@
 
 #include "event.h"
 
-#include <asm/insn.h>
+#include "insn.h"
 
 #include "inat.c"
 #include "insn.c"
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213144 — [PATCH 06/16] perf tools: Add Intel PT support for PSB periods

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 06/16] perf tools: Add Intel PT support for PSB periods
Message-ID<q1p74-3gB-29@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

The PSB packet is a synchronization packet that provides a starting
point for decoding or recovery from errors.

This patch adds support for a new Intel PT feature that allows the
frequency of PSB packets to be specified.

Support for this feature is indicated by
/sys/bus/event_source/devices/intel_pt/caps/psb_cyc which contains "1"
if the feature is supported and "0" otherwise.

The PSB period can be specified as a PMU config term e.g. perf record -e
intel_pt/psb_period=2/u sleep 1

The default value is 3 or the nearest lower value that is supported.  0
is always supported.

Valid values are given by:

/sys/bus/event_source/devices/intel_pt/caps/psb_periods

which contains a hexadecimal value, the bits of which represent valid
values e.g. bit 2 set means value 2 is valid.

The value is converted to the approximate number of trace bytes between
PSB packets as:

	2 ^ (value + 11)

e.g. value 3 means 16KiB bytes between PSBs

If an invalid value is entered, the error message will give a list of
valid values e.g.

	$ perf record -e intel_pt/psb_period=15/u uname
	Invalid psb_period for intel_pt. Valid values are: 0-5

tools/perf/Documentation/intel-pt.txt is updated in a later patch as
there are a number of new features being added.

For more information about PSB periods refer to the Intel 64 and IA-32
Architectures SDM Chapter 36 Intel Processor Trace from June 2015 or
later.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-18-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/intel-pt.c | 217 ++++++++++++++++++++++++++++++++++--
 1 file changed, 210 insertions(+), 7 deletions(-)

diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index da7d2c15e611..145975b003a7 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -99,17 +99,121 @@ static int intel_pt_parse_terms(struct list_head *formats, const char *str,
 	return intel_pt_parse_terms_with_default(formats, str, config);
 }
 
-static size_t intel_pt_psb_period(struct perf_pmu *intel_pt_pmu __maybe_unused,
-				  struct perf_evlist *evlist __maybe_unused)
+static u64 intel_pt_masked_bits(u64 mask, u64 bits)
 {
-	return 256;
+	const u64 top_bit = 1ULL << 63;
+	u64 res = 0;
+	int i;
+
+	for (i = 0; i < 64; i++) {
+		if (mask & top_bit) {
+			res <<= 1;
+			if (bits & top_bit)
+				res |= 1;
+		}
+		mask <<= 1;
+		bits <<= 1;
+	}
+
+	return res;
+}
+
+static int intel_pt_read_config(struct perf_pmu *intel_pt_pmu, const char *str,
+				struct perf_evlist *evlist, u64 *res)
+{
+	struct perf_evsel *evsel;
+	u64 mask;
+
+	*res = 0;
+
+	mask = perf_pmu__format_bits(&intel_pt_pmu->format, str);
+	if (!mask)
+		return -EINVAL;
+
+	evlist__for_each(evlist, evsel) {
+		if (evsel->attr.type == intel_pt_pmu->type) {
+			*res = intel_pt_masked_bits(mask, evsel->attr.config);
+			return 0;
+		}
+	}
+
+	return -EINVAL;
+}
+
+static size_t intel_pt_psb_period(struct perf_pmu *intel_pt_pmu,
+				  struct perf_evlist *evlist)
+{
+	u64 val;
+	int err, topa_multiple_entries;
+	size_t psb_period;
+
+	if (perf_pmu__scan_file(intel_pt_pmu, "caps/topa_multiple_entries",
+				"%d", &topa_multiple_entries) != 1)
+		topa_multiple_entries = 0;
+
+	/*
+	 * Use caps/topa_multiple_entries to indicate early hardware that had
+	 * extra frequent PSBs.
+	 */
+	if (!topa_multiple_entries) {
+		psb_period = 256;
+		goto out;
+	}
+
+	err = intel_pt_read_config(intel_pt_pmu, "psb_period", evlist, &val);
+	if (err)
+		val = 0;
+
+	psb_period = 1 << (val + 11);
+out:
+	pr_debug2("%s psb_period %zu\n", intel_pt_pmu->name, psb_period);
+	return psb_period;
+}
+
+static int intel_pt_pick_bit(int bits, int target)
+{
+	int pos, pick = -1;
+
+	for (pos = 0; bits; bits >>= 1, pos++) {
+		if (bits & 1) {
+			if (pos <= target || pick < 0)
+				pick = pos;
+			if (pos >= target)
+				break;
+		}
+	}
+
+	return pick;
 }
 
 static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu)
 {
+	char buf[256];
+	int psb_cyc, psb_periods, psb_period;
+	int pos = 0;
 	u64 config;
 
-	intel_pt_parse_terms(&intel_pt_pmu->format, "tsc", &config);
+	pos += scnprintf(buf + pos, sizeof(buf) - pos, "tsc");
+
+	if (perf_pmu__scan_file(intel_pt_pmu, "caps/psb_cyc", "%d",
+				&psb_cyc) != 1)
+		psb_cyc = 1;
+
+	if (psb_cyc) {
+		if (perf_pmu__scan_file(intel_pt_pmu, "caps/psb_periods", "%x",
+					&psb_periods) != 1)
+			psb_periods = 0;
+		if (psb_periods) {
+			psb_period = intel_pt_pick_bit(psb_periods, 3);
+			pos += scnprintf(buf + pos, sizeof(buf) - pos,
+					 ",psb_period=%d", psb_period);
+		}
+	}
+
+	pr_debug2("%s default config: %s\n", intel_pt_pmu->name, buf);
+
+	intel_pt_parse_terms(&intel_pt_pmu->format, buf, &config);
+
 	return config;
 }
 
@@ -239,6 +343,103 @@ static int intel_pt_track_switches(struct perf_evlist *evlist)
 	return 0;
 }
 
+static void intel_pt_valid_str(char *str, size_t len, u64 valid)
+{
+	unsigned int val, last = 0, state = 1;
+	int p = 0;
+
+	str[0] = '\0';
+
+	for (val = 0; val <= 64; val++, valid >>= 1) {
+		if (valid & 1) {
+			last = val;
+			switch (state) {
+			case 0:
+				p += scnprintf(str + p, len - p, ",");
+				/* Fall through */
+			case 1:
+				p += scnprintf(str + p, len - p, "%u", val);
+				state = 2;
+				break;
+			case 2:
+				state = 3;
+				break;
+			case 3:
+				state = 4;
+				break;
+			default:
+				break;
+			}
+		} else {
+			switch (state) {
+			case 3:
+				p += scnprintf(str + p, len - p, ",%u", last);
+				state = 0;
+				break;
+			case 4:
+				p += scnprintf(str + p, len - p, "-%u", last);
+				state = 0;
+				break;
+			default:
+				break;
+			}
+			if (state != 1)
+				state = 0;
+		}
+	}
+}
+
+static int intel_pt_val_config_term(struct perf_pmu *intel_pt_pmu,
+				    const char *caps, const char *name,
+				    const char *supported, u64 config)
+{
+	char valid_str[256];
+	unsigned int shift;
+	unsigned long long valid;
+	u64 bits;
+	int ok;
+
+	if (perf_pmu__scan_file(intel_pt_pmu, caps, "%llx", &valid) != 1)
+		valid = 0;
+
+	if (supported &&
+	    perf_pmu__scan_file(intel_pt_pmu, supported, "%d", &ok) == 1 && !ok)
+		valid = 0;
+
+	valid |= 1;
+
+	bits = perf_pmu__format_bits(&intel_pt_pmu->format, name);
+
+	config &= bits;
+
+	for (shift = 0; bits && !(bits & 1); shift++)
+		bits >>= 1;
+
+	config >>= shift;
+
+	if (config > 63)
+		goto out_err;
+
+	if (valid & (1 << config))
+		return 0;
+out_err:
+	intel_pt_valid_str(valid_str, sizeof(valid_str), valid);
+	pr_err("Invalid %s for %s. Valid values are: %s\n",
+	       name, INTEL_PT_PMU_NAME, valid_str);
+	return -EINVAL;
+}
+
+static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu,
+				    struct perf_evsel *evsel)
+{
+	if (!evsel)
+		return 0;
+
+	return intel_pt_val_config_term(intel_pt_pmu, "caps/psb_periods",
+					"psb_period", "caps/psb_cyc",
+					evsel->attr.config);
+}
+
 static int intel_pt_recording_options(struct auxtrace_record *itr,
 				      struct perf_evlist *evlist,
 				      struct record_opts *opts)
@@ -251,6 +452,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	const struct cpu_map *cpus = evlist->cpus;
 	bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
 	u64 tsc_bit;
+	int err;
 
 	ptr->evlist = evlist;
 	ptr->snapshot_mode = opts->auxtrace_snapshot_mode;
@@ -281,6 +483,10 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	if (!opts->full_auxtrace)
 		return 0;
 
+	err = intel_pt_validate_config(intel_pt_pmu, intel_pt_evsel);
+	if (err)
+		return err;
+
 	/* Set default sizes for snapshot mode */
 	if (opts->auxtrace_snapshot_mode) {
 		size_t psb_period = intel_pt_psb_period(intel_pt_pmu, evlist);
@@ -366,8 +572,6 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	 * threads.
 	 */
 	if (have_timing_info && !cpu_map__empty(cpus)) {
-		int err;
-
 		err = intel_pt_track_switches(evlist);
 		if (err == -EPERM)
 			pr_debug2("Unable to select sched:sched_switch\n");
@@ -394,7 +598,6 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
 	/* Add dummy event to keep tracking */
 	if (opts->full_auxtrace) {
 		struct perf_evsel *tracking_evsel;
-		int err;
 
 		err = parse_events(evlist, "dummy:u", NULL);
 		if (err)
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213145 — [PATCH 04/16] perf ordered_events: Clear the progress bar at the end of a flush

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 04/16] perf ordered_events: Clear the progress bar at the end of a flush
Message-ID<q1p75-3gB-43@gated-at.bofh.it>
In reply to#1213141
From: Arnaldo Carvalho de Melo <acme@redhat.com>

We were depending on the next screen operation after a flush() being
one that would redraw the whole screen so that the progress bar would
be overwritten, when that didn't happen a screen artifact of, say, a
error dialog window would be overlaid on top of the progress bar, fix
it by calling ui_browser__finish(), that now has a TUI implementation.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-el0fyw6duemnx62lydjzhs8c@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/ordered-events.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/tools/perf/util/ordered-events.c b/tools/perf/util/ordered-events.c
index 52be201b9b25..b1b9e2385f4b 100644
--- a/tools/perf/util/ordered-events.c
+++ b/tools/perf/util/ordered-events.c
@@ -220,6 +220,9 @@ static int __ordered_events__flush(struct ordered_events *oe)
 	else if (last_ts <= limit)
 		oe->last = list_entry(head->prev, struct ordered_event, list);
 
+	if (show_progress)
+		ui_progress__finish();
+
 	return 0;
 }
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213146 — [PATCH 02/16] perf annotate: Reset the dso find_symbol cache when removing symbols

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 02/16] perf annotate: Reset the dso find_symbol cache when removing symbols
Message-ID<q1p74-3gB-31@gated-at.bofh.it>
In reply to#1213141
From: Arnaldo Carvalho de Melo <acme@redhat.com>

The 'annotate' tool does some filtering in the entries in a DSO but
forgot to reset the cache done in dso__find_symbol(), cauxing a SEGV:

  [root@zoo ~]# perf annotate netlink_poll
  perf: Segmentation fault
  -------- backtrace --------
  perf[0x526ceb]
  /lib64/libc.so.6(+0x34960)[0x7faedfbe0960]
  perf(rb_erase+0x223)[0x499d63]
  perf[0x4213e9]
  perf[0x4bc123]
  perf[0x4bc621]
  perf[0x4bf26b]
  perf[0x4bc855]
  perf(perf_session__process_events+0x340)[0x4bddc0]
  perf(cmd_annotate+0x6bb)[0x421b5b]
  perf[0x479063]
  perf(main+0x60a)[0x42098a]
  /lib64/libc.so.6(__libc_start_main+0xf0)[0x7faedfbcbfe0]
  perf[0x420aa9]
  [0x0]
  [root@zoo ~]#

Fix it by reseting the find cache when removing symbols.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Fixes: b685ac22b436 ("perf symbols: Add front end cache for DSO symbol lookup")
Link: http://lkml.kernel.org/n/tip-b2y9x46y0t8yem1ive41zqyp@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/builtin-annotate.c |  1 +
 tools/perf/util/dso.h         |  2 ++
 tools/perf/util/symbol.c      | 10 ++++++++++
 3 files changed, 13 insertions(+)

diff --git a/tools/perf/builtin-annotate.c b/tools/perf/builtin-annotate.c
index a32a64ef08e2..8edc205ff9a7 100644
--- a/tools/perf/builtin-annotate.c
+++ b/tools/perf/builtin-annotate.c
@@ -67,6 +67,7 @@ static int perf_evsel__add_sample(struct perf_evsel *evsel,
 			rb_erase(&al->sym->rb_node,
 				 &al->map->dso->symbols[al->map->type]);
 			symbol__delete(al->sym);
+			dso__reset_find_symbol_cache(al->map->dso);
 		}
 		return 0;
 	}
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index c73276db6d6f..fc8db9c764ac 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -324,6 +324,8 @@ struct dso *__dsos__findnew(struct dsos *dsos, const char *name);
 struct dso *dsos__findnew(struct dsos *dsos, const char *name);
 bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
 
+void dso__reset_find_symbol_cache(struct dso *dso);
+
 size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
 			       bool (skip)(struct dso *dso, int parm), int parm);
 size_t __dsos__fprintf(struct list_head *head, FILE *fp);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 42e98ab5a9bb..46ae0532a8a6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -441,6 +441,16 @@ static struct symbol *symbols__find_by_name(struct rb_root *symbols,
 	return &s->sym;
 }
 
+void dso__reset_find_symbol_cache(struct dso *dso)
+{
+	enum map_type type;
+
+	for (type = MAP__FUNCTION; type <= MAP__VARIABLE; ++type) {
+		dso->last_find_result[type].addr   = 0;
+		dso->last_find_result[type].symbol = NULL;
+	}
+}
+
 struct symbol *dso__find_symbol(struct dso *dso,
 				enum map_type type, u64 addr)
 {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213147 — [PATCH 16/16] perf probe: Support probing at absolute addresses

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 16/16] perf probe: Support probing at absolute addresses
Message-ID<q1p74-3gB-33@gated-at.bofh.it>
In reply to#1213141
From: Wang Nan <wangnan0@huawei.com>

It should be useful to allow 'perf probe' probe at absolute offsets of a
target.

For example, when (u)probing at a instruction of a shared object in an
embedded system where debuginfo is not available but we know the offset
of that instruction by manually digging.

This patch enables following perf probe command syntax:

  # perf probe +0xffffffff811e6615

And

  # perf probe /lib/x86_64-linux-gnu/libc-2.19.so +0xeb860

In the above example, we don't need a anchor symbol, so it is possible
to compute absolute addresses using other methods and then use 'perf
probe' to create the probing points.

Committer note:

One can as well specify a name, so that the probe doesn't get assigned a
generic one starting with abs_, i.e. if we use as described above we
get:

  [root@zoo ~]# readelf -sW  /lib64/libc-2.20.so | grep -w malloc
    1175: 00000000000830f0   300 FUNC    GLOBAL DEFAULT   12 malloc@@GLIBC_2.2.5
     813: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS malloc.c
    5276: 00000000000830f0   300 FUNC    GLOBAL DEFAULT   12 malloc
  [root@zoo ~]#
  [root@zoo ~]# perf probe /lib64/libc-2.20.so +0x830f0
  Added new event:
    probe_libc:abs_830f0 (on 0x830f0 in /lib64/libc-2.20.so)

  You can now use it in all perf tools, such as:

	perf record -e probe_libc:abs_830f0 -aR sleep 1

  [root@zoo ~]#
  [root@zoo ~]# perf probe -l
    probe_libc:abs_830f0 (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
  [root@zoo ~]#

Whereas if we assign it a name it gets more manageable:

  [root@zoo ~]# perf probe /lib64/libc-2.20.so malloc=+0x830f0
  Added new event:
    probe_libc:malloc    (on 0x830f0 in /lib64/libc-2.20.so)

  You can now use it in all perf tools, such as:

	perf record -e probe_libc:malloc -aR sleep 1

  [root@zoo ~]# perf probe -l
    probe_libc:malloc    (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
  [root@zoo ~]#

Both, of course, will produce the same results, and we can use a
non canonical name, if the need arises:

  [root@zoo ~]# perf probe /lib64/libc-2.20.so memory_allocation=+0x830f0
  Added new event:
    probe_libc:memory_allocation (on 0x830f0 in /lib64/libc-2.20.so)

  You can now use it in all perf tools, such as:

	perf record -e probe_libc:memory_allocation -aR sleep 1

  [root@zoo ~]# perf probe -l
    probe_libc:memory_allocation (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
  [root@zoo ~]#

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1440509256-193590-2-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/probe-event.c  | 144 +++++++++++++++++++++++++++++++++++++----
 tools/perf/util/probe-event.h  |   3 +
 tools/perf/util/probe-finder.c |  21 +-----
 3 files changed, 138 insertions(+), 30 deletions(-)

diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 6c7e538c9b8b..59de69a4e3ac 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1194,9 +1194,13 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 		*ptr++ = '\0';
 	}
 
-	tmp = strdup(arg);
-	if (tmp == NULL)
-		return -ENOMEM;
+	if (arg[0] == '\0')
+		tmp = NULL;
+	else {
+		tmp = strdup(arg);
+		if (tmp == NULL)
+			return -ENOMEM;
+	}
 
 	if (file_spec)
 		pp->file = tmp;
@@ -1283,11 +1287,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 		return -EINVAL;
 	}
 
-	if (pp->offset && !pp->function) {
-		semantic_error("Offset requires an entry function.\n");
-		return -EINVAL;
-	}
-
 	if (pp->retprobe && !pp->function) {
 		semantic_error("Return probe requires an entry function.\n");
 		return -EINVAL;
@@ -1299,6 +1298,11 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
 		return -EINVAL;
 	}
 
+	if (!pp->function && !pp->offset && !pp->file) {
+		semantic_error("Absolute address should not be zero.\n");
+		return -EINVAL;
+	}
+
 	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
 		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
 		 pp->lazy_line);
@@ -1609,7 +1613,7 @@ error:
 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
 {
 	char *buf, *tmp;
-	char offs[32] = "", line[32] = "", file[32] = "";
+	char offs[32] = "", line[32] = "", file[32] = "", addr[32] = "";
 	int ret, len;
 
 	buf = zalloc(MAX_CMDLEN);
@@ -1622,6 +1626,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
 		if (ret <= 0)
 			goto error;
 	}
+	if (!pp->function) {
+		ret = e_snprintf(addr, 32, "0x%lx", pp->offset);
+		if (ret <= 0)
+			goto error;
+	}
 	if (pp->line) {
 		ret = e_snprintf(line, 32, ":%d", pp->line);
 		if (ret <= 0)
@@ -1639,9 +1648,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
 			goto error;
 	}
 
-	if (pp->function)
-		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
-				 offs, pp->retprobe ? "%return" : "", line,
+	if (pp->function || pp->offset)
+		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s",
+				 pp->function ? : addr,
+				 pp->function ? offs : "",
+				 pp->retprobe ? "%return" : "", line,
 				 file);
 	else
 		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
@@ -1786,6 +1797,11 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
 	if (tev->uprobes)
 		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
 				 tp->module, tp->address);
+	else if (tp->symbol[0] == '0' && tp->symbol[1] == 'x')
+		/* Absolute address. See try_to_find_absolute_address() */
+		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
+				 tp->module ?: "", tp->module ? ":" : "",
+				 tp->address);
 	else
 		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
 				 tp->module ?: "", tp->module ? ":" : "",
@@ -2572,6 +2588,87 @@ err_out:
 	goto out;
 }
 
+static int try_to_find_absolute_address(struct perf_probe_event *pev,
+					struct probe_trace_event **tevs)
+{
+	struct perf_probe_point *pp = &pev->point;
+	struct probe_trace_event *tev;
+	struct probe_trace_point *tp;
+	int i, err;
+
+	if (perf_probe_event_need_dwarf(pev) || pev->point.function)
+		return -EINVAL;
+
+	/*
+	 * This is 'perf probe /lib/libc.so +0xabcd'. Try to probe at
+	 * absolute address.
+	 *
+	 * Only one tev can be generated by this.
+	 */
+	*tevs = zalloc(sizeof(*tev));
+	if (!*tevs)
+		return -ENOMEM;
+
+	tev = *tevs;
+	tp = &tev->point;
+
+	/*
+	 * Don't use tp->offset, use address directly, because
+	 * in synthesize_probe_trace_command() address cannot be
+	 * zero.
+	 */
+	tp->address = pev->point.offset;
+	tp->retprobe = pp->retprobe;
+	tev->uprobes = pev->uprobes;
+
+	err = -ENOMEM;
+	/* Give it a '0x' leading symbol name */
+	if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
+		goto errout;
+
+	/* For kprobe, check range */
+	if ((!tev->uprobes) &&
+	    (kprobe_warn_out_range(tev->point.symbol,
+				   tev->point.address))) {
+		err = -EACCES;
+		goto errout;
+	}
+
+	if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
+		goto errout;
+
+	if (pev->target) {
+		tp->module = strdup(pev->target);
+		if (!tp->module)
+			goto errout;
+	}
+
+	if (tev->group) {
+		tev->group = strdup(pev->group);
+		if (!tev->group)
+			goto errout;
+	}
+
+	if (pev->event) {
+		tev->event = strdup(pev->event);
+		if (!tev->event)
+			goto errout;
+	}
+
+	tev->nargs = pev->nargs;
+	for (i = 0; i < tev->nargs; i++)
+		copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
+
+	return 1;
+
+errout:
+	if (*tevs) {
+		clear_probe_trace_events(*tevs, 1);
+		*tevs = NULL;
+	}
+	return err;
+}
+
 bool __weak arch__prefers_symtab(void) { return false; }
 
 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
@@ -2588,6 +2685,10 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
 		}
 	}
 
+	ret = try_to_find_absolute_address(pev, tevs);
+	if (ret > 0)
+		return ret;
+
 	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
 		ret = find_probe_trace_events_from_map(pev, tevs);
 		if (ret > 0)
@@ -2758,3 +2859,22 @@ end:
 	return ret;
 }
 
+int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
+			    struct perf_probe_arg *pvar)
+{
+	tvar->value = strdup(pvar->var);
+	if (tvar->value == NULL)
+		return -ENOMEM;
+	if (pvar->type) {
+		tvar->type = strdup(pvar->type);
+		if (tvar->type == NULL)
+			return -ENOMEM;
+	}
+	if (pvar->name) {
+		tvar->name = strdup(pvar->name);
+		if (tvar->name == NULL)
+			return -ENOMEM;
+	} else
+		tvar->name = NULL;
+	return 0;
+}
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 83ee95e9743b..174a3cf6c03d 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -156,4 +156,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
 /* Maximum index number of event-name postfix */
 #define MAX_EVENT_INDEX	1024
 
+int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
+			    struct perf_probe_arg *pvar);
+
 #endif /*_PROBE_EVENT_H */
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index 7b80f8cb62b9..29c43c0680a8 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -553,24 +553,9 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
 	char buf[32], *ptr;
 	int ret = 0;
 
-	if (!is_c_varname(pf->pvar->var)) {
-		/* Copy raw parameters */
-		pf->tvar->value = strdup(pf->pvar->var);
-		if (pf->tvar->value == NULL)
-			return -ENOMEM;
-		if (pf->pvar->type) {
-			pf->tvar->type = strdup(pf->pvar->type);
-			if (pf->tvar->type == NULL)
-				return -ENOMEM;
-		}
-		if (pf->pvar->name) {
-			pf->tvar->name = strdup(pf->pvar->name);
-			if (pf->tvar->name == NULL)
-				return -ENOMEM;
-		} else
-			pf->tvar->name = NULL;
-		return 0;
-	}
+	/* Copy raw parameters */
+	if (!is_c_varname(pf->pvar->var))
+		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
 
 	if (pf->pvar->name)
 		pf->tvar->name = strdup(pf->pvar->name);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213452 — RE: [PATCH 16/16] perf probe: Support probing at absolute addresses

From平松雅巳 / HIRAMATU,MASAMI <masami.hiramatsu.pt@hitachi.com>
Date2015-08-26 02:10 +0200
SubjectRE: [PATCH 16/16] perf probe: Support probing at absolute addresses
Message-ID<q1wrU-5N8-21@gated-at.bofh.it>
In reply to#1213147
QXJuYWxkbywgSSBkb24ndCB0aGluayB3ZSBuZWVkICIrIi4gDQoNClNvLCBOYWsgaXQuDQoNCj4g
LS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogQXJuYWxkbyBDYXJ2YWxobyBkZSBN
ZWxvIFttYWlsdG86YWNtZUBrZXJuZWwub3JnXQ0KPiBTZW50OiBXZWRuZXNkYXksIEF1Z3VzdCAy
NiwgMjAxNSAxOjE1IEFNDQo+IFRvOiBJbmdvIE1vbG5hcg0KPiBDYzogbGludXgta2VybmVsQHZn
ZXIua2VybmVsLm9yZzsgV2FuZyBOYW47IOW5s+advumbheW3syAvIEhJUkFNQVRV77yMTUFTQU1J
OyBOYW1oeXVuZyBLaW07IHBpM29yYW1hQDE2My5jb207IEFybmFsZG8gQ2FydmFsaG8NCj4gZGUg
TWVsbw0KPiBTdWJqZWN0OiBbIV1bUEFUQ0ggMTYvMTZdIHBlcmYgcHJvYmU6IFN1cHBvcnQgcHJv
YmluZyBhdCBhYnNvbHV0ZSBhZGRyZXNzZXMNCj4gDQo+IEZyb206IFdhbmcgTmFuIDx3YW5nbmFu
MEBodWF3ZWkuY29tPg0KPiANCj4gSXQgc2hvdWxkIGJlIHVzZWZ1bCB0byBhbGxvdyAncGVyZiBw
cm9iZScgcHJvYmUgYXQgYWJzb2x1dGUgb2Zmc2V0cyBvZiBhDQo+IHRhcmdldC4NCj4gDQo+IEZv
ciBleGFtcGxlLCB3aGVuICh1KXByb2JpbmcgYXQgYSBpbnN0cnVjdGlvbiBvZiBhIHNoYXJlZCBv
YmplY3QgaW4gYW4NCj4gZW1iZWRkZWQgc3lzdGVtIHdoZXJlIGRlYnVnaW5mbyBpcyBub3QgYXZh
aWxhYmxlIGJ1dCB3ZSBrbm93IHRoZSBvZmZzZXQNCj4gb2YgdGhhdCBpbnN0cnVjdGlvbiBieSBt
YW51YWxseSBkaWdnaW5nLg0KPiANCj4gVGhpcyBwYXRjaCBlbmFibGVzIGZvbGxvd2luZyBwZXJm
IHByb2JlIGNvbW1hbmQgc3ludGF4Og0KPiANCj4gICAjIHBlcmYgcHJvYmUgKzB4ZmZmZmZmZmY4
MTFlNjYxNQ0KPiANCj4gQW5kDQo+IA0KPiAgICMgcGVyZiBwcm9iZSAvbGliL3g4Nl82NC1saW51
eC1nbnUvbGliYy0yLjE5LnNvICsweGViODYwDQo+IA0KPiBJbiB0aGUgYWJvdmUgZXhhbXBsZSwg
d2UgZG9uJ3QgbmVlZCBhIGFuY2hvciBzeW1ib2wsIHNvIGl0IGlzIHBvc3NpYmxlDQo+IHRvIGNv
bXB1dGUgYWJzb2x1dGUgYWRkcmVzc2VzIHVzaW5nIG90aGVyIG1ldGhvZHMgYW5kIHRoZW4gdXNl
ICdwZXJmDQo+IHByb2JlJyB0byBjcmVhdGUgdGhlIHByb2JpbmcgcG9pbnRzLg0KPiANCj4gQ29t
bWl0dGVyIG5vdGU6DQo+IA0KPiBPbmUgY2FuIGFzIHdlbGwgc3BlY2lmeSBhIG5hbWUsIHNvIHRo
YXQgdGhlIHByb2JlIGRvZXNuJ3QgZ2V0IGFzc2lnbmVkIGENCj4gZ2VuZXJpYyBvbmUgc3RhcnRp
bmcgd2l0aCBhYnNfLCBpLmUuIGlmIHdlIHVzZSBhcyBkZXNjcmliZWQgYWJvdmUgd2UNCj4gZ2V0
Og0KPiANCj4gICBbcm9vdEB6b28gfl0jIHJlYWRlbGYgLXNXICAvbGliNjQvbGliYy0yLjIwLnNv
IHwgZ3JlcCAtdyBtYWxsb2MNCj4gICAgIDExNzU6IDAwMDAwMDAwMDAwODMwZjAgICAzMDAgRlVO
QyAgICBHTE9CQUwgREVGQVVMVCAgIDEyIG1hbGxvY0BAR0xJQkNfMi4yLjUNCj4gICAgICA4MTM6
IDAwMDAwMDAwMDAwMDAwMDAgICAgIDAgRklMRSAgICBMT0NBTCAgREVGQVVMVCAgQUJTIG1hbGxv
Yy5jDQo+ICAgICA1Mjc2OiAwMDAwMDAwMDAwMDgzMGYwICAgMzAwIEZVTkMgICAgR0xPQkFMIERF
RkFVTFQgICAxMiBtYWxsb2MNCj4gICBbcm9vdEB6b28gfl0jDQo+ICAgW3Jvb3RAem9vIH5dIyBw
ZXJmIHByb2JlIC9saWI2NC9saWJjLTIuMjAuc28gKzB4ODMwZjANCj4gICBBZGRlZCBuZXcgZXZl
bnQ6DQo+ICAgICBwcm9iZV9saWJjOmFic184MzBmMCAob24gMHg4MzBmMCBpbiAvbGliNjQvbGli
Yy0yLjIwLnNvKQ0KPiANCj4gICBZb3UgY2FuIG5vdyB1c2UgaXQgaW4gYWxsIHBlcmYgdG9vbHMs
IHN1Y2ggYXM6DQo+IA0KPiAJcGVyZiByZWNvcmQgLWUgcHJvYmVfbGliYzphYnNfODMwZjAgLWFS
IHNsZWVwIDENCj4gDQo+ICAgW3Jvb3RAem9vIH5dIw0KPiAgIFtyb290QHpvbyB+XSMgcGVyZiBw
cm9iZSAtbA0KPiAgICAgcHJvYmVfbGliYzphYnNfODMwZjAgKG9uIF9fbGliY19tYWxsb2NAZ2xp
YmMtMi4yMC9tYWxsb2MvbWFsbG9jLmMgaW4gL2xpYjY0L2xpYmMtMi4yMC5zbykNCj4gICBbcm9v
dEB6b28gfl0jDQo+IA0KPiBXaGVyZWFzIGlmIHdlIGFzc2lnbiBpdCBhIG5hbWUgaXQgZ2V0cyBt
b3JlIG1hbmFnZWFibGU6DQo+IA0KPiAgIFtyb290QHpvbyB+XSMgcGVyZiBwcm9iZSAvbGliNjQv
bGliYy0yLjIwLnNvIG1hbGxvYz0rMHg4MzBmMA0KPiAgIEFkZGVkIG5ldyBldmVudDoNCj4gICAg
IHByb2JlX2xpYmM6bWFsbG9jICAgIChvbiAweDgzMGYwIGluIC9saWI2NC9saWJjLTIuMjAuc28p
DQo+IA0KPiAgIFlvdSBjYW4gbm93IHVzZSBpdCBpbiBhbGwgcGVyZiB0b29scywgc3VjaCBhczoN
Cj4gDQo+IAlwZXJmIHJlY29yZCAtZSBwcm9iZV9saWJjOm1hbGxvYyAtYVIgc2xlZXAgMQ0KPiAN
Cj4gICBbcm9vdEB6b28gfl0jIHBlcmYgcHJvYmUgLWwNCj4gICAgIHByb2JlX2xpYmM6bWFsbG9j
ICAgIChvbiBfX2xpYmNfbWFsbG9jQGdsaWJjLTIuMjAvbWFsbG9jL21hbGxvYy5jIGluIC9saWI2
NC9saWJjLTIuMjAuc28pDQo+ICAgW3Jvb3RAem9vIH5dIw0KPiANCj4gQm90aCwgb2YgY291cnNl
LCB3aWxsIHByb2R1Y2UgdGhlIHNhbWUgcmVzdWx0cywgYW5kIHdlIGNhbiB1c2UgYQ0KPiBub24g
Y2Fub25pY2FsIG5hbWUsIGlmIHRoZSBuZWVkIGFyaXNlczoNCj4gDQo+ICAgW3Jvb3RAem9vIH5d
IyBwZXJmIHByb2JlIC9saWI2NC9saWJjLTIuMjAuc28gbWVtb3J5X2FsbG9jYXRpb249KzB4ODMw
ZjANCj4gICBBZGRlZCBuZXcgZXZlbnQ6DQo+ICAgICBwcm9iZV9saWJjOm1lbW9yeV9hbGxvY2F0
aW9uIChvbiAweDgzMGYwIGluIC9saWI2NC9saWJjLTIuMjAuc28pDQo+IA0KPiAgIFlvdSBjYW4g
bm93IHVzZSBpdCBpbiBhbGwgcGVyZiB0b29scywgc3VjaCBhczoNCj4gDQo+IAlwZXJmIHJlY29y
ZCAtZSBwcm9iZV9saWJjOm1lbW9yeV9hbGxvY2F0aW9uIC1hUiBzbGVlcCAxDQo+IA0KPiAgIFty
b290QHpvbyB+XSMgcGVyZiBwcm9iZSAtbA0KPiAgICAgcHJvYmVfbGliYzptZW1vcnlfYWxsb2Nh
dGlvbiAob24gX19saWJjX21hbGxvY0BnbGliYy0yLjIwL21hbGxvYy9tYWxsb2MuYyBpbiAvbGli
NjQvbGliYy0yLjIwLnNvKQ0KPiAgIFtyb290QHpvbyB+XSMNCj4gDQo+IFNpZ25lZC1vZmYtYnk6
IFdhbmcgTmFuIDx3YW5nbmFuMEBodWF3ZWkuY29tPg0KPiBUZXN0ZWQtYnk6IEFybmFsZG8gQ2Fy
dmFsaG8gZGUgTWVsbyA8YWNtZUByZWRoYXQuY29tPg0KPiBDYzogTWFzYW1pIEhpcmFtYXRzdSA8
bWFzYW1pLmhpcmFtYXRzdS5wdEBoaXRhY2hpLmNvbT4NCj4gQ2M6IE5hbWh5dW5nIEtpbSA8bmFt
aHl1bmdAa2VybmVsLm9yZz4NCj4gQ2M6IHBpM29yYW1hQDE2My5jb20NCj4gTGluazogaHR0cDov
L2xrbWwua2VybmVsLm9yZy9yLzE0NDA1MDkyNTYtMTkzNTkwLTItZ2l0LXNlbmQtZW1haWwtd2Fu
Z25hbjBAaHVhd2VpLmNvbQ0KPiBTaWduZWQtb2ZmLWJ5OiBBcm5hbGRvIENhcnZhbGhvIGRlIE1l
bG8gPGFjbWVAcmVkaGF0LmNvbT4NCj4gLS0tDQo+ICB0b29scy9wZXJmL3V0aWwvcHJvYmUtZXZl
bnQuYyAgfCAxNDQgKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0tLS0NCj4g
IHRvb2xzL3BlcmYvdXRpbC9wcm9iZS1ldmVudC5oICB8ICAgMyArDQo+ICB0b29scy9wZXJmL3V0
aWwvcHJvYmUtZmluZGVyLmMgfCAgMjEgKy0tLS0tDQo+ICAzIGZpbGVzIGNoYW5nZWQsIDEzOCBp
bnNlcnRpb25zKCspLCAzMCBkZWxldGlvbnMoLSkNCj4gDQo+IGRpZmYgLS1naXQgYS90b29scy9w
ZXJmL3V0aWwvcHJvYmUtZXZlbnQuYyBiL3Rvb2xzL3BlcmYvdXRpbC9wcm9iZS1ldmVudC5jDQo+
IGluZGV4IDZjN2U1MzhjOWI4Yi4uNTlkZTY5YTRlM2FjIDEwMDY0NA0KPiAtLS0gYS90b29scy9w
ZXJmL3V0aWwvcHJvYmUtZXZlbnQuYw0KPiArKysgYi90b29scy9wZXJmL3V0aWwvcHJvYmUtZXZl
bnQuYw0KPiBAQCAtMTE5NCw5ICsxMTk0LDEzIEBAIHN0YXRpYyBpbnQgcGFyc2VfcGVyZl9wcm9i
ZV9wb2ludChjaGFyICphcmcsIHN0cnVjdCBwZXJmX3Byb2JlX2V2ZW50ICpwZXYpDQo+ICAJCSpw
dHIrKyA9ICdcMCc7DQo+ICAJfQ0KPiANCj4gLQl0bXAgPSBzdHJkdXAoYXJnKTsNCj4gLQlpZiAo
dG1wID09IE5VTEwpDQo+IC0JCXJldHVybiAtRU5PTUVNOw0KPiArCWlmIChhcmdbMF0gPT0gJ1ww
JykNCj4gKwkJdG1wID0gTlVMTDsNCj4gKwllbHNlIHsNCj4gKwkJdG1wID0gc3RyZHVwKGFyZyk7
DQo+ICsJCWlmICh0bXAgPT0gTlVMTCkNCj4gKwkJCXJldHVybiAtRU5PTUVNOw0KPiArCX0NCj4g
DQo+ICAJaWYgKGZpbGVfc3BlYykNCj4gIAkJcHAtPmZpbGUgPSB0bXA7DQo+IEBAIC0xMjgzLDEx
ICsxMjg3LDYgQEAgc3RhdGljIGludCBwYXJzZV9wZXJmX3Byb2JlX3BvaW50KGNoYXIgKmFyZywg
c3RydWN0IHBlcmZfcHJvYmVfZXZlbnQgKnBldikNCj4gIAkJcmV0dXJuIC1FSU5WQUw7DQo+ICAJ
fQ0KPiANCj4gLQlpZiAocHAtPm9mZnNldCAmJiAhcHAtPmZ1bmN0aW9uKSB7DQo+IC0JCXNlbWFu
dGljX2Vycm9yKCJPZmZzZXQgcmVxdWlyZXMgYW4gZW50cnkgZnVuY3Rpb24uXG4iKTsNCj4gLQkJ
cmV0dXJuIC1FSU5WQUw7DQo+IC0JfQ0KPiAtDQo+ICAJaWYgKHBwLT5yZXRwcm9iZSAmJiAhcHAt
PmZ1bmN0aW9uKSB7DQo+ICAJCXNlbWFudGljX2Vycm9yKCJSZXR1cm4gcHJvYmUgcmVxdWlyZXMg
YW4gZW50cnkgZnVuY3Rpb24uXG4iKTsNCj4gIAkJcmV0dXJuIC1FSU5WQUw7DQo+IEBAIC0xMjk5
LDYgKzEyOTgsMTEgQEAgc3RhdGljIGludCBwYXJzZV9wZXJmX3Byb2JlX3BvaW50KGNoYXIgKmFy
Zywgc3RydWN0IHBlcmZfcHJvYmVfZXZlbnQgKnBldikNCj4gIAkJcmV0dXJuIC1FSU5WQUw7DQo+
ICAJfQ0KPiANCj4gKwlpZiAoIXBwLT5mdW5jdGlvbiAmJiAhcHAtPm9mZnNldCAmJiAhcHAtPmZp
bGUpIHsNCj4gKwkJc2VtYW50aWNfZXJyb3IoIkFic29sdXRlIGFkZHJlc3Mgc2hvdWxkIG5vdCBi
ZSB6ZXJvLlxuIik7DQo+ICsJCXJldHVybiAtRUlOVkFMOw0KPiArCX0NCj4gKw0KPiAgCXByX2Rl
YnVnKCJzeW1ib2w6JXMgZmlsZTolcyBsaW5lOiVkIG9mZnNldDolbHUgcmV0dXJuOiVkIGxhenk6
JXNcbiIsDQo+ICAJCSBwcC0+ZnVuY3Rpb24sIHBwLT5maWxlLCBwcC0+bGluZSwgcHAtPm9mZnNl
dCwgcHAtPnJldHByb2JlLA0KPiAgCQkgcHAtPmxhenlfbGluZSk7DQo+IEBAIC0xNjA5LDcgKzE2
MTMsNyBAQCBlcnJvcjoNCj4gIHN0YXRpYyBjaGFyICpzeW50aGVzaXplX3BlcmZfcHJvYmVfcG9p
bnQoc3RydWN0IHBlcmZfcHJvYmVfcG9pbnQgKnBwKQ0KPiAgew0KPiAgCWNoYXIgKmJ1ZiwgKnRt
cDsNCj4gLQljaGFyIG9mZnNbMzJdID0gIiIsIGxpbmVbMzJdID0gIiIsIGZpbGVbMzJdID0gIiI7
DQo+ICsJY2hhciBvZmZzWzMyXSA9ICIiLCBsaW5lWzMyXSA9ICIiLCBmaWxlWzMyXSA9ICIiLCBh
ZGRyWzMyXSA9ICIiOw0KPiAgCWludCByZXQsIGxlbjsNCj4gDQo+ICAJYnVmID0gemFsbG9jKE1B
WF9DTURMRU4pOw0KPiBAQCAtMTYyMiw2ICsxNjI2LDExIEBAIHN0YXRpYyBjaGFyICpzeW50aGVz
aXplX3BlcmZfcHJvYmVfcG9pbnQoc3RydWN0IHBlcmZfcHJvYmVfcG9pbnQgKnBwKQ0KPiAgCQlp
ZiAocmV0IDw9IDApDQo+ICAJCQlnb3RvIGVycm9yOw0KPiAgCX0NCj4gKwlpZiAoIXBwLT5mdW5j
dGlvbikgew0KPiArCQlyZXQgPSBlX3NucHJpbnRmKGFkZHIsIDMyLCAiMHglbHgiLCBwcC0+b2Zm
c2V0KTsNCj4gKwkJaWYgKHJldCA8PSAwKQ0KPiArCQkJZ290byBlcnJvcjsNCj4gKwl9DQo+ICAJ
aWYgKHBwLT5saW5lKSB7DQo+ICAJCXJldCA9IGVfc25wcmludGYobGluZSwgMzIsICI6JWQiLCBw
cC0+bGluZSk7DQo+ICAJCWlmIChyZXQgPD0gMCkNCj4gQEAgLTE2MzksOSArMTY0OCwxMSBAQCBz
dGF0aWMgY2hhciAqc3ludGhlc2l6ZV9wZXJmX3Byb2JlX3BvaW50KHN0cnVjdCBwZXJmX3Byb2Jl
X3BvaW50ICpwcCkNCj4gIAkJCWdvdG8gZXJyb3I7DQo+ICAJfQ0KPiANCj4gLQlpZiAocHAtPmZ1
bmN0aW9uKQ0KPiAtCQlyZXQgPSBlX3NucHJpbnRmKGJ1ZiwgTUFYX0NNRExFTiwgIiVzJXMlcyVz
JXMiLCBwcC0+ZnVuY3Rpb24sDQo+IC0JCQkJIG9mZnMsIHBwLT5yZXRwcm9iZSA/ICIlcmV0dXJu
IiA6ICIiLCBsaW5lLA0KPiArCWlmIChwcC0+ZnVuY3Rpb24gfHwgcHAtPm9mZnNldCkNCj4gKwkJ
cmV0ID0gZV9zbnByaW50ZihidWYsIE1BWF9DTURMRU4sICIlcyVzJXMlcyVzIiwNCj4gKwkJCQkg
cHAtPmZ1bmN0aW9uID8gOiBhZGRyLA0KPiArCQkJCSBwcC0+ZnVuY3Rpb24gPyBvZmZzIDogIiIs
DQo+ICsJCQkJIHBwLT5yZXRwcm9iZSA/ICIlcmV0dXJuIiA6ICIiLCBsaW5lLA0KPiAgCQkJCSBm
aWxlKTsNCj4gIAllbHNlDQo+ICAJCXJldCA9IGVfc25wcmludGYoYnVmLCBNQVhfQ01ETEVOLCAi
JXMlcyIsIGZpbGUsIGxpbmUpOw0KPiBAQCAtMTc4Niw2ICsxNzk3LDExIEBAIGNoYXIgKnN5bnRo
ZXNpemVfcHJvYmVfdHJhY2VfY29tbWFuZChzdHJ1Y3QgcHJvYmVfdHJhY2VfZXZlbnQgKnRldikN
Cj4gIAlpZiAodGV2LT51cHJvYmVzKQ0KPiAgCQlyZXQgPSBlX3NucHJpbnRmKGJ1ZiArIGxlbiwg
TUFYX0NNRExFTiAtIGxlbiwgIiVzOjB4JWx4IiwNCj4gIAkJCQkgdHAtPm1vZHVsZSwgdHAtPmFk
ZHJlc3MpOw0KPiArCWVsc2UgaWYgKHRwLT5zeW1ib2xbMF0gPT0gJzAnICYmIHRwLT5zeW1ib2xb
MV0gPT0gJ3gnKQ0KPiArCQkvKiBBYnNvbHV0ZSBhZGRyZXNzLiBTZWUgdHJ5X3RvX2ZpbmRfYWJz
b2x1dGVfYWRkcmVzcygpICovDQo+ICsJCXJldCA9IGVfc25wcmludGYoYnVmICsgbGVuLCBNQVhf
Q01ETEVOIC0gbGVuLCAiJXMlczB4JWx4IiwNCj4gKwkJCQkgdHAtPm1vZHVsZSA/OiAiIiwgdHAt
Pm1vZHVsZSA/ICI6IiA6ICIiLA0KPiArCQkJCSB0cC0+YWRkcmVzcyk7DQo+ICAJZWxzZQ0KPiAg
CQlyZXQgPSBlX3NucHJpbnRmKGJ1ZiArIGxlbiwgTUFYX0NNRExFTiAtIGxlbiwgIiVzJXMlcysl
bHUiLA0KPiAgCQkJCSB0cC0+bW9kdWxlID86ICIiLCB0cC0+bW9kdWxlID8gIjoiIDogIiIsDQo+
IEBAIC0yNTcyLDYgKzI1ODgsODcgQEAgZXJyX291dDoNCj4gIAlnb3RvIG91dDsNCj4gIH0NCj4g
DQo+ICtzdGF0aWMgaW50IHRyeV90b19maW5kX2Fic29sdXRlX2FkZHJlc3Moc3RydWN0IHBlcmZf
cHJvYmVfZXZlbnQgKnBldiwNCj4gKwkJCQkJc3RydWN0IHByb2JlX3RyYWNlX2V2ZW50ICoqdGV2
cykNCj4gK3sNCj4gKwlzdHJ1Y3QgcGVyZl9wcm9iZV9wb2ludCAqcHAgPSAmcGV2LT5wb2ludDsN
Cj4gKwlzdHJ1Y3QgcHJvYmVfdHJhY2VfZXZlbnQgKnRldjsNCj4gKwlzdHJ1Y3QgcHJvYmVfdHJh
Y2VfcG9pbnQgKnRwOw0KPiArCWludCBpLCBlcnI7DQo+ICsNCj4gKwlpZiAocGVyZl9wcm9iZV9l
dmVudF9uZWVkX2R3YXJmKHBldikgfHwgcGV2LT5wb2ludC5mdW5jdGlvbikNCj4gKwkJcmV0dXJu
IC1FSU5WQUw7DQo+ICsNCj4gKwkvKg0KPiArCSAqIFRoaXMgaXMgJ3BlcmYgcHJvYmUgL2xpYi9s
aWJjLnNvICsweGFiY2QnLiBUcnkgdG8gcHJvYmUgYXQNCj4gKwkgKiBhYnNvbHV0ZSBhZGRyZXNz
Lg0KPiArCSAqDQo+ICsJICogT25seSBvbmUgdGV2IGNhbiBiZSBnZW5lcmF0ZWQgYnkgdGhpcy4N
Cj4gKwkgKi8NCj4gKwkqdGV2cyA9IHphbGxvYyhzaXplb2YoKnRldikpOw0KPiArCWlmICghKnRl
dnMpDQo+ICsJCXJldHVybiAtRU5PTUVNOw0KPiArDQo+ICsJdGV2ID0gKnRldnM7DQo+ICsJdHAg
PSAmdGV2LT5wb2ludDsNCj4gKw0KPiArCS8qDQo+ICsJICogRG9uJ3QgdXNlIHRwLT5vZmZzZXQs
IHVzZSBhZGRyZXNzIGRpcmVjdGx5LCBiZWNhdXNlDQo+ICsJICogaW4gc3ludGhlc2l6ZV9wcm9i
ZV90cmFjZV9jb21tYW5kKCkgYWRkcmVzcyBjYW5ub3QgYmUNCj4gKwkgKiB6ZXJvLg0KPiArCSAq
Lw0KPiArCXRwLT5hZGRyZXNzID0gcGV2LT5wb2ludC5vZmZzZXQ7DQo+ICsJdHAtPnJldHByb2Jl
ID0gcHAtPnJldHByb2JlOw0KPiArCXRldi0+dXByb2JlcyA9IHBldi0+dXByb2JlczsNCj4gKw0K
PiArCWVyciA9IC1FTk9NRU07DQo+ICsJLyogR2l2ZSBpdCBhICcweCcgbGVhZGluZyBzeW1ib2wg
bmFtZSAqLw0KPiArCWlmIChhc3ByaW50ZigmdHAtPnN5bWJvbCwgIjB4JWx4IiwgdHAtPmFkZHJl
c3MpIDwgMCkNCj4gKwkJZ290byBlcnJvdXQ7DQo+ICsNCj4gKwkvKiBGb3Iga3Byb2JlLCBjaGVj
ayByYW5nZSAqLw0KPiArCWlmICgoIXRldi0+dXByb2JlcykgJiYNCj4gKwkgICAgKGtwcm9iZV93
YXJuX291dF9yYW5nZSh0ZXYtPnBvaW50LnN5bWJvbCwNCj4gKwkJCQkgICB0ZXYtPnBvaW50LmFk
ZHJlc3MpKSkgew0KPiArCQllcnIgPSAtRUFDQ0VTOw0KPiArCQlnb3RvIGVycm91dDsNCj4gKwl9
DQo+ICsNCj4gKwlpZiAoYXNwcmludGYoJnRwLT5yZWFsbmFtZSwgImFic18lbHgiLCB0cC0+YWRk
cmVzcykgPCAwKQ0KPiArCQlnb3RvIGVycm91dDsNCj4gKw0KPiArCWlmIChwZXYtPnRhcmdldCkg
ew0KPiArCQl0cC0+bW9kdWxlID0gc3RyZHVwKHBldi0+dGFyZ2V0KTsNCj4gKwkJaWYgKCF0cC0+
bW9kdWxlKQ0KPiArCQkJZ290byBlcnJvdXQ7DQo+ICsJfQ0KPiArDQo+ICsJaWYgKHRldi0+Z3Jv
dXApIHsNCj4gKwkJdGV2LT5ncm91cCA9IHN0cmR1cChwZXYtPmdyb3VwKTsNCj4gKwkJaWYgKCF0
ZXYtPmdyb3VwKQ0KPiArCQkJZ290byBlcnJvdXQ7DQo+ICsJfQ0KPiArDQo+ICsJaWYgKHBldi0+
ZXZlbnQpIHsNCj4gKwkJdGV2LT5ldmVudCA9IHN0cmR1cChwZXYtPmV2ZW50KTsNCj4gKwkJaWYg
KCF0ZXYtPmV2ZW50KQ0KPiArCQkJZ290byBlcnJvdXQ7DQo+ICsJfQ0KPiArDQo+ICsJdGV2LT5u
YXJncyA9IHBldi0+bmFyZ3M7DQo+ICsJZm9yIChpID0gMDsgaSA8IHRldi0+bmFyZ3M7IGkrKykN
Cj4gKwkJY29weV90b19wcm9iZV90cmFjZV9hcmcoJnRldi0+YXJnc1tpXSwgJnBldi0+YXJnc1tp
XSk7DQo+ICsNCj4gKwlyZXR1cm4gMTsNCj4gKw0KPiArZXJyb3V0Og0KPiArCWlmICgqdGV2cykg
ew0KPiArCQljbGVhcl9wcm9iZV90cmFjZV9ldmVudHMoKnRldnMsIDEpOw0KPiArCQkqdGV2cyA9
IE5VTEw7DQo+ICsJfQ0KPiArCXJldHVybiBlcnI7DQo+ICt9DQo+ICsNCj4gIGJvb2wgX193ZWFr
IGFyY2hfX3ByZWZlcnNfc3ltdGFiKHZvaWQpIHsgcmV0dXJuIGZhbHNlOyB9DQo+IA0KPiAgc3Rh
dGljIGludCBjb252ZXJ0X3RvX3Byb2JlX3RyYWNlX2V2ZW50cyhzdHJ1Y3QgcGVyZl9wcm9iZV9l
dmVudCAqcGV2LA0KPiBAQCAtMjU4OCw2ICsyNjg1LDEwIEBAIHN0YXRpYyBpbnQgY29udmVydF90
b19wcm9iZV90cmFjZV9ldmVudHMoc3RydWN0IHBlcmZfcHJvYmVfZXZlbnQgKnBldiwNCj4gIAkJ
fQ0KPiAgCX0NCj4gDQo+ICsJcmV0ID0gdHJ5X3RvX2ZpbmRfYWJzb2x1dGVfYWRkcmVzcyhwZXYs
IHRldnMpOw0KPiArCWlmIChyZXQgPiAwKQ0KPiArCQlyZXR1cm4gcmV0Ow0KPiArDQo+ICAJaWYg
KGFyY2hfX3ByZWZlcnNfc3ltdGFiKCkgJiYgIXBlcmZfcHJvYmVfZXZlbnRfbmVlZF9kd2FyZihw
ZXYpKSB7DQo+ICAJCXJldCA9IGZpbmRfcHJvYmVfdHJhY2VfZXZlbnRzX2Zyb21fbWFwKHBldiwg
dGV2cyk7DQo+ICAJCWlmIChyZXQgPiAwKQ0KPiBAQCAtMjc1OCwzICsyODU5LDIyIEBAIGVuZDoN
Cj4gIAlyZXR1cm4gcmV0Ow0KPiAgfQ0KPiANCj4gK2ludCBjb3B5X3RvX3Byb2JlX3RyYWNlX2Fy
ZyhzdHJ1Y3QgcHJvYmVfdHJhY2VfYXJnICp0dmFyLA0KPiArCQkJICAgIHN0cnVjdCBwZXJmX3By
b2JlX2FyZyAqcHZhcikNCj4gK3sNCj4gKwl0dmFyLT52YWx1ZSA9IHN0cmR1cChwdmFyLT52YXIp
Ow0KPiArCWlmICh0dmFyLT52YWx1ZSA9PSBOVUxMKQ0KPiArCQlyZXR1cm4gLUVOT01FTTsNCj4g
KwlpZiAocHZhci0+dHlwZSkgew0KPiArCQl0dmFyLT50eXBlID0gc3RyZHVwKHB2YXItPnR5cGUp
Ow0KPiArCQlpZiAodHZhci0+dHlwZSA9PSBOVUxMKQ0KPiArCQkJcmV0dXJuIC1FTk9NRU07DQo+
ICsJfQ0KPiArCWlmIChwdmFyLT5uYW1lKSB7DQo+ICsJCXR2YXItPm5hbWUgPSBzdHJkdXAocHZh
ci0+bmFtZSk7DQo+ICsJCWlmICh0dmFyLT5uYW1lID09IE5VTEwpDQo+ICsJCQlyZXR1cm4gLUVO
T01FTTsNCj4gKwl9IGVsc2UNCj4gKwkJdHZhci0+bmFtZSA9IE5VTEw7DQo+ICsJcmV0dXJuIDA7
DQo+ICt9DQo+IGRpZmYgLS1naXQgYS90b29scy9wZXJmL3V0aWwvcHJvYmUtZXZlbnQuaCBiL3Rv
b2xzL3BlcmYvdXRpbC9wcm9iZS1ldmVudC5oDQo+IGluZGV4IDgzZWU5NWU5NzQzYi4uMTc0YTNj
ZjZjMDNkIDEwMDY0NA0KPiAtLS0gYS90b29scy9wZXJmL3V0aWwvcHJvYmUtZXZlbnQuaA0KPiAr
KysgYi90b29scy9wZXJmL3V0aWwvcHJvYmUtZXZlbnQuaA0KPiBAQCAtMTU2LDQgKzE1Niw3IEBA
IGludCBlX3NucHJpbnRmKGNoYXIgKnN0ciwgc2l6ZV90IHNpemUsIGNvbnN0IGNoYXIgKmZvcm1h
dCwgLi4uKQ0KPiAgLyogTWF4aW11bSBpbmRleCBudW1iZXIgb2YgZXZlbnQtbmFtZSBwb3N0Zml4
ICovDQo+ICAjZGVmaW5lIE1BWF9FVkVOVF9JTkRFWAkxMDI0DQo+IA0KPiAraW50IGNvcHlfdG9f
cHJvYmVfdHJhY2VfYXJnKHN0cnVjdCBwcm9iZV90cmFjZV9hcmcgKnR2YXIsDQo+ICsJCQkgICAg
c3RydWN0IHBlcmZfcHJvYmVfYXJnICpwdmFyKTsNCj4gKw0KPiAgI2VuZGlmIC8qX1BST0JFX0VW
RU5UX0ggKi8NCj4gZGlmZiAtLWdpdCBhL3Rvb2xzL3BlcmYvdXRpbC9wcm9iZS1maW5kZXIuYyBi
L3Rvb2xzL3BlcmYvdXRpbC9wcm9iZS1maW5kZXIuYw0KPiBpbmRleCA3YjgwZjhjYjYyYjkuLjI5
YzQzYzA2ODBhOCAxMDA2NDQNCj4gLS0tIGEvdG9vbHMvcGVyZi91dGlsL3Byb2JlLWZpbmRlci5j
DQo+ICsrKyBiL3Rvb2xzL3BlcmYvdXRpbC9wcm9iZS1maW5kZXIuYw0KPiBAQCAtNTUzLDI0ICs1
NTMsOSBAQCBzdGF0aWMgaW50IGZpbmRfdmFyaWFibGUoRHdhcmZfRGllICpzY19kaWUsIHN0cnVj
dCBwcm9iZV9maW5kZXIgKnBmKQ0KPiAgCWNoYXIgYnVmWzMyXSwgKnB0cjsNCj4gIAlpbnQgcmV0
ID0gMDsNCj4gDQo+IC0JaWYgKCFpc19jX3Zhcm5hbWUocGYtPnB2YXItPnZhcikpIHsNCj4gLQkJ
LyogQ29weSByYXcgcGFyYW1ldGVycyAqLw0KPiAtCQlwZi0+dHZhci0+dmFsdWUgPSBzdHJkdXAo
cGYtPnB2YXItPnZhcik7DQo+IC0JCWlmIChwZi0+dHZhci0+dmFsdWUgPT0gTlVMTCkNCj4gLQkJ
CXJldHVybiAtRU5PTUVNOw0KPiAtCQlpZiAocGYtPnB2YXItPnR5cGUpIHsNCj4gLQkJCXBmLT50
dmFyLT50eXBlID0gc3RyZHVwKHBmLT5wdmFyLT50eXBlKTsNCj4gLQkJCWlmIChwZi0+dHZhci0+
dHlwZSA9PSBOVUxMKQ0KPiAtCQkJCXJldHVybiAtRU5PTUVNOw0KPiAtCQl9DQo+IC0JCWlmIChw
Zi0+cHZhci0+bmFtZSkgew0KPiAtCQkJcGYtPnR2YXItPm5hbWUgPSBzdHJkdXAocGYtPnB2YXIt
Pm5hbWUpOw0KPiAtCQkJaWYgKHBmLT50dmFyLT5uYW1lID09IE5VTEwpDQo+IC0JCQkJcmV0dXJu
IC1FTk9NRU07DQo+IC0JCX0gZWxzZQ0KPiAtCQkJcGYtPnR2YXItPm5hbWUgPSBOVUxMOw0KPiAt
CQlyZXR1cm4gMDsNCj4gLQl9DQo+ICsJLyogQ29weSByYXcgcGFyYW1ldGVycyAqLw0KPiArCWlm
ICghaXNfY192YXJuYW1lKHBmLT5wdmFyLT52YXIpKQ0KPiArCQlyZXR1cm4gY29weV90b19wcm9i
ZV90cmFjZV9hcmcocGYtPnR2YXIsIHBmLT5wdmFyKTsNCj4gDQo+ICAJaWYgKHBmLT5wdmFyLT5u
YW1lKQ0KPiAgCQlwZi0+dHZhci0+bmFtZSA9IHN0cmR1cChwZi0+cHZhci0+bmFtZSk7DQo+IC0t
DQo+IDIuMS4wDQoNCg==
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213831 — Re: [PATCH 16/16] perf probe: Support probing at absolute addresses

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-26 15:00 +0200
SubjectRe: [PATCH 16/16] perf probe: Support probing at absolute addresses
Message-ID<q1It4-6bl-7@gated-at.bofh.it>
In reply to#1213452
Em Wed, Aug 26, 2015 at 12:00:56AM +0000, 平松雅巳 / HIRAMATU,MASAMI escreveu:
> Arnaldo, I don't think we need "+". 

What would be the problem? When we write


 perf probe /lib/x86_64-linux-gnu/libc-2.19.so +0xeb860

What we're meaning is: Take the address where libc-2.19.so is loaded, in
each process, add (+) to that address the number 0xeb860 (an offset),
and when that probe is enabled, put a breakpoint there.

I saw it that way and thus to me it seemed really natural, thus I
applied.

> So, Nak it.

I don't have strong feelings about that one and I saw that there was a
long discussion, so I'll read it and process the patches, if I don't see
anything questionable.

Next time I'll try not to process perf probe patches so fast :-)

- Arnaldo
 
> > -----Original Message-----
> > From: Arnaldo Carvalho de Melo [mailto:acme@kernel.org]
> > Sent: Wednesday, August 26, 2015 1:15 AM
> > To: Ingo Molnar
> > Cc: linux-kernel@vger.kernel.org; Wang Nan; 平松雅巳 / HIRAMATU,MASAMI; Namhyung Kim; pi3orama@163.com; Arnaldo Carvalho
> > de Melo
> > Subject: [!][PATCH 16/16] perf probe: Support probing at absolute addresses
> > 
> > From: Wang Nan <wangnan0@huawei.com>
> > 
> > It should be useful to allow 'perf probe' probe at absolute offsets of a
> > target.
> > 
> > For example, when (u)probing at a instruction of a shared object in an
> > embedded system where debuginfo is not available but we know the offset
> > of that instruction by manually digging.
> > 
> > This patch enables following perf probe command syntax:
> > 
> >   # perf probe +0xffffffff811e6615
> > 
> > And
> > 
> >   # perf probe /lib/x86_64-linux-gnu/libc-2.19.so +0xeb860
> > 
> > In the above example, we don't need a anchor symbol, so it is possible
> > to compute absolute addresses using other methods and then use 'perf
> > probe' to create the probing points.
> > 
> > Committer note:
> > 
> > One can as well specify a name, so that the probe doesn't get assigned a
> > generic one starting with abs_, i.e. if we use as described above we
> > get:
> > 
> >   [root@zoo ~]# readelf -sW  /lib64/libc-2.20.so | grep -w malloc
> >     1175: 00000000000830f0   300 FUNC    GLOBAL DEFAULT   12 malloc@@GLIBC_2.2.5
> >      813: 0000000000000000     0 FILE    LOCAL  DEFAULT  ABS malloc.c
> >     5276: 00000000000830f0   300 FUNC    GLOBAL DEFAULT   12 malloc
> >   [root@zoo ~]#
> >   [root@zoo ~]# perf probe /lib64/libc-2.20.so +0x830f0
> >   Added new event:
> >     probe_libc:abs_830f0 (on 0x830f0 in /lib64/libc-2.20.so)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> > 	perf record -e probe_libc:abs_830f0 -aR sleep 1
> > 
> >   [root@zoo ~]#
> >   [root@zoo ~]# perf probe -l
> >     probe_libc:abs_830f0 (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> >   [root@zoo ~]#
> > 
> > Whereas if we assign it a name it gets more manageable:
> > 
> >   [root@zoo ~]# perf probe /lib64/libc-2.20.so malloc=+0x830f0
> >   Added new event:
> >     probe_libc:malloc    (on 0x830f0 in /lib64/libc-2.20.so)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> > 	perf record -e probe_libc:malloc -aR sleep 1
> > 
> >   [root@zoo ~]# perf probe -l
> >     probe_libc:malloc    (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> >   [root@zoo ~]#
> > 
> > Both, of course, will produce the same results, and we can use a
> > non canonical name, if the need arises:
> > 
> >   [root@zoo ~]# perf probe /lib64/libc-2.20.so memory_allocation=+0x830f0
> >   Added new event:
> >     probe_libc:memory_allocation (on 0x830f0 in /lib64/libc-2.20.so)
> > 
> >   You can now use it in all perf tools, such as:
> > 
> > 	perf record -e probe_libc:memory_allocation -aR sleep 1
> > 
> >   [root@zoo ~]# perf probe -l
> >     probe_libc:memory_allocation (on __libc_malloc@glibc-2.20/malloc/malloc.c in /lib64/libc-2.20.so)
> >   [root@zoo ~]#
> > 
> > Signed-off-by: Wang Nan <wangnan0@huawei.com>
> > Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
> > Cc: Namhyung Kim <namhyung@kernel.org>
> > Cc: pi3orama@163.com
> > Link: http://lkml.kernel.org/r/1440509256-193590-2-git-send-email-wangnan0@huawei.com
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> >  tools/perf/util/probe-event.c  | 144 +++++++++++++++++++++++++++++++++++++----
> >  tools/perf/util/probe-event.h  |   3 +
> >  tools/perf/util/probe-finder.c |  21 +-----
> >  3 files changed, 138 insertions(+), 30 deletions(-)
> > 
> > diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
> > index 6c7e538c9b8b..59de69a4e3ac 100644
> > --- a/tools/perf/util/probe-event.c
> > +++ b/tools/perf/util/probe-event.c
> > @@ -1194,9 +1194,13 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> >  		*ptr++ = '\0';
> >  	}
> > 
> > -	tmp = strdup(arg);
> > -	if (tmp == NULL)
> > -		return -ENOMEM;
> > +	if (arg[0] == '\0')
> > +		tmp = NULL;
> > +	else {
> > +		tmp = strdup(arg);
> > +		if (tmp == NULL)
> > +			return -ENOMEM;
> > +	}
> > 
> >  	if (file_spec)
> >  		pp->file = tmp;
> > @@ -1283,11 +1287,6 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> >  		return -EINVAL;
> >  	}
> > 
> > -	if (pp->offset && !pp->function) {
> > -		semantic_error("Offset requires an entry function.\n");
> > -		return -EINVAL;
> > -	}
> > -
> >  	if (pp->retprobe && !pp->function) {
> >  		semantic_error("Return probe requires an entry function.\n");
> >  		return -EINVAL;
> > @@ -1299,6 +1298,11 @@ static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
> >  		return -EINVAL;
> >  	}
> > 
> > +	if (!pp->function && !pp->offset && !pp->file) {
> > +		semantic_error("Absolute address should not be zero.\n");
> > +		return -EINVAL;
> > +	}
> > +
> >  	pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
> >  		 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
> >  		 pp->lazy_line);
> > @@ -1609,7 +1613,7 @@ error:
> >  static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> >  {
> >  	char *buf, *tmp;
> > -	char offs[32] = "", line[32] = "", file[32] = "";
> > +	char offs[32] = "", line[32] = "", file[32] = "", addr[32] = "";
> >  	int ret, len;
> > 
> >  	buf = zalloc(MAX_CMDLEN);
> > @@ -1622,6 +1626,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> >  		if (ret <= 0)
> >  			goto error;
> >  	}
> > +	if (!pp->function) {
> > +		ret = e_snprintf(addr, 32, "0x%lx", pp->offset);
> > +		if (ret <= 0)
> > +			goto error;
> > +	}
> >  	if (pp->line) {
> >  		ret = e_snprintf(line, 32, ":%d", pp->line);
> >  		if (ret <= 0)
> > @@ -1639,9 +1648,11 @@ static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
> >  			goto error;
> >  	}
> > 
> > -	if (pp->function)
> > -		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
> > -				 offs, pp->retprobe ? "%return" : "", line,
> > +	if (pp->function || pp->offset)
> > +		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s",
> > +				 pp->function ? : addr,
> > +				 pp->function ? offs : "",
> > +				 pp->retprobe ? "%return" : "", line,
> >  				 file);
> >  	else
> >  		ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
> > @@ -1786,6 +1797,11 @@ char *synthesize_probe_trace_command(struct probe_trace_event *tev)
> >  	if (tev->uprobes)
> >  		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s:0x%lx",
> >  				 tp->module, tp->address);
> > +	else if (tp->symbol[0] == '0' && tp->symbol[1] == 'x')
> > +		/* Absolute address. See try_to_find_absolute_address() */
> > +		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s0x%lx",
> > +				 tp->module ?: "", tp->module ? ":" : "",
> > +				 tp->address);
> >  	else
> >  		ret = e_snprintf(buf + len, MAX_CMDLEN - len, "%s%s%s+%lu",
> >  				 tp->module ?: "", tp->module ? ":" : "",
> > @@ -2572,6 +2588,87 @@ err_out:
> >  	goto out;
> >  }
> > 
> > +static int try_to_find_absolute_address(struct perf_probe_event *pev,
> > +					struct probe_trace_event **tevs)
> > +{
> > +	struct perf_probe_point *pp = &pev->point;
> > +	struct probe_trace_event *tev;
> > +	struct probe_trace_point *tp;
> > +	int i, err;
> > +
> > +	if (perf_probe_event_need_dwarf(pev) || pev->point.function)
> > +		return -EINVAL;
> > +
> > +	/*
> > +	 * This is 'perf probe /lib/libc.so +0xabcd'. Try to probe at
> > +	 * absolute address.
> > +	 *
> > +	 * Only one tev can be generated by this.
> > +	 */
> > +	*tevs = zalloc(sizeof(*tev));
> > +	if (!*tevs)
> > +		return -ENOMEM;
> > +
> > +	tev = *tevs;
> > +	tp = &tev->point;
> > +
> > +	/*
> > +	 * Don't use tp->offset, use address directly, because
> > +	 * in synthesize_probe_trace_command() address cannot be
> > +	 * zero.
> > +	 */
> > +	tp->address = pev->point.offset;
> > +	tp->retprobe = pp->retprobe;
> > +	tev->uprobes = pev->uprobes;
> > +
> > +	err = -ENOMEM;
> > +	/* Give it a '0x' leading symbol name */
> > +	if (asprintf(&tp->symbol, "0x%lx", tp->address) < 0)
> > +		goto errout;
> > +
> > +	/* For kprobe, check range */
> > +	if ((!tev->uprobes) &&
> > +	    (kprobe_warn_out_range(tev->point.symbol,
> > +				   tev->point.address))) {
> > +		err = -EACCES;
> > +		goto errout;
> > +	}
> > +
> > +	if (asprintf(&tp->realname, "abs_%lx", tp->address) < 0)
> > +		goto errout;
> > +
> > +	if (pev->target) {
> > +		tp->module = strdup(pev->target);
> > +		if (!tp->module)
> > +			goto errout;
> > +	}
> > +
> > +	if (tev->group) {
> > +		tev->group = strdup(pev->group);
> > +		if (!tev->group)
> > +			goto errout;
> > +	}
> > +
> > +	if (pev->event) {
> > +		tev->event = strdup(pev->event);
> > +		if (!tev->event)
> > +			goto errout;
> > +	}
> > +
> > +	tev->nargs = pev->nargs;
> > +	for (i = 0; i < tev->nargs; i++)
> > +		copy_to_probe_trace_arg(&tev->args[i], &pev->args[i]);
> > +
> > +	return 1;
> > +
> > +errout:
> > +	if (*tevs) {
> > +		clear_probe_trace_events(*tevs, 1);
> > +		*tevs = NULL;
> > +	}
> > +	return err;
> > +}
> > +
> >  bool __weak arch__prefers_symtab(void) { return false; }
> > 
> >  static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> > @@ -2588,6 +2685,10 @@ static int convert_to_probe_trace_events(struct perf_probe_event *pev,
> >  		}
> >  	}
> > 
> > +	ret = try_to_find_absolute_address(pev, tevs);
> > +	if (ret > 0)
> > +		return ret;
> > +
> >  	if (arch__prefers_symtab() && !perf_probe_event_need_dwarf(pev)) {
> >  		ret = find_probe_trace_events_from_map(pev, tevs);
> >  		if (ret > 0)
> > @@ -2758,3 +2859,22 @@ end:
> >  	return ret;
> >  }
> > 
> > +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> > +			    struct perf_probe_arg *pvar)
> > +{
> > +	tvar->value = strdup(pvar->var);
> > +	if (tvar->value == NULL)
> > +		return -ENOMEM;
> > +	if (pvar->type) {
> > +		tvar->type = strdup(pvar->type);
> > +		if (tvar->type == NULL)
> > +			return -ENOMEM;
> > +	}
> > +	if (pvar->name) {
> > +		tvar->name = strdup(pvar->name);
> > +		if (tvar->name == NULL)
> > +			return -ENOMEM;
> > +	} else
> > +		tvar->name = NULL;
> > +	return 0;
> > +}
> > diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
> > index 83ee95e9743b..174a3cf6c03d 100644
> > --- a/tools/perf/util/probe-event.h
> > +++ b/tools/perf/util/probe-event.h
> > @@ -156,4 +156,7 @@ int e_snprintf(char *str, size_t size, const char *format, ...)
> >  /* Maximum index number of event-name postfix */
> >  #define MAX_EVENT_INDEX	1024
> > 
> > +int copy_to_probe_trace_arg(struct probe_trace_arg *tvar,
> > +			    struct perf_probe_arg *pvar);
> > +
> >  #endif /*_PROBE_EVENT_H */
> > diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
> > index 7b80f8cb62b9..29c43c0680a8 100644
> > --- a/tools/perf/util/probe-finder.c
> > +++ b/tools/perf/util/probe-finder.c
> > @@ -553,24 +553,9 @@ static int find_variable(Dwarf_Die *sc_die, struct probe_finder *pf)
> >  	char buf[32], *ptr;
> >  	int ret = 0;
> > 
> > -	if (!is_c_varname(pf->pvar->var)) {
> > -		/* Copy raw parameters */
> > -		pf->tvar->value = strdup(pf->pvar->var);
> > -		if (pf->tvar->value == NULL)
> > -			return -ENOMEM;
> > -		if (pf->pvar->type) {
> > -			pf->tvar->type = strdup(pf->pvar->type);
> > -			if (pf->tvar->type == NULL)
> > -				return -ENOMEM;
> > -		}
> > -		if (pf->pvar->name) {
> > -			pf->tvar->name = strdup(pf->pvar->name);
> > -			if (pf->tvar->name == NULL)
> > -				return -ENOMEM;
> > -		} else
> > -			pf->tvar->name = NULL;
> > -		return 0;
> > -	}
> > +	/* Copy raw parameters */
> > +	if (!is_c_varname(pf->pvar->var))
> > +		return copy_to_probe_trace_arg(pf->tvar, pf->pvar);
> > 
> >  	if (pf->pvar->name)
> >  		pf->tvar->name = strdup(pf->pvar->name);
> > --
> > 2.1.0
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213148 — [PATCH 14/16] perf tools: Update Intel PT documentation

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 14/16] perf tools: Update Intel PT documentation
Message-ID<q1p74-3gB-35@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

Update Intel PT documentation to describe new features.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-26-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/Documentation/intel-pt.txt | 194 ++++++++++++++++++++++++++++++++--
 1 file changed, 186 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/intel-pt.txt b/tools/perf/Documentation/intel-pt.txt
index 2866b62eb293..4a0501d7a3b4 100644
--- a/tools/perf/Documentation/intel-pt.txt
+++ b/tools/perf/Documentation/intel-pt.txt
@@ -142,19 +142,21 @@ which is the same as
 
 	-e intel_pt/tsc=1,noretcomp=0/
 
+Note there are now new config terms - see section 'config terms' further below.
+
 The config terms are listed in /sys/devices/intel_pt/format.  They are bit
 fields within the config member of the struct perf_event_attr which is
 passed to the kernel by the perf_event_open system call.  They correspond to bit
 fields in the IA32_RTIT_CTL MSR.  Here is a list of them and their definitions:
 
-	$ for f in `ls /sys/devices/intel_pt/format`;do
-	> echo $f
-	> cat /sys/devices/intel_pt/format/$f
-	> done
-	noretcomp
-	config:11
-	tsc
-	config:10
+	$ grep -H . /sys/bus/event_source/devices/intel_pt/format/*
+	/sys/bus/event_source/devices/intel_pt/format/cyc:config:1
+	/sys/bus/event_source/devices/intel_pt/format/cyc_thresh:config:19-22
+	/sys/bus/event_source/devices/intel_pt/format/mtc:config:9
+	/sys/bus/event_source/devices/intel_pt/format/mtc_period:config:14-17
+	/sys/bus/event_source/devices/intel_pt/format/noretcomp:config:11
+	/sys/bus/event_source/devices/intel_pt/format/psb_period:config:24-27
+	/sys/bus/event_source/devices/intel_pt/format/tsc:config:10
 
 Note that the default config must be overridden for each term i.e.
 
@@ -209,9 +211,185 @@ perf_event_attr is displayed if the -vv option is used e.g.
 	------------------------------------------------------------
 
 
+config terms
+------------
+
+The June 2015 version of Intel 64 and IA-32 Architectures Software Developer
+Manuals, Chapter 36 Intel Processor Trace, defined new Intel PT features.
+Some of the features are reflect in new config terms.  All the config terms are
+described below.
+
+tsc		Always supported.  Produces TSC timestamp packets to provide
+		timing information.  In some cases it is possible to decode
+		without timing information, for example a per-thread context
+		that does not overlap executable memory maps.
+
+		The default config selects tsc (i.e. tsc=1).
+
+noretcomp	Always supported.  Disables "return compression" so a TIP packet
+		is produced when a function returns.  Causes more packets to be
+		produced but might make decoding more reliable.
+
+		The default config does not select noretcomp (i.e. noretcomp=0).
+
+psb_period	Allows the frequency of PSB packets to be specified.
+
+		The PSB packet is a synchronization packet that provides a
+		starting point for decoding or recovery from errors.
+
+		Support for psb_period is indicated by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
+
+		which contains "1" if the feature is supported and "0"
+		otherwise.
+
+		Valid values are given by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/psb_periods
+
+		which contains a hexadecimal value, the bits of which represent
+		valid values e.g. bit 2 set means value 2 is valid.
+
+		The psb_period value is converted to the approximate number of
+		trace bytes between PSB packets as:
+
+			2 ^ (value + 11)
+
+		e.g. value 3 means 16KiB bytes between PSBs
+
+		If an invalid value is entered, the error message
+		will give a list of valid values e.g.
+
+			$ perf record -e intel_pt/psb_period=15/u uname
+			Invalid psb_period for intel_pt. Valid values are: 0-5
+
+		If MTC packets are selected, the default config selects a value
+		of 3 (i.e. psb_period=3) or the nearest lower value that is
+		supported (0 is always supported).  Otherwise the default is 0.
+
+		If decoding is expected to be reliable and the buffer is large
+		then a large PSB period can be used.
+
+		Because a TSC packet is produced with PSB, the PSB period can
+		also affect the granularity to timing information in the absence
+		of MTC or CYC.
+
+mtc		Produces MTC timing packets.
+
+		MTC packets provide finer grain timestamp information than TSC
+		packets.  MTC packets record time using the hardware crystal
+		clock (CTC) which is related to TSC packets using a TMA packet.
+
+		Support for this feature is indicated by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/mtc
+
+		which contains "1" if the feature is supported and
+		"0" otherwise.
+
+		The frequency of MTC packets can also be specified - see
+		mtc_period below.
+
+mtc_period	Specifies how frequently MTC packets are produced - see mtc
+		above for how to determine if MTC packets are supported.
+
+		Valid values are given by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/mtc_periods
+
+		which contains a hexadecimal value, the bits of which represent
+		valid values e.g. bit 2 set means value 2 is valid.
+
+		The mtc_period value is converted to the MTC frequency as:
+
+			CTC-frequency / (2 ^ value)
+
+		e.g. value 3 means one eighth of CTC-frequency
+
+		Where CTC is the hardware crystal clock, the frequency of which
+		can be related to TSC via values provided in cpuid leaf 0x15.
+
+		If an invalid value is entered, the error message
+		will give a list of valid values e.g.
+
+			$ perf record -e intel_pt/mtc_period=15/u uname
+			Invalid mtc_period for intel_pt. Valid values are: 0,3,6,9
+
+		The default value is 3 or the nearest lower value
+		that is supported (0 is always supported).
+
+cyc		Produces CYC timing packets.
+
+		CYC packets provide even finer grain timestamp information than
+		MTC and TSC packets.  A CYC packet contains the number of CPU
+		cycles since the last CYC packet. Unlike MTC and TSC packets,
+		CYC packets are only sent when another packet is also sent.
+
+		Support for this feature is indicated by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/psb_cyc
+
+		which contains "1" if the feature is supported and
+		"0" otherwise.
+
+		The number of CYC packets produced can be reduced by specifying
+		a threshold - see cyc_thresh below.
+
+cyc_thresh	Specifies how frequently CYC packets are produced - see cyc
+		above for how to determine if CYC packets are supported.
+
+		Valid cyc_thresh values are given by:
+
+			/sys/bus/event_source/devices/intel_pt/caps/cycle_thresholds
+
+		which contains a hexadecimal value, the bits of which represent
+		valid values e.g. bit 2 set means value 2 is valid.
+
+		The cyc_thresh value represents the minimum number of CPU cycles
+		that must have passed before a CYC packet can be sent.  The
+		number of CPU cycles is:
+
+			2 ^ (value - 1)
+
+		e.g. value 4 means 8 CPU cycles must pass before a CYC packet
+		can be sent.  Note a CYC packet is still only sent when another
+		packet is sent, not at, e.g. every 8 CPU cycles.
+
+		If an invalid value is entered, the error message
+		will give a list of valid values e.g.
+
+			$ perf record -e intel_pt/cyc,cyc_thresh=15/u uname
+			Invalid cyc_thresh for intel_pt. Valid values are: 0-12
+
+		CYC packets are not requested by default.
+
+no_force_psb	This is a driver option and is not in the IA32_RTIT_CTL MSR.
+
+		It stops the driver resetting the byte count to zero whenever
+		enabling the trace (for example on context switches) which in
+		turn results in no PSB being forced.  However some processors
+		will produce a PSB anyway.
+
+		In any case, there is still a PSB when the trace is enabled for
+		the first time.
+
+		no_force_psb can be used to slightly decrease the trace size but
+		may make it harder for the decoder to recover from errors.
+
+		no_force_psb is not selected by default.
+
+
 new snapshot option
 -------------------
 
+The difference between full trace and snapshot from the kernel's perspective is
+that in full trace we don't overwrite trace data that the user hasn't collected
+yet (and indicated that by advancing aux_tail), whereas in snapshot mode we let
+the trace run and overwrite older data in the buffer so that whenever something
+interesting happens, we can stop it and grab a snapshot of what was going on
+around that interesting moment.
+
 To select snapshot mode a new option has been added:
 
 	-S
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213149 — [PATCH 12/16] perf tools: Add Intel PT support for using CYC packets

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 12/16] perf tools: Add Intel PT support for using CYC packets
Message-ID<q1p74-3gB-37@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

CYC packets are a new Intel PT feature.

CYC packets provide even finer grain timestamp information than MTC and
TSC packets.  A CYC packet contains the number of CPU cycles since the
last CYC packet. Unlike MTC and TSC packets, CYC packets are only sent
when another packet is also sent.

Support for this feature is indicated by:

/sys/bus/event_source/devices/intel_pt/caps/psb_cyc

which contains "1" if the feature is supported and "0" otherwise.

CYC packets can be requested using a PMU config term e.g. perf record -e
intel_pt/cyc/u sleep 1

The frequency of CYC packets can also be specified.  e.g. perf record -e
intel_pt/cyc,cyc_thresh=2/u sleep 1

CYC packets are not requested by default.

Valid cyc_thresh values are given by:

/sys/bus/event_source/devices/intel_pt/caps/cycle_thresholds

which contains a hexadecimal value, the bits of which represent valid
values e.g. bit 2 set means value 2 is valid.

The value represents the minimum number of CPU cycles that must have
passed before a CYC packet can be sent.  The number of CPU cycles is:

    2 ^ (value - 1)

e.g. value 4 means 8 CPU cycles must pass before a CYC packet can be
sent.  Note a CYC packet is still only sent when another packet is sent,
not at, e.g. every 8 CPU cycles.

If an invalid value is entered, the error message will give a list of
valid values e.g.

    $ perf record -e intel_pt/cyc,cyc_thresh=15/u uname
    Invalid cyc_thresh for intel_pt. Valid values are: 0-12

tools/perf/Documentation/intel-pt.txt is updated in a later patch as
there are a number of new features being added.

For more information refer to the June 2015 or later Intel 64 and IA-32
Architectures SDM Chapter 36 Intel Processor Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-24-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/intel-pt.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index a5de01dad868..2ca10d796c0b 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -475,6 +475,12 @@ static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu,
 	if (!evsel)
 		return 0;
 
+	err = intel_pt_val_config_term(intel_pt_pmu, "caps/cycle_thresholds",
+				       "cyc_thresh", "caps/psb_cyc",
+				       evsel->attr.config);
+	if (err)
+		return err;
+
 	err = intel_pt_val_config_term(intel_pt_pmu, "caps/mtc_periods",
 				       "mtc_period", "caps/mtc",
 				       evsel->attr.config);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213150 — [PATCH 09/16] perf tools: Add Intel PT support for decoding MTC packets

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 09/16] perf tools: Add Intel PT support for decoding MTC packets
Message-ID<q1p75-3gB-41@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

MTC packets provide finer grain timestamp information than TSC packets.
MTC packets record time using the hardware crystal clock (CTC) which is
related to TSC packets using a TMA packet.

This patch just adds decoder support.

Support for a default value and validation of values is provided by a
later patch. Also documentation is updated in a separate patch.

For details refer to the June 2015 or later Intel 64 and IA-32
Architectures SDM Chapter 36 Intel Processor Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-21-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 162 ++++++++++++++++++++-
 .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |   1 +
 2 files changed, 159 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 4a0e9fb1d173..f7119a11a4b6 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -85,7 +85,9 @@ struct intel_pt_decoder {
 	const unsigned char *buf;
 	size_t len;
 	bool return_compression;
+	bool mtc_insn;
 	bool pge;
+	bool have_tma;
 	uint64_t pos;
 	uint64_t last_ip;
 	uint64_t ip;
@@ -94,6 +96,15 @@ struct intel_pt_decoder {
 	uint64_t tsc_timestamp;
 	uint64_t ref_timestamp;
 	uint64_t ret_addr;
+	uint64_t ctc_timestamp;
+	uint64_t ctc_delta;
+	uint32_t last_mtc;
+	uint32_t tsc_ctc_ratio_n;
+	uint32_t tsc_ctc_ratio_d;
+	uint32_t tsc_ctc_mult;
+	uint32_t tsc_slip;
+	uint32_t ctc_rem_mask;
+	int mtc_shift;
 	struct intel_pt_stack stack;
 	enum intel_pt_pkt_state pkt_state;
 	struct intel_pt_pkt packet;
@@ -149,6 +160,13 @@ static void intel_pt_setup_period(struct intel_pt_decoder *decoder)
 	}
 }
 
+static uint64_t multdiv(uint64_t t, uint32_t n, uint32_t d)
+{
+	if (!d)
+		return 0;
+	return (t / d) * n + ((t % d) * n) / d;
+}
+
 struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
 {
 	struct intel_pt_decoder *decoder;
@@ -175,6 +193,39 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
 
 	intel_pt_setup_period(decoder);
 
+	decoder->mtc_shift = params->mtc_period;
+	decoder->ctc_rem_mask = (1 << decoder->mtc_shift) - 1;
+
+	decoder->tsc_ctc_ratio_n = params->tsc_ctc_ratio_n;
+	decoder->tsc_ctc_ratio_d = params->tsc_ctc_ratio_d;
+
+	if (!decoder->tsc_ctc_ratio_n)
+		decoder->tsc_ctc_ratio_d = 0;
+
+	if (decoder->tsc_ctc_ratio_d) {
+		if (!(decoder->tsc_ctc_ratio_n % decoder->tsc_ctc_ratio_d))
+			decoder->tsc_ctc_mult = decoder->tsc_ctc_ratio_n /
+						decoder->tsc_ctc_ratio_d;
+
+		/*
+		 * Allow for timestamps appearing to backwards because a TSC
+		 * packet has slipped past a MTC packet, so allow 2 MTC ticks
+		 * or ...
+		 */
+		decoder->tsc_slip = multdiv(2 << decoder->mtc_shift,
+					decoder->tsc_ctc_ratio_n,
+					decoder->tsc_ctc_ratio_d);
+	}
+	/* ... or 0x100 paranoia */
+	if (decoder->tsc_slip < 0x100)
+		decoder->tsc_slip = 0x100;
+
+	intel_pt_log("timestamp: mtc_shift %u\n", decoder->mtc_shift);
+	intel_pt_log("timestamp: tsc_ctc_ratio_n %u\n", decoder->tsc_ctc_ratio_n);
+	intel_pt_log("timestamp: tsc_ctc_ratio_d %u\n", decoder->tsc_ctc_ratio_d);
+	intel_pt_log("timestamp: tsc_ctc_mult %u\n", decoder->tsc_ctc_mult);
+	intel_pt_log("timestamp: tsc_slip %#x\n", decoder->tsc_slip);
+
 	return decoder;
 }
 
@@ -368,6 +419,7 @@ static inline void intel_pt_update_in_tx(struct intel_pt_decoder *decoder)
 static int intel_pt_bad_packet(struct intel_pt_decoder *decoder)
 {
 	intel_pt_clear_tx_flags(decoder);
+	decoder->have_tma = false;
 	decoder->pkt_len = 1;
 	decoder->pkt_step = 1;
 	intel_pt_decoder_log_packet(decoder);
@@ -400,6 +452,7 @@ static int intel_pt_get_data(struct intel_pt_decoder *decoder)
 		decoder->pkt_state = INTEL_PT_STATE_NO_PSB;
 		decoder->ref_timestamp = buffer.ref_timestamp;
 		decoder->timestamp = 0;
+		decoder->have_tma = false;
 		decoder->state.trace_nr = buffer.trace_nr;
 		intel_pt_log("Reference timestamp 0x%" PRIx64 "\n",
 			     decoder->ref_timestamp);
@@ -523,6 +576,7 @@ static uint64_t intel_pt_next_sample(struct intel_pt_decoder *decoder)
 	case INTEL_PT_PERIOD_TICKS:
 		return intel_pt_next_period(decoder);
 	case INTEL_PT_PERIOD_NONE:
+	case INTEL_PT_PERIOD_MTC:
 	default:
 		return 0;
 	}
@@ -542,6 +596,7 @@ static void intel_pt_sample_insn(struct intel_pt_decoder *decoder)
 		decoder->last_masked_timestamp = masked_timestamp;
 		break;
 	case INTEL_PT_PERIOD_NONE:
+	case INTEL_PT_PERIOD_MTC:
 	default:
 		break;
 	}
@@ -555,6 +610,9 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
 	uint64_t max_insn_cnt, insn_cnt = 0;
 	int err;
 
+	if (!decoder->mtc_insn)
+		decoder->mtc_insn = true;
+
 	max_insn_cnt = intel_pt_next_sample(decoder);
 
 	err = decoder->walk_insn(intel_pt_insn, &insn_cnt, &decoder->ip, ip,
@@ -861,6 +919,8 @@ static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
 {
 	uint64_t timestamp;
 
+	decoder->have_tma = false;
+
 	if (decoder->ref_timestamp) {
 		timestamp = decoder->packet.payload |
 			    (decoder->ref_timestamp & (0xffULL << 56));
@@ -878,17 +938,18 @@ static void intel_pt_calc_tsc_timestamp(struct intel_pt_decoder *decoder)
 	} else if (decoder->timestamp) {
 		timestamp = decoder->packet.payload |
 			    (decoder->timestamp & (0xffULL << 56));
+		decoder->tsc_timestamp = timestamp;
 		if (timestamp < decoder->timestamp &&
-		    decoder->timestamp - timestamp < 0x100) {
-			intel_pt_log_to("ERROR: Suppressing backwards timestamp",
+		    decoder->timestamp - timestamp < decoder->tsc_slip) {
+			intel_pt_log_to("Suppressing backwards timestamp",
 					timestamp);
 			timestamp = decoder->timestamp;
 		}
 		while (timestamp < decoder->timestamp) {
 			intel_pt_log_to("Wraparound timestamp", timestamp);
 			timestamp += (1ULL << 56);
+			decoder->tsc_timestamp = timestamp;
 		}
-		decoder->tsc_timestamp = timestamp;
 		decoder->timestamp = timestamp;
 		decoder->timestamp_insn_cnt = 0;
 	}
@@ -900,11 +961,73 @@ static int intel_pt_overflow(struct intel_pt_decoder *decoder)
 {
 	intel_pt_log("ERROR: Buffer overflow\n");
 	intel_pt_clear_tx_flags(decoder);
+	decoder->have_tma = false;
 	decoder->pkt_state = INTEL_PT_STATE_ERR_RESYNC;
 	decoder->overflow = true;
 	return -EOVERFLOW;
 }
 
+static void intel_pt_calc_tma(struct intel_pt_decoder *decoder)
+{
+	uint32_t ctc = decoder->packet.payload;
+	uint32_t fc = decoder->packet.count;
+	uint32_t ctc_rem = ctc & decoder->ctc_rem_mask;
+
+	if (!decoder->tsc_ctc_ratio_d)
+		return;
+
+	decoder->last_mtc = (ctc >> decoder->mtc_shift) & 0xff;
+	decoder->ctc_timestamp = decoder->tsc_timestamp - fc;
+	if (decoder->tsc_ctc_mult) {
+		decoder->ctc_timestamp -= ctc_rem * decoder->tsc_ctc_mult;
+	} else {
+		decoder->ctc_timestamp -= multdiv(ctc_rem,
+						  decoder->tsc_ctc_ratio_n,
+						  decoder->tsc_ctc_ratio_d);
+	}
+	decoder->ctc_delta = 0;
+	decoder->have_tma = true;
+	intel_pt_log("CTC timestamp " x64_fmt " last MTC %#x  CTC rem %#x\n",
+		     decoder->ctc_timestamp, decoder->last_mtc, ctc_rem);
+}
+
+static void intel_pt_calc_mtc_timestamp(struct intel_pt_decoder *decoder)
+{
+	uint64_t timestamp;
+	uint32_t mtc, mtc_delta;
+
+	if (!decoder->have_tma)
+		return;
+
+	mtc = decoder->packet.payload;
+
+	if (mtc > decoder->last_mtc)
+		mtc_delta = mtc - decoder->last_mtc;
+	else
+		mtc_delta = mtc + 256 - decoder->last_mtc;
+
+	decoder->ctc_delta += mtc_delta << decoder->mtc_shift;
+
+	if (decoder->tsc_ctc_mult) {
+		timestamp = decoder->ctc_timestamp +
+			    decoder->ctc_delta * decoder->tsc_ctc_mult;
+	} else {
+		timestamp = decoder->ctc_timestamp +
+			    multdiv(decoder->ctc_delta,
+				    decoder->tsc_ctc_ratio_n,
+				    decoder->tsc_ctc_ratio_d);
+	}
+
+	if (timestamp < decoder->timestamp)
+		intel_pt_log("Suppressing MTC timestamp " x64_fmt " less than current timestamp " x64_fmt "\n",
+			     timestamp, decoder->timestamp);
+	else
+		decoder->timestamp = timestamp;
+
+	decoder->timestamp_insn_cnt = 0;
+	decoder->last_mtc = mtc;
+}
+
 /* Walk PSB+ packets when already in sync. */
 static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 {
@@ -926,6 +1049,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 		case INTEL_PT_TRACESTOP:
 		case INTEL_PT_BAD:
 		case INTEL_PT_PSB:
+			decoder->have_tma = false;
 			intel_pt_log("ERROR: Unexpected packet\n");
 			return -EAGAIN;
 
@@ -937,6 +1061,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_TMA:
+			intel_pt_calc_tma(decoder);
 			break;
 
 		case INTEL_PT_CBR:
@@ -961,6 +1086,9 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_MTC:
+			intel_pt_calc_mtc_timestamp(decoder);
+			if (decoder->period_type == INTEL_PT_PERIOD_MTC)
+				decoder->state.type |= INTEL_PT_INSTRUCTION;
 			break;
 
 		case INTEL_PT_CYC:
@@ -1048,6 +1176,9 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_MTC:
+			intel_pt_calc_mtc_timestamp(decoder);
+			if (decoder->period_type == INTEL_PT_PERIOD_MTC)
+				decoder->state.type |= INTEL_PT_INSTRUCTION;
 			break;
 
 		case INTEL_PT_CYC:
@@ -1159,13 +1290,31 @@ next:
 			break;
 
 		case INTEL_PT_MTC:
-			break;
+			intel_pt_calc_mtc_timestamp(decoder);
+			if (decoder->period_type != INTEL_PT_PERIOD_MTC)
+				break;
+			/*
+			 * Ensure that there has been an instruction since the
+			 * last MTC.
+			 */
+			if (!decoder->mtc_insn)
+				break;
+			decoder->mtc_insn = false;
+			/* Ensure that there is a timestamp */
+			if (!decoder->timestamp)
+				break;
+			decoder->state.type = INTEL_PT_INSTRUCTION;
+			decoder->state.from_ip = decoder->ip;
+			decoder->state.to_ip = 0;
+			decoder->mtc_insn = false;
+			return 0;
 
 		case INTEL_PT_TSC:
 			intel_pt_calc_tsc_timestamp(decoder);
 			break;
 
 		case INTEL_PT_TMA:
+			intel_pt_calc_tma(decoder);
 			break;
 
 		case INTEL_PT_CYC:
@@ -1237,6 +1386,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_MTC:
+			intel_pt_calc_mtc_timestamp(decoder);
 			break;
 
 		case INTEL_PT_TSC:
@@ -1244,6 +1394,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_TMA:
+			intel_pt_calc_tma(decoder);
 			break;
 
 		case INTEL_PT_CYC:
@@ -1267,6 +1418,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 
 		case INTEL_PT_TRACESTOP:
 		case INTEL_PT_TNT:
+			decoder->have_tma = false;
 			intel_pt_log("ERROR: Unexpected packet\n");
 			if (decoder->ip)
 				decoder->pkt_state = INTEL_PT_STATE_ERR4;
@@ -1329,6 +1481,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_MTC:
+			intel_pt_calc_mtc_timestamp(decoder);
 			break;
 
 		case INTEL_PT_TSC:
@@ -1336,6 +1489,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_TMA:
+			intel_pt_calc_tma(decoder);
 			break;
 
 		case INTEL_PT_CYC:
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
index 56cc47baca11..02c38fec1c37 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -36,6 +36,7 @@ enum intel_pt_period_type {
 	INTEL_PT_PERIOD_NONE,
 	INTEL_PT_PERIOD_INSTRUCTIONS,
 	INTEL_PT_PERIOD_TICKS,
+	INTEL_PT_PERIOD_MTC,
 };
 
 enum {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213151 — [PATCH 07/16] perf tools: Add new Intel PT packet definitions

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 07/16] perf tools: Add new Intel PT packet definitions
Message-ID<q1p75-3gB-39@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

New features have been added to Intel PT which include a number of new
packet definitions.

This patch adds packet definitions for new packets: TMA, MTC, CYC, VMCS,
TRACESTOP and MNT.  Also another bit in PIP is defined.

This patch only adds support for the definitions. Later patches add
support for decoding TMA, MTC, CYC and TRACESTOP which is where those
packets are explained.

VMCS and the newly defined bit in PIP are used with virtualization which
is not supported yet.  MNT is a maintenance packet which the decoder
should ignore.

For details, refer to the June 2015 or later Intel 64 and IA-32
Architectures SDM Chapter 36 Intel Processor Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-19-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 .../perf/util/intel-pt-decoder/intel-pt-decoder.c  |  70 +++++++++-
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   | 142 +++++++++++++++++++--
 .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   6 +
 3 files changed, 201 insertions(+), 17 deletions(-)

diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
index 56790ea1e88e..4a0e9fb1d173 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -923,6 +923,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 		case INTEL_PT_TIP_PGE:
 		case INTEL_PT_TIP:
 		case INTEL_PT_TNT:
+		case INTEL_PT_TRACESTOP:
 		case INTEL_PT_BAD:
 		case INTEL_PT_PSB:
 			intel_pt_log("ERROR: Unexpected packet\n");
@@ -935,6 +936,9 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 			intel_pt_calc_tsc_timestamp(decoder);
 			break;
 
+		case INTEL_PT_TMA:
+			break;
+
 		case INTEL_PT_CBR:
 			decoder->cbr = decoder->packet.payload;
 			break;
@@ -944,7 +948,7 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 			break;
 
 		case INTEL_PT_PIP:
-			decoder->cr3 = decoder->packet.payload;
+			decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
 			break;
 
 		case INTEL_PT_FUP:
@@ -956,6 +960,12 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
 			intel_pt_update_in_tx(decoder);
 			break;
 
+		case INTEL_PT_MTC:
+			break;
+
+		case INTEL_PT_CYC:
+		case INTEL_PT_VMCS:
+		case INTEL_PT_MNT:
 		case INTEL_PT_PAD:
 		default:
 			break;
@@ -983,8 +993,10 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
 		switch (decoder->packet.type) {
 		case INTEL_PT_TNT:
 		case INTEL_PT_FUP:
+		case INTEL_PT_TRACESTOP:
 		case INTEL_PT_PSB:
 		case INTEL_PT_TSC:
+		case INTEL_PT_TMA:
 		case INTEL_PT_CBR:
 		case INTEL_PT_MODE_TSX:
 		case INTEL_PT_BAD:
@@ -1032,13 +1044,21 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
 			return 0;
 
 		case INTEL_PT_PIP:
-			decoder->cr3 = decoder->packet.payload;
+			decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
+			break;
+
+		case INTEL_PT_MTC:
+			break;
+
+		case INTEL_PT_CYC:
 			break;
 
 		case INTEL_PT_MODE_EXEC:
 			decoder->exec_mode = decoder->packet.payload;
 			break;
 
+		case INTEL_PT_VMCS:
+		case INTEL_PT_MNT:
 		case INTEL_PT_PAD:
 			break;
 
@@ -1122,6 +1142,9 @@ next:
 			}
 			return intel_pt_walk_fup_tip(decoder);
 
+		case INTEL_PT_TRACESTOP:
+			break;
+
 		case INTEL_PT_PSB:
 			intel_pt_clear_stack(&decoder->stack);
 			err = intel_pt_walk_psbend(decoder);
@@ -1132,13 +1155,22 @@ next:
 			break;
 
 		case INTEL_PT_PIP:
-			decoder->cr3 = decoder->packet.payload;
+			decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
+			break;
+
+		case INTEL_PT_MTC:
 			break;
 
 		case INTEL_PT_TSC:
 			intel_pt_calc_tsc_timestamp(decoder);
 			break;
 
+		case INTEL_PT_TMA:
+			break;
+
+		case INTEL_PT_CYC:
+			break;
+
 		case INTEL_PT_CBR:
 			decoder->cbr = decoder->packet.payload;
 			break;
@@ -1162,6 +1194,8 @@ next:
 			return intel_pt_bug(decoder);
 
 		case INTEL_PT_PSBEND:
+		case INTEL_PT_VMCS:
+		case INTEL_PT_MNT:
 		case INTEL_PT_PAD:
 			break;
 
@@ -1202,16 +1236,25 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 			}
 			break;
 
+		case INTEL_PT_MTC:
+			break;
+
 		case INTEL_PT_TSC:
 			intel_pt_calc_tsc_timestamp(decoder);
 			break;
 
+		case INTEL_PT_TMA:
+			break;
+
+		case INTEL_PT_CYC:
+			break;
+
 		case INTEL_PT_CBR:
 			decoder->cbr = decoder->packet.payload;
 			break;
 
 		case INTEL_PT_PIP:
-			decoder->cr3 = decoder->packet.payload;
+			decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
 			break;
 
 		case INTEL_PT_MODE_EXEC:
@@ -1222,6 +1265,7 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 			intel_pt_update_in_tx(decoder);
 			break;
 
+		case INTEL_PT_TRACESTOP:
 		case INTEL_PT_TNT:
 			intel_pt_log("ERROR: Unexpected packet\n");
 			if (decoder->ip)
@@ -1240,6 +1284,8 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
 			return 0;
 
 		case INTEL_PT_PSB:
+		case INTEL_PT_VMCS:
+		case INTEL_PT_MNT:
 		case INTEL_PT_PAD:
 		default:
 			break;
@@ -1282,16 +1328,25 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
 				intel_pt_set_last_ip(decoder);
 			break;
 
+		case INTEL_PT_MTC:
+			break;
+
 		case INTEL_PT_TSC:
 			intel_pt_calc_tsc_timestamp(decoder);
 			break;
 
+		case INTEL_PT_TMA:
+			break;
+
+		case INTEL_PT_CYC:
+			break;
+
 		case INTEL_PT_CBR:
 			decoder->cbr = decoder->packet.payload;
 			break;
 
 		case INTEL_PT_PIP:
-			decoder->cr3 = decoder->packet.payload;
+			decoder->cr3 = decoder->packet.payload & (BIT63 - 1);
 			break;
 
 		case INTEL_PT_MODE_EXEC:
@@ -1308,6 +1363,9 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
 		case INTEL_PT_BAD: /* Does not happen */
 			return intel_pt_bug(decoder);
 
+		case INTEL_PT_TRACESTOP:
+			break;
+
 		case INTEL_PT_PSB:
 			err = intel_pt_walk_psb(decoder);
 			if (err)
@@ -1321,6 +1379,8 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
 
 		case INTEL_PT_TNT:
 		case INTEL_PT_PSBEND:
+		case INTEL_PT_VMCS:
+		case INTEL_PT_MNT:
 		case INTEL_PT_PAD:
 		default:
 			break;
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
index 988c82c6652d..b1257c816310 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
@@ -24,6 +24,8 @@
 
 #define BIT63		((uint64_t)1 << 63)
 
+#define NR_FLAG		BIT63
+
 #if __BYTE_ORDER == __BIG_ENDIAN
 #define le16_to_cpu bswap_16
 #define le32_to_cpu bswap_32
@@ -46,15 +48,21 @@ static const char * const packet_name[] = {
 	[INTEL_PT_TIP_PGD]	= "TIP.PGD",
 	[INTEL_PT_TIP_PGE]	= "TIP.PGE",
 	[INTEL_PT_TSC]		= "TSC",
+	[INTEL_PT_TMA]		= "TMA",
 	[INTEL_PT_MODE_EXEC]	= "MODE.Exec",
 	[INTEL_PT_MODE_TSX]	= "MODE.TSX",
+	[INTEL_PT_MTC]		= "MTC",
 	[INTEL_PT_TIP]		= "TIP",
 	[INTEL_PT_FUP]		= "FUP",
+	[INTEL_PT_CYC]		= "CYC",
+	[INTEL_PT_VMCS]		= "VMCS",
 	[INTEL_PT_PSB]		= "PSB",
 	[INTEL_PT_PSBEND]	= "PSBEND",
 	[INTEL_PT_CBR]		= "CBR",
+	[INTEL_PT_TRACESTOP]	= "TraceSTOP",
 	[INTEL_PT_PIP]		= "PIP",
 	[INTEL_PT_OVF]		= "OVF",
+	[INTEL_PT_MNT]		= "MNT",
 };
 
 const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
@@ -96,10 +104,18 @@ static int intel_pt_get_pip(const unsigned char *buf, size_t len,
 	packet->type = INTEL_PT_PIP;
 	memcpy_le64(&payload, buf + 2, 6);
 	packet->payload = payload >> 1;
+	if (payload & 1)
+		packet->payload |= NR_FLAG;
 
 	return 8;
 }
 
+static int intel_pt_get_tracestop(struct intel_pt_pkt *packet)
+{
+	packet->type = INTEL_PT_TRACESTOP;
+	return 2;
+}
+
 static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
 			    struct intel_pt_pkt *packet)
 {
@@ -110,6 +126,24 @@ static int intel_pt_get_cbr(const unsigned char *buf, size_t len,
 	return 4;
 }
 
+static int intel_pt_get_vmcs(const unsigned char *buf, size_t len,
+			     struct intel_pt_pkt *packet)
+{
+	unsigned int count = (52 - 5) >> 3;
+
+	if (count < 1 || count > 7)
+		return INTEL_PT_BAD_PACKET;
+
+	if (len < count + 2)
+		return INTEL_PT_NEED_MORE_BYTES;
+
+	packet->type = INTEL_PT_VMCS;
+	packet->count = count;
+	memcpy_le64(&packet->payload, buf + 2, count);
+
+	return count + 2;
+}
+
 static int intel_pt_get_ovf(struct intel_pt_pkt *packet)
 {
 	packet->type = INTEL_PT_OVF;
@@ -139,12 +173,49 @@ static int intel_pt_get_psbend(struct intel_pt_pkt *packet)
 	return 2;
 }
 
+static int intel_pt_get_tma(const unsigned char *buf, size_t len,
+			    struct intel_pt_pkt *packet)
+{
+	if (len < 7)
+		return INTEL_PT_NEED_MORE_BYTES;
+
+	packet->type = INTEL_PT_TMA;
+	packet->payload = buf[2] | (buf[3] << 8);
+	packet->count = buf[5] | ((buf[6] & BIT(0)) << 8);
+	return 7;
+}
+
 static int intel_pt_get_pad(struct intel_pt_pkt *packet)
 {
 	packet->type = INTEL_PT_PAD;
 	return 1;
 }
 
+static int intel_pt_get_mnt(const unsigned char *buf, size_t len,
+			    struct intel_pt_pkt *packet)
+{
+	if (len < 11)
+		return INTEL_PT_NEED_MORE_BYTES;
+	packet->type = INTEL_PT_MNT;
+	memcpy_le64(&packet->payload, buf + 3, 8);
+	return 11
+;
+}
+
+static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
+			      struct intel_pt_pkt *packet)
+{
+	if (len < 3)
+		return INTEL_PT_NEED_MORE_BYTES;
+
+	switch (buf[2]) {
+	case 0x88: /* MNT */
+		return intel_pt_get_mnt(buf, len, packet);
+	default:
+		return INTEL_PT_BAD_PACKET;
+	}
+}
+
 static int intel_pt_get_ext(const unsigned char *buf, size_t len,
 			    struct intel_pt_pkt *packet)
 {
@@ -156,14 +227,22 @@ static int intel_pt_get_ext(const unsigned char *buf, size_t len,
 		return intel_pt_get_long_tnt(buf, len, packet);
 	case 0x43: /* PIP */
 		return intel_pt_get_pip(buf, len, packet);
+	case 0x83: /* TraceStop */
+		return intel_pt_get_tracestop(packet);
 	case 0x03: /* CBR */
 		return intel_pt_get_cbr(buf, len, packet);
+	case 0xc8: /* VMCS */
+		return intel_pt_get_vmcs(buf, len, packet);
 	case 0xf3: /* OVF */
 		return intel_pt_get_ovf(packet);
 	case 0x82: /* PSB */
 		return intel_pt_get_psb(buf, len, packet);
 	case 0x23: /* PSBEND */
 		return intel_pt_get_psbend(packet);
+	case 0x73: /* TMA */
+		return intel_pt_get_tma(buf, len, packet);
+	case 0xC3: /* 3-byte header */
+		return intel_pt_get_3byte(buf, len, packet);
 	default:
 		return INTEL_PT_BAD_PACKET;
 	}
@@ -187,6 +266,28 @@ static int intel_pt_get_short_tnt(unsigned int byte,
 	return 1;
 }
 
+static int intel_pt_get_cyc(unsigned int byte, const unsigned char *buf,
+			    size_t len, struct intel_pt_pkt *packet)
+{
+	unsigned int offs = 1, shift;
+	uint64_t payload = byte >> 3;
+
+	byte >>= 2;
+	len -= 1;
+	for (shift = 5; byte & 1; shift += 7) {
+		if (offs > 9)
+			return INTEL_PT_BAD_PACKET;
+		if (len < offs)
+			return INTEL_PT_NEED_MORE_BYTES;
+		byte = buf[offs++];
+		payload |= (byte >> 1) << shift;
+	}
+
+	packet->type = INTEL_PT_CYC;
+	packet->payload = payload;
+	return offs;
+}
+
 static int intel_pt_get_ip(enum intel_pt_pkt_type type, unsigned int byte,
 			   const unsigned char *buf, size_t len,
 			   struct intel_pt_pkt *packet)
@@ -269,6 +370,16 @@ static int intel_pt_get_tsc(const unsigned char *buf, size_t len,
 	return 8;
 }
 
+static int intel_pt_get_mtc(const unsigned char *buf, size_t len,
+			    struct intel_pt_pkt *packet)
+{
+	if (len < 2)
+		return INTEL_PT_NEED_MORE_BYTES;
+	packet->type = INTEL_PT_MTC;
+	packet->payload = buf[1];
+	return 2;
+}
+
 static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
 				  struct intel_pt_pkt *packet)
 {
@@ -288,6 +399,9 @@ static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
 		return intel_pt_get_short_tnt(byte, packet);
 	}
 
+	if ((byte & 2))
+		return intel_pt_get_cyc(byte, buf, len, packet);
+
 	switch (byte & 0x1f) {
 	case 0x0D:
 		return intel_pt_get_ip(INTEL_PT_TIP, byte, buf, len, packet);
@@ -305,6 +419,8 @@ static int intel_pt_do_get_packet(const unsigned char *buf, size_t len,
 			return intel_pt_get_mode(buf, len, packet);
 		case 0x19:
 			return intel_pt_get_tsc(buf, len, packet);
+		case 0x59:
+			return intel_pt_get_mtc(buf, len, packet);
 		default:
 			return INTEL_PT_BAD_PACKET;
 		}
@@ -329,7 +445,7 @@ int intel_pt_get_packet(const unsigned char *buf, size_t len,
 int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
 		      size_t buf_len)
 {
-	int ret, i;
+	int ret, i, nr;
 	unsigned long long payload = packet->payload;
 	const char *name = intel_pt_pkt_name(packet->type);
 
@@ -338,6 +454,7 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
 	case INTEL_PT_PAD:
 	case INTEL_PT_PSB:
 	case INTEL_PT_PSBEND:
+	case INTEL_PT_TRACESTOP:
 	case INTEL_PT_OVF:
 		return snprintf(buf, buf_len, "%s", name);
 	case INTEL_PT_TNT: {
@@ -371,17 +488,16 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
 	case INTEL_PT_FUP:
 		if (!(packet->count))
 			return snprintf(buf, buf_len, "%s no ip", name);
+	case INTEL_PT_CYC:
+	case INTEL_PT_VMCS:
+	case INTEL_PT_MTC:
+	case INTEL_PT_MNT:
 	case INTEL_PT_CBR:
-		return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
 	case INTEL_PT_TSC:
-		if (packet->count)
-			return snprintf(buf, buf_len,
-					"%s 0x%llx CTC 0x%x FC 0x%x",
-					name, payload, packet->count & 0xffff,
-					(packet->count >> 16) & 0x1ff);
-		else
-			return snprintf(buf, buf_len, "%s 0x%llx",
-					name, payload);
+		return snprintf(buf, buf_len, "%s 0x%llx", name, payload);
+	case INTEL_PT_TMA:
+		return snprintf(buf, buf_len, "%s CTC 0x%x FC 0x%x", name,
+				(unsigned)payload, packet->count);
 	case INTEL_PT_MODE_EXEC:
 		return snprintf(buf, buf_len, "%s %lld", name, payload);
 	case INTEL_PT_MODE_TSX:
@@ -389,8 +505,10 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
 				name, (unsigned)(payload >> 1) & 1,
 				(unsigned)payload & 1);
 	case INTEL_PT_PIP:
-		ret = snprintf(buf, buf_len, "%s 0x%llx",
-			       name, payload);
+		nr = packet->payload & NR_FLAG ? 1 : 0;
+		payload &= ~NR_FLAG;
+		ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
+			       name, payload, nr);
 		return ret;
 	default:
 		break;
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
index 53404fa942b3..781bb79883bd 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.h
@@ -37,15 +37,21 @@ enum intel_pt_pkt_type {
 	INTEL_PT_TIP_PGD,
 	INTEL_PT_TIP_PGE,
 	INTEL_PT_TSC,
+	INTEL_PT_TMA,
 	INTEL_PT_MODE_EXEC,
 	INTEL_PT_MODE_TSX,
+	INTEL_PT_MTC,
 	INTEL_PT_TIP,
 	INTEL_PT_FUP,
+	INTEL_PT_CYC,
+	INTEL_PT_VMCS,
 	INTEL_PT_PSB,
 	INTEL_PT_PSBEND,
 	INTEL_PT_CBR,
+	INTEL_PT_TRACESTOP,
 	INTEL_PT_PIP,
 	INTEL_PT_OVF,
+	INTEL_PT_MNT,
 };
 
 struct intel_pt_pkt {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213152 — [PATCH 10/16] perf tools: Add Intel PT support for using MTC packets

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 10/16] perf tools: Add Intel PT support for using MTC packets
Message-ID<q1p75-3gB-47@gated-at.bofh.it>
In reply to#1213141
From: Adrian Hunter <adrian.hunter@intel.com>

MTC packets are a new Intel PT feature.

MTC packets provide finer grain timestamp information than TSC packets.

Support for this feature is indicated by:

  /sys/bus/event_source/devices/intel_pt/caps/mtc

which contains "1" if the feature is supported and "0" otherwise.

MTC packets can be requested using a PMU config term e.g. perf record -e
intel_pt/mtc/u sleep 1

The frequency of MTC packets can also be specified.  e.g. perf record -e
intel_pt/mtc,mtc_period=2/u sleep 1

The default value is 3 or the nearest lower value that is supported.  0
is always supported.

Valid values are given by:

/sys/bus/event_source/devices/intel_pt/caps/mtc_periods

which contains a hexadecimal value, the bits of which represent valid
values e.g. bit 2 set means value 2 is valid.

The value is converted to the MTC frequency as:

	CTC-frequency / (2 ^ value)

e.g. value 3 means one eighth of CTC-frequency

Where CTC is the hardware crystal clock, the frequency of which can be
related to TSC via values provided in cpuid leaf 0x15.

If an invalid value is entered, the error message will give a list of
valid values e.g.

	$ perf record -e intel_pt/mtc_period=15/u uname
	Invalid mtc_period for intel_pt. Valid values are: 0,3,6,9

tools/perf/Documentation/intel-pt.txt is updated in a later patch as
there are a number of new features being added.

For more information refer to the June 2015 or later Intel 64 and IA-32
Architectures SDM Chapter 36 Intel Processor Trace.

Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Link: http://lkml.kernel.org/r/1437150840-31811-22-git-send-email-adrian.hunter@intel.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/arch/x86/util/intel-pt.c | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/tools/perf/arch/x86/util/intel-pt.c b/tools/perf/arch/x86/util/intel-pt.c
index faae9289bcf6..a5de01dad868 100644
--- a/tools/perf/arch/x86/util/intel-pt.c
+++ b/tools/perf/arch/x86/util/intel-pt.c
@@ -190,17 +190,33 @@ static int intel_pt_pick_bit(int bits, int target)
 static u64 intel_pt_default_config(struct perf_pmu *intel_pt_pmu)
 {
 	char buf[256];
+	int mtc, mtc_periods = 0, mtc_period;
 	int psb_cyc, psb_periods, psb_period;
 	int pos = 0;
 	u64 config;
 
 	pos += scnprintf(buf + pos, sizeof(buf) - pos, "tsc");
 
+	if (perf_pmu__scan_file(intel_pt_pmu, "caps/mtc", "%d",
+				&mtc) != 1)
+		mtc = 1;
+
+	if (mtc) {
+		if (perf_pmu__scan_file(intel_pt_pmu, "caps/mtc_periods", "%x",
+					&mtc_periods) != 1)
+			mtc_periods = 0;
+		if (mtc_periods) {
+			mtc_period = intel_pt_pick_bit(mtc_periods, 3);
+			pos += scnprintf(buf + pos, sizeof(buf) - pos,
+					 ",mtc,mtc_period=%d", mtc_period);
+		}
+	}
+
 	if (perf_pmu__scan_file(intel_pt_pmu, "caps/psb_cyc", "%d",
 				&psb_cyc) != 1)
 		psb_cyc = 1;
 
-	if (psb_cyc) {
+	if (psb_cyc && mtc_periods) {
 		if (perf_pmu__scan_file(intel_pt_pmu, "caps/psb_periods", "%x",
 					&psb_periods) != 1)
 			psb_periods = 0;
@@ -454,9 +470,17 @@ out_err:
 static int intel_pt_validate_config(struct perf_pmu *intel_pt_pmu,
 				    struct perf_evsel *evsel)
 {
+	int err;
+
 	if (!evsel)
 		return 0;
 
+	err = intel_pt_val_config_term(intel_pt_pmu, "caps/mtc_periods",
+				       "mtc_period", "caps/mtc",
+				       evsel->attr.config);
+	if (err)
+		return err;
+
 	return intel_pt_val_config_term(intel_pt_pmu, "caps/psb_periods",
 					"psb_period", "caps/psb_cyc",
 					evsel->attr.config);
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213153 — [PATCH 03/16] perf ui tui progress: Implement the ui_progress_ops->finish() method

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-25 18:20 +0200
Subject[PATCH 03/16] perf ui tui progress: Implement the ui_progress_ops->finish() method
Message-ID<q1p75-3gB-49@gated-at.bofh.it>
In reply to#1213141
From: Arnaldo Carvalho de Melo <acme@redhat.com>

So that we can erase the progress bar after we're done with it, avoiding
things like:

-------------------------------------------------------------------

          ┌─Error:──────────────────────────────────────────────────────┐
          │Can't annotate unmapped_area_topdown:                        │
          │                                                             │
          │No vmlinux file with build id a826726b5ddacfab1f0bade868f1a79│
          │was found in the path.                                       │
          │                                                             │
          │Note that annotation using /proc/kcore requires CAP_SYS_RAWIO│
┌Processin│                                                             │──┐
│         │Please use:                                                  │  │
└─────────│                                                             │──┘
          │  perf buildid-cache -vu vmlinux                             │
          │                                                             │
          │or:                                                          │
          │                                                             │
          │  --vmlinux vmlinux                                          │
          │                                                             │
          │                                                             │
          │Press any key...                                             │
          └─────────────────────────────────────────────────────────────┘

Can't annotate unmapped_area_topdown:
-------------------------------------------------------------------

I.e. that finished progress bar behind the error window. It is not a
problem when we end up redrawing the whole screen, but its ugly when
we present such error windows, provide a TUI method so that code like
the above may avoid this situation, as will be done with the annotation
code in the next cset.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/n/tip-qvktnojzwwe37pweging058t@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/tui/progress.c | 19 ++++++++++++++++++-
 1 file changed, 18 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/tui/progress.c b/tools/perf/ui/tui/progress.c
index c61d14b101e0..c4b99008e2c9 100644
--- a/tools/perf/ui/tui/progress.c
+++ b/tools/perf/ui/tui/progress.c
@@ -33,9 +33,26 @@ static void tui_progress__update(struct ui_progress *p)
 	pthread_mutex_unlock(&ui__lock);
 }
 
+static void tui_progress__finish(void)
+{
+	int y;
+
+	if (use_browser <= 0)
+		return;
+
+	ui__refresh_dimensions(false);
+	pthread_mutex_lock(&ui__lock);
+	y = SLtt_Screen_Rows / 2 - 2;
+	SLsmg_set_color(0);
+	SLsmg_fill_region(y, 0, 3, SLtt_Screen_Cols, ' ');
+	SLsmg_refresh();
+	pthread_mutex_unlock(&ui__lock);
+}
+
 static struct ui_progress_ops tui_progress__ops =
 {
-	.update		= tui_progress__update,
+	.update = tui_progress__update,
+	.finish = tui_progress__finish,
 };
 
 void tui_progress__init(void)
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1213877

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-08-26 15:40 +0200
Message-ID<q1J5L-79A-7@gated-at.bofh.it>
In reply to#1213141
Em Tue, Aug 25, 2015 at 01:14:22PM -0300, Arnaldo Carvalho de Melo escreveu:
> Hi Ingo,
> 
> 	Please consider pulling, now to get back looking at eBPF :-)

Ingo, please do not process this one, there was a NAK from Masami to
some new syntax on adding non symbolic probes, will resubmit with the
new patches provided by Wang Nan that already got Masami's approval.

- Arnaldo
 
> - Arnaldo
> 
> The following changes since commit 0e53909a1cf0153736fb52c216558a65530d8c40:
> 
>   Merge tag 'perf-core-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/core (2015-08-22 08:45:46 +0200)
> 
> are available in the git repository at:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo
> 
> for you to fetch changes up to 1cbebfc7abb549ed3f4080e12c4d7b07d1f16637:
> 
>   perf probe: Support probing at absolute addresses (2015-08-25 12:36:22 -0300)
> 
> ----------------------------------------------------------------
> perf/core improvements and fixes:
> 
> User visible:
> 
> - Add support for using several Intel PT features (CYC, MTC packets), the
>   relevant documentation was updated: tools/perf/Documentation/intel-pt.txt,
>   briefly describing those packets, its purposes, how to configure them in
>   the event config terms and relevant external documentation for further
>   reading. (Adrian Hunter)
> 
> - Introduce support for probing at an absolut address, for user and kernel
>   'perf probe's, useful when one have the symbol maps on a developer machine
>   but not on an embedded system (Wang Nan)
> 
> - Clear the progress bar at the end of a ordered_events flush, fixing
>   an UI artifact when, after ordering the events the screen doesn't get
>   completely redraw, for instance, when an error window covers just the
>   center of the screen and waits for user input. (Arnaldo Carvalho de Melo)
> 
> - Fix 'annotate' segfault by resetting the dso find_symbol cache when removing
>   symbols (Arnaldo Carvalho de Melo)
> 
> Infrastructure:
> 
> - Fix Intel PT 'instructions' sample period (Adrian Hunter)
> 
> - Prevent segfault when reading probe point with absolute address (Wang Nan)
> 
> Build fixes:
> 
> - Fix tarball build broken by pt/bts (Adrian Hunter)
> 
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> 
> ----------------------------------------------------------------
> Adrian Hunter (11):
>       perf tools: Fix tarball build broken by pt/bts
>       perf tools: Fix Intel PT 'instructions' sample period
>       perf tools: Add Intel PT support for PSB periods
>       perf tools: Add new Intel PT packet definitions
>       perf tools: Pass Intel PT information for decoding MTC and CYC
>       perf tools: Add Intel PT support for decoding MTC packets
>       perf tools: Add Intel PT support for using MTC packets
>       perf tools: Add Intel PT support for decoding CYC packets
>       perf tools: Add Intel PT support for using CYC packets
>       perf tools: Add Intel PT support for decoding TRACESTOP packets
>       perf tools: Update Intel PT documentation
> 
> Arnaldo Carvalho de Melo (3):
>       perf annotate: Reset the dso find_symbol cache when removing symbols
>       perf ui tui progress: Implement the ui_progress_ops->finish() method
>       perf ordered_events: Clear the progress bar at the end of a flush
> 
> Wang Nan (2):
>       perf probe: Prevent segfault when reading probe point with absolute address
>       perf probe: Support probing at absolute addresses
> 
>  tools/perf/Documentation/intel-pt.txt              | 194 ++++++-
>  tools/perf/arch/x86/util/intel-pt.c                | 271 +++++++++-
>  tools/perf/builtin-annotate.c                      |   1 +
>  tools/perf/ui/tui/progress.c                       |  19 +-
>  tools/perf/util/dso.h                              |   2 +
>  tools/perf/util/intel-pt-decoder/inat.c            |   2 +-
>  tools/perf/util/intel-pt-decoder/inat.h            |   2 +-
>  tools/perf/util/intel-pt-decoder/inat_types.h      |  29 ++
>  tools/perf/util/intel-pt-decoder/insn.c            |   4 +-
>  tools/perf/util/intel-pt-decoder/insn.h            |   2 +-
>  .../perf/util/intel-pt-decoder/intel-pt-decoder.c  | 555 ++++++++++++++++++++-
>  .../perf/util/intel-pt-decoder/intel-pt-decoder.h  |   5 +
>  .../util/intel-pt-decoder/intel-pt-insn-decoder.c  |   2 +-
>  .../util/intel-pt-decoder/intel-pt-pkt-decoder.c   | 142 +++++-
>  .../util/intel-pt-decoder/intel-pt-pkt-decoder.h   |   6 +
>  tools/perf/util/intel-pt.c                         |  67 ++-
>  tools/perf/util/intel-pt.h                         |   5 +
>  tools/perf/util/ordered-events.c                   |   3 +
>  tools/perf/util/probe-event.c                      | 152 +++++-
>  tools/perf/util/probe-event.h                      |   3 +
>  tools/perf/util/probe-finder.c                     |  21 +-
>  tools/perf/util/symbol.c                           |  10 +
>  22 files changed, 1404 insertions(+), 93 deletions(-)
>  create mode 100644 tools/perf/util/intel-pt-decoder/inat_types.h
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web