Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1651189 > unrolled thread
| Started by | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| First post | 2017-05-26 10:30 +0200 |
| Last post | 2017-05-26 10:40 +0200 |
| Articles | 10 — 1 participant |
Back to article view | Back to linux.kernel
[PATCH V2 00/37] perf intel-pt: Power events and PTWRITE Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:30 +0200
[PATCH V2 05/37] perf intel-pt: Fix last_ip usage Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 02/37] perf intel-pt: Improve sample timestamp Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 10/37] perf intel-pt: Allow decoding with branch tracing disabled Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 15/37] perf intel-pt: Add decoder support for CBR events Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 13/37] perf intel-pt: Add decoder support for ptwrite and power event packets Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 04/37] perf intel-pt: Ensure IP is zero when state is INTEL_PT_STATE_NO_IP Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 03/37] perf intel-pt: Fix missing stack clear Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 22/37] tools include: Add byte-swapping macros to kernel.h Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
[PATCH V2 06/37] perf intel-pt: Ensure never to set 'last_ip' when packet 'count' is zero Adrian Hunter <adrian.hunter@intel.com> - 2017-05-26 10:40 +0200
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:30 +0200 |
| Subject | [PATCH V2 00/37] perf intel-pt: Power events and PTWRITE |
| Message-ID | <tLiNb-3tM-9@gated-at.bofh.it> |
Hi
Here are some patches to support Intel PT Power events and PTWRITE.
Power events report changes to C-state but I have also added support
for the existing CBR (core-to-bus ratio) packet and included that
when outputting power events. The PTWRITE packet is associated with
the new ptwrite instruction, which is essentially just a way to stuff
a 32 or 64 bit value into the PT trace. More details can be found in
the patches that add documentation and in the Intel SDM.
As far as I know, there isn't any hardware released that supports
the new packets, however the CBR packet is not new and will now be
visible by default.
There are also some miscellaneous improvements to Intel PT.
There are 3 patches that introduce a new way to define synthesized
events that carry arbitrary raw_data. I sent an RFC about that earlier.
The 3 patches are:
perf script: Add 'synth' event type for synthesized events
perf script: Add 'synth' field for synthesized event payloads
perf script: Add synthesized Intel PT power and ptwrite events
Changes in V2:
Reorder patches and add stable tags to fixes.
Adrian Hunter (37):
perf intel-pt: Move decoder error setting into one condition
perf intel-pt: Improve sample timestamp
perf intel-pt: Fix missing stack clear
perf intel-pt: Ensure IP is zero when state is INTEL_PT_STATE_NO_IP
perf intel-pt: Fix last_ip usage
perf intel-pt: Ensure never to set 'last_ip' when packet 'count' is zero
perf intel-pt: Use FUP always when scanning for an IP
perf intel-pt: Clear FUP flag on error
perf intel-pt: Add missing __fallthrough
perf intel-pt: Allow decoding with branch tracing disabled
perf intel-pt: Add default config for pass-through branch enable
perf intel-pt: Add documentation for new config terms
perf intel-pt: Add decoder support for ptwrite and power event packets
perf intel-pt: Add reserved byte to CBR packet payload
perf intel-pt: Add decoder support for CBR events
perf intel-pt: Remove redundant initial_skip checks
perf intel-pt: Fix transactions_sample_type
perf tools: Fix message because cpu list option is -C not -c
perf script: Fix message because field list option is -F not -f
perf script: Add 'synth' event type for synthesized events
perf script: Add 'synth' field for synthesized event payloads
tools include: Add byte-swapping macros to kernel.h
perf auxtrace: Add itrace option to output ptwrite events
perf auxtrace: Add itrace option to output power events
perf script: Add synthesized Intel PT power and ptwrite events
perf intel-pt: Factor out common code synthesizing event samples
perf intel-pt: Remove unused instructions_sample_period
perf intel-pt: Join needlessly wrapped lines
perf intel-pt: Tidy Intel PT evsel lookup into separate function
perf intel-pt: Tidy messages into called function intel_pt_synth_event()
perf intel-pt: Factor out intel_pt_set_event_name()
perf intel-pt: Move code in intel_pt_synth_events() to simplify attr setting
perf intel-pt: Synthesize new power and ptwrite events
perf intel-pt: Add example script for power events and PTWRITE
perf intel-pt: Update documentation to include new ptwrite and power events
perf intel-pt: Do not use TSC packets for calculating CPU cycles to TSC
perf auxtrace: Add CPU filter support
tools/include/linux/kernel.h | 35 +-
tools/perf/Documentation/intel-pt.txt | 78 ++-
tools/perf/Documentation/itrace.txt | 8 +-
tools/perf/Documentation/perf-script.txt | 6 +-
tools/perf/arch/x86/util/intel-pt.c | 5 +
tools/perf/builtin-report.c | 1 +
tools/perf/builtin-script.c | 207 ++++++-
.../perf/scripts/python/bin/intel-pt-events-record | 13 +
.../perf/scripts/python/bin/intel-pt-events-report | 3 +
tools/perf/scripts/python/intel-pt-events.py | 128 ++++
tools/perf/util/auxtrace.c | 18 +
tools/perf/util/auxtrace.h | 6 +
tools/perf/util/event.h | 93 +++
.../perf/util/intel-pt-decoder/intel-pt-decoder.c | 304 +++++++++-
.../perf/util/intel-pt-decoder/intel-pt-decoder.h | 13 +
.../util/intel-pt-decoder/intel-pt-pkt-decoder.c | 110 +++-
.../util/intel-pt-decoder/intel-pt-pkt-decoder.h | 7 +
tools/perf/util/intel-pt.c | 642 +++++++++++++++------
tools/perf/util/session.c | 2 +-
19 files changed, 1435 insertions(+), 244 deletions(-)
create mode 100644 tools/perf/scripts/python/bin/intel-pt-events-record
create mode 100644 tools/perf/scripts/python/bin/intel-pt-events-report
create mode 100644 tools/perf/scripts/python/intel-pt-events.py
Regards
Adrian
[toc] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 05/37] perf intel-pt: Fix last_ip usage |
| Message-ID | <tLiWR-3x5-1@gated-at.bofh.it> |
| In reply to | #1651189 |
Intel PT uses IP compression based on the last IP. For decoding purposes,
'last IP' is considered to be reset to zero whenever there is a
synchronization packet (PSB). The decoder wasn't doing that, and was
treating the zero value to mean that there was no last IP, whereas
compression can be done against the zero value. Fix by setting last_ip to
zero when a PSB is received and keep track of have_last_ip.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org # prereq. e1717e0485af
---
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 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 f9cd3aaef488..62e2c2ad3f1d 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -111,6 +111,7 @@ struct intel_pt_decoder {
bool have_tma;
bool have_cyc;
bool fixup_last_mtc;
+ bool have_last_ip;
uint64_t pos;
uint64_t last_ip;
uint64_t ip;
@@ -419,6 +420,7 @@ static uint64_t intel_pt_calc_ip(const struct intel_pt_pkt *packet,
static inline void intel_pt_set_last_ip(struct intel_pt_decoder *decoder)
{
decoder->last_ip = intel_pt_calc_ip(&decoder->packet, decoder->last_ip);
+ decoder->have_last_ip = true;
}
static inline void intel_pt_set_ip(struct intel_pt_decoder *decoder)
@@ -1672,6 +1674,8 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
break;
case INTEL_PT_PSB:
+ decoder->last_ip = 0;
+ decoder->have_last_ip = true;
intel_pt_clear_stack(&decoder->stack);
err = intel_pt_walk_psbend(decoder);
if (err == -EAGAIN)
@@ -1752,7 +1756,7 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
{
- return decoder->last_ip || decoder->packet.count == 0 ||
+ return decoder->have_last_ip || decoder->packet.count == 0 ||
decoder->packet.count == 3 || decoder->packet.count == 6;
}
@@ -1882,7 +1886,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
if (decoder->ip)
return 0;
}
- if (decoder->packet.count)
+ if (decoder->packet.count && decoder->have_last_ip)
intel_pt_set_last_ip(decoder);
break;
@@ -1932,6 +1936,8 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
break;
case INTEL_PT_PSB:
+ decoder->last_ip = 0;
+ decoder->have_last_ip = true;
intel_pt_clear_stack(&decoder->stack);
err = intel_pt_walk_psb(decoder);
if (err)
@@ -2066,6 +2072,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
decoder->pge = false;
decoder->continuous_period = false;
+ decoder->have_last_ip = false;
decoder->last_ip = 0;
decoder->ip = 0;
intel_pt_clear_stack(&decoder->stack);
@@ -2074,6 +2081,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
if (err)
return err;
+ decoder->have_last_ip = true;
decoder->pkt_state = INTEL_PT_STATE_NO_IP;
err = intel_pt_walk_psb(decoder);
@@ -2116,6 +2124,7 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
err = intel_pt_sync(decoder);
break;
case INTEL_PT_STATE_NO_IP:
+ decoder->have_last_ip = false;
decoder->last_ip = 0;
decoder->ip = 0;
/* Fall through */
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 02/37] perf intel-pt: Improve sample timestamp |
| Message-ID | <tLiWR-3x5-7@gated-at.bofh.it> |
| In reply to | #1651189 |
The decoder uses its current timestamp in samples. Usually that is a
timestamp that has already passed, but in some cases it is a timestamp for
a branch that the decoder is walking towards, and consequently hasn't
reached. Improve that situation by using the pkt_state to determine when
to use the current or previous timestamp.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
---
.../perf/util/intel-pt-decoder/intel-pt-decoder.c | 34 ++++++++++++++++++++--
1 file changed, 31 insertions(+), 3 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 5a9676c6e23f..d5c69e822282 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -64,6 +64,25 @@ enum intel_pt_pkt_state {
INTEL_PT_STATE_FUP_NO_TIP,
};
+static inline bool intel_pt_sample_time(enum intel_pt_pkt_state pkt_state)
+{
+ switch (pkt_state) {
+ case INTEL_PT_STATE_NO_PSB:
+ case INTEL_PT_STATE_NO_IP:
+ case INTEL_PT_STATE_ERR_RESYNC:
+ case INTEL_PT_STATE_IN_SYNC:
+ case INTEL_PT_STATE_TNT:
+ return true;
+ case INTEL_PT_STATE_TIP:
+ case INTEL_PT_STATE_TIP_PGD:
+ case INTEL_PT_STATE_FUP:
+ case INTEL_PT_STATE_FUP_NO_TIP:
+ return false;
+ default:
+ return true;
+ };
+}
+
#ifdef INTEL_PT_STRICT
#define INTEL_PT_STATE_ERR1 INTEL_PT_STATE_NO_PSB
#define INTEL_PT_STATE_ERR2 INTEL_PT_STATE_NO_PSB
@@ -99,6 +118,7 @@ struct intel_pt_decoder {
uint64_t timestamp;
uint64_t tsc_timestamp;
uint64_t ref_timestamp;
+ uint64_t sample_timestamp;
uint64_t ret_addr;
uint64_t ctc_timestamp;
uint64_t ctc_delta;
@@ -139,6 +159,7 @@ struct intel_pt_decoder {
unsigned int fup_tx_flags;
unsigned int tx_flags;
uint64_t timestamp_insn_cnt;
+ uint64_t sample_insn_cnt;
uint64_t stuck_ip;
int no_progress;
int stuck_ip_prd;
@@ -898,6 +919,7 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
decoder->tot_insn_cnt += insn_cnt;
decoder->timestamp_insn_cnt += insn_cnt;
+ decoder->sample_insn_cnt += insn_cnt;
decoder->period_insn_cnt += insn_cnt;
if (err) {
@@ -2069,7 +2091,7 @@ static int intel_pt_sync(struct intel_pt_decoder *decoder)
static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
{
- uint64_t est = decoder->timestamp_insn_cnt << 1;
+ uint64_t est = decoder->sample_insn_cnt << 1;
if (!decoder->cbr || !decoder->max_non_turbo_ratio)
goto out;
@@ -2077,7 +2099,7 @@ static uint64_t intel_pt_est_timestamp(struct intel_pt_decoder *decoder)
est *= decoder->max_non_turbo_ratio;
est /= decoder->cbr;
out:
- return decoder->timestamp + est;
+ return decoder->sample_timestamp + est;
}
const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
@@ -2133,11 +2155,17 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
if (err) {
decoder->state.err = intel_pt_ext_err(err);
decoder->state.from_ip = decoder->ip;
+ decoder->sample_timestamp = decoder->timestamp;
+ decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
} else {
decoder->state.err = 0;
+ if (intel_pt_sample_time(decoder->pkt_state)) {
+ decoder->sample_timestamp = decoder->timestamp;
+ decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
+ }
}
- decoder->state.timestamp = decoder->timestamp;
+ decoder->state.timestamp = decoder->sample_timestamp;
decoder->state.est_timestamp = intel_pt_est_timestamp(decoder);
decoder->state.cr3 = decoder->cr3;
decoder->state.tot_insn_cnt = decoder->tot_insn_cnt;
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 10/37] perf intel-pt: Allow decoding with branch tracing disabled |
| Message-ID | <tLiWR-3x5-13@gated-at.bofh.it> |
| In reply to | #1651189 |
The kernel now supports the disabling of branch tracing, however the
decoder assumes branch tracing is always enabled. Pass through a parameter
to indicate whether branch tracing is enabled and use it to avoid cases
when the decoder is expecting branch packets. There are 2 such cases.
First, FUP packets which can bind to an IP even when there is no branch
tracing. Secondly, the decoder will try to use branch packets to find an IP
to start decoding or to recover from errors.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 13 +++++++++++++
tools/perf/util/intel-pt-decoder/intel-pt-decoder.h | 1 +
tools/perf/util/intel-pt.c | 14 ++++++++++++++
3 files changed, 28 insertions(+)
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 cad40fe93bd2..dacb9223e743 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -106,6 +106,7 @@ struct intel_pt_decoder {
const unsigned char *buf;
size_t len;
bool return_compression;
+ bool branch_enable;
bool mtc_insn;
bool pge;
bool have_tma;
@@ -214,6 +215,7 @@ struct intel_pt_decoder *intel_pt_decoder_new(struct intel_pt_params *params)
decoder->pgd_ip = params->pgd_ip;
decoder->data = params->data;
decoder->return_compression = params->return_compression;
+ decoder->branch_enable = params->branch_enable;
decoder->period = params->period;
decoder->period_type = params->period_type;
@@ -1650,6 +1652,10 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
break;
}
intel_pt_set_last_ip(decoder);
+ if (!decoder->branch_enable) {
+ decoder->ip = decoder->last_ip;
+ break;
+ }
err = intel_pt_walk_fup(decoder);
if (err != -EAGAIN) {
if (err)
@@ -1964,6 +1970,13 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
decoder->set_fup_tx_flags = false;
+ if (!decoder->branch_enable) {
+ decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
+ decoder->overflow = false;
+ decoder->state.type = 0; /* Do not have a sample */
+ return 0;
+ }
+
intel_pt_log("Scanning for full IP\n");
err = intel_pt_walk_to_ip(decoder);
if (err)
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 e90619a43c0c..add3bed58349 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -87,6 +87,7 @@ struct intel_pt_params {
bool (*pgd_ip)(uint64_t ip, void *data);
void *data;
bool return_compression;
+ bool branch_enable;
uint64_t period;
enum intel_pt_period_type period_type;
unsigned max_non_turbo_ratio;
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c
index 4c7718f87a08..5c59b8c6a719 100644
--- a/tools/perf/util/intel-pt.c
+++ b/tools/perf/util/intel-pt.c
@@ -668,6 +668,19 @@ static bool intel_pt_return_compression(struct intel_pt *pt)
return true;
}
+static bool intel_pt_branch_enable(struct intel_pt *pt)
+{
+ struct perf_evsel *evsel;
+ u64 config;
+
+ evlist__for_each_entry(pt->session->evlist, evsel) {
+ if (intel_pt_get_config(pt, &evsel->attr, &config) &&
+ (config & 1) && !(config & 0x2000))
+ return false;
+ }
+ return true;
+}
+
static unsigned int intel_pt_mtc_period(struct intel_pt *pt)
{
struct perf_evsel *evsel;
@@ -799,6 +812,7 @@ static struct intel_pt_queue *intel_pt_alloc_queue(struct intel_pt *pt,
params.walk_insn = intel_pt_walk_next_insn;
params.data = ptq;
params.return_compression = intel_pt_return_compression(pt);
+ params.branch_enable = intel_pt_branch_enable(pt);
params.max_non_turbo_ratio = pt->max_non_turbo_ratio;
params.mtc_period = intel_pt_mtc_period(pt);
params.tsc_ctc_ratio_n = pt->tsc_ctc_ratio_n;
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 15/37] perf intel-pt: Add decoder support for CBR events |
| Message-ID | <tLiWS-3x5-23@gated-at.bofh.it> |
| In reply to | #1651189 |
Add decoder support for informing the tools of changes to the core-to-bus
ratio (CBR).
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 19 +++++++++++++++++++
tools/perf/util/intel-pt-decoder/intel-pt-decoder.h | 2 ++
2 files changed, 21 insertions(+)
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 96bf8d8e83c0..5dea06289db5 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -141,6 +141,7 @@ struct intel_pt_decoder {
int pkt_len;
int last_packet_type;
unsigned int cbr;
+ unsigned int cbr_seen;
unsigned int max_non_turbo_ratio;
double max_non_turbo_ratio_fp;
double cbr_cyc_to_tsc;
@@ -167,6 +168,7 @@ struct intel_pt_decoder {
uint64_t fup_ptw_payload;
uint64_t fup_mwait_payload;
uint64_t fup_pwre_payload;
+ uint64_t cbr_payload;
uint64_t timestamp_insn_cnt;
uint64_t sample_insn_cnt;
uint64_t stuck_ip;
@@ -1446,6 +1448,8 @@ static void intel_pt_calc_cbr(struct intel_pt_decoder *decoder)
{
unsigned int cbr = decoder->packet.payload & 0xff;
+ decoder->cbr_payload = decoder->packet.payload;
+
if (decoder->cbr == cbr)
return;
@@ -1806,6 +1810,16 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
case INTEL_PT_CBR:
intel_pt_calc_cbr(decoder);
+ if (!decoder->branch_enable &&
+ decoder->cbr != decoder->cbr_seen) {
+ decoder->cbr_seen = decoder->cbr;
+ decoder->state.type = INTEL_PT_CBR_CHG;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.cbr_payload =
+ decoder->packet.payload;
+ return 0;
+ }
break;
case INTEL_PT_MODE_EXEC:
@@ -2343,6 +2357,11 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder)
decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
} else {
decoder->state.err = 0;
+ if (decoder->cbr != decoder->cbr_seen && decoder->state.type) {
+ decoder->cbr_seen = decoder->cbr;
+ decoder->state.type |= INTEL_PT_CBR_CHG;
+ decoder->state.cbr_payload = decoder->cbr_payload;
+ }
if (intel_pt_sample_time(decoder->pkt_state)) {
decoder->sample_timestamp = decoder->timestamp;
decoder->sample_insn_cnt = decoder->timestamp_insn_cnt;
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 414c88e9e0da..921b22e8ca0e 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_sample_type {
INTEL_PT_PWR_ENTRY = 1 << 5,
INTEL_PT_EX_STOP = 1 << 6,
INTEL_PT_PWR_EXIT = 1 << 7,
+ INTEL_PT_CBR_CHG = 1 << 8,
};
enum intel_pt_period_type {
@@ -73,6 +74,7 @@ struct intel_pt_state {
uint64_t mwait_payload;
uint64_t pwre_payload;
uint64_t pwrx_payload;
+ uint64_t cbr_payload;
uint32_t flags;
enum intel_pt_insn_op insn_op;
int insn_len;
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 13/37] perf intel-pt: Add decoder support for ptwrite and power event packets |
| Message-ID | <tLiWS-3x5-21@gated-at.bofh.it> |
| In reply to | #1651189 |
Add decoder support for PTWRITE, MWAIT, PWRE, PWRX and EXSTOP packets. This
patch only affects the decoder, so the tools still do not select or consume
the new information. That is added in subsequent patches.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
---
.../perf/util/intel-pt-decoder/intel-pt-decoder.c | 176 ++++++++++++++++++++-
.../perf/util/intel-pt-decoder/intel-pt-decoder.h | 10 ++
.../util/intel-pt-decoder/intel-pt-pkt-decoder.c | 108 +++++++++++++
.../util/intel-pt-decoder/intel-pt-pkt-decoder.h | 7 +
4 files changed, 293 insertions(+), 8 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 dacb9223e743..e42804d10001 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -158,8 +158,15 @@ struct intel_pt_decoder {
bool continuous_period;
bool overflow;
bool set_fup_tx_flags;
+ bool set_fup_ptw;
+ bool set_fup_mwait;
+ bool set_fup_pwre;
+ bool set_fup_exstop;
unsigned int fup_tx_flags;
unsigned int tx_flags;
+ uint64_t fup_ptw_payload;
+ uint64_t fup_mwait_payload;
+ uint64_t fup_pwre_payload;
uint64_t timestamp_insn_cnt;
uint64_t sample_insn_cnt;
uint64_t stuck_ip;
@@ -660,6 +667,8 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
case INTEL_PT_PAD:
case INTEL_PT_VMCS:
case INTEL_PT_MNT:
+ case INTEL_PT_PTWRITE:
+ case INTEL_PT_PTWRITE_IP:
return 0;
case INTEL_PT_MTC:
@@ -758,6 +767,11 @@ static int intel_pt_calc_cyc_cb(struct intel_pt_pkt_info *pkt_info)
case INTEL_PT_TIP_PGD:
case INTEL_PT_TRACESTOP:
+ case INTEL_PT_EXSTOP:
+ case INTEL_PT_EXSTOP_IP:
+ case INTEL_PT_MWAIT:
+ case INTEL_PT_PWRE:
+ case INTEL_PT_PWRX:
case INTEL_PT_OVF:
case INTEL_PT_BAD: /* Does not happen */
default:
@@ -1016,6 +1030,57 @@ static int intel_pt_walk_insn(struct intel_pt_decoder *decoder,
return err;
}
+static bool intel_pt_fup_event(struct intel_pt_decoder *decoder)
+{
+ bool ret = false;
+
+ if (decoder->set_fup_tx_flags) {
+ decoder->set_fup_tx_flags = false;
+ decoder->tx_flags = decoder->fup_tx_flags;
+ decoder->state.type = INTEL_PT_TRANSACTION;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.flags = decoder->fup_tx_flags;
+ return true;
+ }
+ if (decoder->set_fup_ptw) {
+ decoder->set_fup_ptw = false;
+ decoder->state.type = INTEL_PT_PTW;
+ decoder->state.flags |= INTEL_PT_FUP_IP;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.ptw_payload = decoder->fup_ptw_payload;
+ return true;
+ }
+ if (decoder->set_fup_mwait) {
+ decoder->set_fup_mwait = false;
+ decoder->state.type = INTEL_PT_MWAIT_OP;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.mwait_payload = decoder->fup_mwait_payload;
+ ret = true;
+ }
+ if (decoder->set_fup_pwre) {
+ decoder->set_fup_pwre = false;
+ decoder->state.type |= INTEL_PT_PWR_ENTRY;
+ decoder->state.type &= ~INTEL_PT_BRANCH;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.pwre_payload = decoder->fup_pwre_payload;
+ ret = true;
+ }
+ if (decoder->set_fup_exstop) {
+ decoder->set_fup_exstop = false;
+ decoder->state.type |= INTEL_PT_EX_STOP;
+ decoder->state.type &= ~INTEL_PT_BRANCH;
+ decoder->state.flags |= INTEL_PT_FUP_IP;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ ret = true;
+ }
+ return ret;
+}
+
static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
{
struct intel_pt_insn intel_pt_insn;
@@ -1029,15 +1094,8 @@ static int intel_pt_walk_fup(struct intel_pt_decoder *decoder)
if (err == INTEL_PT_RETURN)
return 0;
if (err == -EAGAIN) {
- if (decoder->set_fup_tx_flags) {
- decoder->set_fup_tx_flags = false;
- decoder->tx_flags = decoder->fup_tx_flags;
- decoder->state.type = INTEL_PT_TRANSACTION;
- decoder->state.from_ip = decoder->ip;
- decoder->state.to_ip = 0;
- decoder->state.flags = decoder->fup_tx_flags;
+ if (intel_pt_fup_event(decoder))
return 0;
- }
return err;
}
decoder->set_fup_tx_flags = false;
@@ -1443,6 +1501,13 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
case INTEL_PT_TRACESTOP:
case INTEL_PT_BAD:
case INTEL_PT_PSB:
+ case INTEL_PT_PTWRITE:
+ case INTEL_PT_PTWRITE_IP:
+ case INTEL_PT_EXSTOP:
+ case INTEL_PT_EXSTOP_IP:
+ case INTEL_PT_MWAIT:
+ case INTEL_PT_PWRE:
+ case INTEL_PT_PWRX:
decoder->have_tma = false;
intel_pt_log("ERROR: Unexpected packet\n");
return -EAGAIN;
@@ -1524,6 +1589,13 @@ static int intel_pt_walk_fup_tip(struct intel_pt_decoder *decoder)
case INTEL_PT_MODE_TSX:
case INTEL_PT_BAD:
case INTEL_PT_PSBEND:
+ case INTEL_PT_PTWRITE:
+ case INTEL_PT_PTWRITE_IP:
+ case INTEL_PT_EXSTOP:
+ case INTEL_PT_EXSTOP_IP:
+ case INTEL_PT_MWAIT:
+ case INTEL_PT_PWRE:
+ case INTEL_PT_PWRX:
intel_pt_log("ERROR: Missing TIP after FUP\n");
decoder->pkt_state = INTEL_PT_STATE_ERR3;
return -ENOENT;
@@ -1654,8 +1726,13 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
intel_pt_set_last_ip(decoder);
if (!decoder->branch_enable) {
decoder->ip = decoder->last_ip;
+ if (intel_pt_fup_event(decoder))
+ return 0;
+ no_tip = false;
break;
}
+ if (decoder->set_fup_mwait)
+ no_tip = true;
err = intel_pt_walk_fup(decoder);
if (err != -EAGAIN) {
if (err)
@@ -1755,6 +1832,71 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
case INTEL_PT_PAD:
break;
+ case INTEL_PT_PTWRITE_IP:
+ decoder->fup_ptw_payload = decoder->packet.payload;
+ err = intel_pt_get_next_packet(decoder);
+ if (err)
+ return err;
+ if (decoder->packet.type == INTEL_PT_FUP) {
+ decoder->set_fup_ptw = true;
+ no_tip = true;
+ } else {
+ intel_pt_log_at("ERROR: Missing FUP after PTWRITE",
+ decoder->pos);
+ }
+ goto next;
+
+ case INTEL_PT_PTWRITE:
+ decoder->state.type = INTEL_PT_PTW;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.ptw_payload = decoder->packet.payload;
+ return 0;
+
+ case INTEL_PT_MWAIT:
+ decoder->fup_mwait_payload = decoder->packet.payload;
+ decoder->set_fup_mwait = true;
+ break;
+
+ case INTEL_PT_PWRE:
+ if (decoder->set_fup_mwait) {
+ decoder->fup_pwre_payload =
+ decoder->packet.payload;
+ decoder->set_fup_pwre = true;
+ break;
+ }
+ decoder->state.type = INTEL_PT_PWR_ENTRY;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.pwrx_payload = decoder->packet.payload;
+ return 0;
+
+ case INTEL_PT_EXSTOP_IP:
+ err = intel_pt_get_next_packet(decoder);
+ if (err)
+ return err;
+ if (decoder->packet.type == INTEL_PT_FUP) {
+ decoder->set_fup_exstop = true;
+ no_tip = true;
+ } else {
+ intel_pt_log_at("ERROR: Missing FUP after EXSTOP",
+ decoder->pos);
+ }
+ goto next;
+
+ case INTEL_PT_EXSTOP:
+ decoder->state.type = INTEL_PT_EX_STOP;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ return 0;
+
+ case INTEL_PT_PWRX:
+ decoder->state.type = INTEL_PT_PWR_EXIT;
+ decoder->state.from_ip = decoder->ip;
+ decoder->state.to_ip = 0;
+ decoder->state.pwrx_payload = decoder->packet.payload;
+ return 0;
+
default:
return intel_pt_bug(decoder);
}
@@ -1784,6 +1926,13 @@ static int intel_pt_walk_psb(struct intel_pt_decoder *decoder)
__fallthrough;
case INTEL_PT_TIP_PGE:
case INTEL_PT_TIP:
+ case INTEL_PT_PTWRITE:
+ case INTEL_PT_PTWRITE_IP:
+ case INTEL_PT_EXSTOP:
+ case INTEL_PT_EXSTOP_IP:
+ case INTEL_PT_MWAIT:
+ case INTEL_PT_PWRE:
+ case INTEL_PT_PWRX:
intel_pt_log("ERROR: Unexpected packet\n");
return -ENOENT;
@@ -1958,6 +2107,13 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder)
case INTEL_PT_VMCS:
case INTEL_PT_MNT:
case INTEL_PT_PAD:
+ case INTEL_PT_PTWRITE:
+ case INTEL_PT_PTWRITE_IP:
+ case INTEL_PT_EXSTOP:
+ case INTEL_PT_EXSTOP_IP:
+ case INTEL_PT_MWAIT:
+ case INTEL_PT_PWRE:
+ case INTEL_PT_PWRX:
default:
break;
}
@@ -1969,6 +2125,10 @@ static int intel_pt_sync_ip(struct intel_pt_decoder *decoder)
int err;
decoder->set_fup_tx_flags = false;
+ decoder->set_fup_ptw = false;
+ decoder->set_fup_mwait = false;
+ decoder->set_fup_pwre = false;
+ decoder->set_fup_exstop = false;
if (!decoder->branch_enable) {
decoder->pkt_state = INTEL_PT_STATE_IN_SYNC;
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 add3bed58349..414c88e9e0da 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.h
@@ -25,11 +25,17 @@
#define INTEL_PT_IN_TX (1 << 0)
#define INTEL_PT_ABORT_TX (1 << 1)
#define INTEL_PT_ASYNC (1 << 2)
+#define INTEL_PT_FUP_IP (1 << 3)
enum intel_pt_sample_type {
INTEL_PT_BRANCH = 1 << 0,
INTEL_PT_INSTRUCTION = 1 << 1,
INTEL_PT_TRANSACTION = 1 << 2,
+ INTEL_PT_PTW = 1 << 3,
+ INTEL_PT_MWAIT_OP = 1 << 4,
+ INTEL_PT_PWR_ENTRY = 1 << 5,
+ INTEL_PT_EX_STOP = 1 << 6,
+ INTEL_PT_PWR_EXIT = 1 << 7,
};
enum intel_pt_period_type {
@@ -63,6 +69,10 @@ struct intel_pt_state {
uint64_t timestamp;
uint64_t est_timestamp;
uint64_t trace_nr;
+ uint64_t ptw_payload;
+ uint64_t mwait_payload;
+ uint64_t pwre_payload;
+ uint64_t pwrx_payload;
uint32_t flags;
enum intel_pt_insn_op insn_op;
int insn_len;
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 7528ae4f7e28..accdb646a03d 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
@@ -64,6 +64,13 @@
[INTEL_PT_PIP] = "PIP",
[INTEL_PT_OVF] = "OVF",
[INTEL_PT_MNT] = "MNT",
+ [INTEL_PT_PTWRITE] = "PTWRITE",
+ [INTEL_PT_PTWRITE_IP] = "PTWRITE",
+ [INTEL_PT_EXSTOP] = "EXSTOP",
+ [INTEL_PT_EXSTOP_IP] = "EXSTOP",
+ [INTEL_PT_MWAIT] = "MWAIT",
+ [INTEL_PT_PWRE] = "PWRE",
+ [INTEL_PT_PWRX] = "PWRX",
};
const char *intel_pt_pkt_name(enum intel_pt_pkt_type type)
@@ -217,12 +224,80 @@ static int intel_pt_get_3byte(const unsigned char *buf, size_t len,
}
}
+static int intel_pt_get_ptwrite(const unsigned char *buf, size_t len,
+ struct intel_pt_pkt *packet)
+{
+ packet->count = (buf[1] >> 5) & 0x3;
+ packet->type = buf[1] & BIT(7) ? INTEL_PT_PTWRITE_IP :
+ INTEL_PT_PTWRITE;
+
+ switch (packet->count) {
+ case 0:
+ if (len < 6)
+ return INTEL_PT_NEED_MORE_BYTES;
+ packet->payload = le32_to_cpu(*(uint32_t *)(buf + 2));
+ return 6;
+ case 1:
+ if (len < 10)
+ return INTEL_PT_NEED_MORE_BYTES;
+ packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
+ return 10;
+ default:
+ return INTEL_PT_BAD_PACKET;
+ }
+}
+
+static int intel_pt_get_exstop(struct intel_pt_pkt *packet)
+{
+ packet->type = INTEL_PT_EXSTOP;
+ return 2;
+}
+
+static int intel_pt_get_exstop_ip(struct intel_pt_pkt *packet)
+{
+ packet->type = INTEL_PT_EXSTOP_IP;
+ return 2;
+}
+
+static int intel_pt_get_mwait(const unsigned char *buf, size_t len,
+ struct intel_pt_pkt *packet)
+{
+ if (len < 10)
+ return INTEL_PT_NEED_MORE_BYTES;
+ packet->type = INTEL_PT_MWAIT;
+ packet->payload = le64_to_cpu(*(uint64_t *)(buf + 2));
+ return 10;
+}
+
+static int intel_pt_get_pwre(const unsigned char *buf, size_t len,
+ struct intel_pt_pkt *packet)
+{
+ if (len < 4)
+ return INTEL_PT_NEED_MORE_BYTES;
+ packet->type = INTEL_PT_PWRE;
+ memcpy_le64(&packet->payload, buf + 2, 2);
+ return 4;
+}
+
+static int intel_pt_get_pwrx(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_PWRX;
+ memcpy_le64(&packet->payload, buf + 2, 5);
+ return 7;
+}
+
static int intel_pt_get_ext(const unsigned char *buf, size_t len,
struct intel_pt_pkt *packet)
{
if (len < 2)
return INTEL_PT_NEED_MORE_BYTES;
+ if ((buf[1] & 0x1f) == 0x12)
+ return intel_pt_get_ptwrite(buf, len, packet);
+
switch (buf[1]) {
case 0xa3: /* Long TNT */
return intel_pt_get_long_tnt(buf, len, packet);
@@ -244,6 +319,16 @@ static int intel_pt_get_ext(const unsigned char *buf, size_t len,
return intel_pt_get_tma(buf, len, packet);
case 0xC3: /* 3-byte header */
return intel_pt_get_3byte(buf, len, packet);
+ case 0x62: /* EXSTOP no IP */
+ return intel_pt_get_exstop(packet);
+ case 0xE2: /* EXSTOP with IP */
+ return intel_pt_get_exstop_ip(packet);
+ case 0xC2: /* MWAIT */
+ return intel_pt_get_mwait(buf, len, packet);
+ case 0x22: /* PWRE */
+ return intel_pt_get_pwre(buf, len, packet);
+ case 0xA2: /* PWRX */
+ return intel_pt_get_pwrx(buf, len, packet);
default:
return INTEL_PT_BAD_PACKET;
}
@@ -522,6 +607,29 @@ int intel_pt_pkt_desc(const struct intel_pt_pkt *packet, char *buf,
ret = snprintf(buf, buf_len, "%s 0x%llx (NR=%d)",
name, payload, nr);
return ret;
+ case INTEL_PT_PTWRITE:
+ return snprintf(buf, buf_len, "%s 0x%llx IP:0", name, payload);
+ case INTEL_PT_PTWRITE_IP:
+ return snprintf(buf, buf_len, "%s 0x%llx IP:1", name, payload);
+ case INTEL_PT_EXSTOP:
+ return snprintf(buf, buf_len, "%s IP:0", name);
+ case INTEL_PT_EXSTOP_IP:
+ return snprintf(buf, buf_len, "%s IP:1", name);
+ case INTEL_PT_MWAIT:
+ return snprintf(buf, buf_len, "%s 0x%llx Hints 0x%x Extensions 0x%x",
+ name, payload, (unsigned int)(payload & 0xff),
+ (unsigned int)((payload >> 32) & 0x3));
+ case INTEL_PT_PWRE:
+ return snprintf(buf, buf_len, "%s 0x%llx HW:%u CState:%u Sub-CState:%u",
+ name, payload, !!(payload & 0x80),
+ (unsigned int)((payload >> 12) & 0xf),
+ (unsigned int)((payload >> 8) & 0xf));
+ case INTEL_PT_PWRX:
+ return snprintf(buf, buf_len, "%s 0x%llx Last CState:%u Deepest CState:%u Wake Reason 0x%x",
+ name, payload,
+ (unsigned int)((payload >> 4) & 0xf),
+ (unsigned int)(payload & 0xf),
+ (unsigned int)((payload >> 8) & 0xf));
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 781bb79883bd..73ddc3a88d07 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
@@ -52,6 +52,13 @@ enum intel_pt_pkt_type {
INTEL_PT_PIP,
INTEL_PT_OVF,
INTEL_PT_MNT,
+ INTEL_PT_PTWRITE,
+ INTEL_PT_PTWRITE_IP,
+ INTEL_PT_EXSTOP,
+ INTEL_PT_EXSTOP_IP,
+ INTEL_PT_MWAIT,
+ INTEL_PT_PWRE,
+ INTEL_PT_PWRX,
};
struct intel_pt_pkt {
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 04/37] perf intel-pt: Ensure IP is zero when state is INTEL_PT_STATE_NO_IP |
| Message-ID | <tLiWS-3x5-35@gated-at.bofh.it> |
| In reply to | #1651189 |
A value of zero is used to indicate that there is no IP. Ensure the value is zero when the state is INTEL_PT_STATE_NO_IP. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: stable@vger.kernel.org --- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 1 + 1 file changed, 1 insertion(+) 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 28b16c3acdde..f9cd3aaef488 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -2117,6 +2117,7 @@ const struct intel_pt_state *intel_pt_decode(struct intel_pt_decoder *decoder) break; case INTEL_PT_STATE_NO_IP: decoder->last_ip = 0; + decoder->ip = 0; /* Fall through */ case INTEL_PT_STATE_ERR_RESYNC: err = intel_pt_sync_ip(decoder); -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 03/37] perf intel-pt: Fix missing stack clear |
| Message-ID | <tLiWS-3x5-37@gated-at.bofh.it> |
| In reply to | #1651189 |
The return compression stack must be cleared whenever there is a PSB. Fix one case where that was not happening. Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> Cc: stable@vger.kernel.org --- tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 1 + 1 file changed, 1 insertion(+) 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 d5c69e822282..28b16c3acdde 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c @@ -1932,6 +1932,7 @@ static int intel_pt_walk_to_ip(struct intel_pt_decoder *decoder) break; case INTEL_PT_PSB: + intel_pt_clear_stack(&decoder->stack); err = intel_pt_walk_psb(decoder); if (err) return err; -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 22/37] tools include: Add byte-swapping macros to kernel.h |
| Message-ID | <tLiWT-3x5-47@gated-at.bofh.it> |
| In reply to | #1651189 |
Add byte-swapping macros to kernel.h Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> --- tools/include/linux/kernel.h | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/tools/include/linux/kernel.h b/tools/include/linux/kernel.h index 73ccc48126bb..039bb85e4171 100644 --- a/tools/include/linux/kernel.h +++ b/tools/include/linux/kernel.h @@ -5,6 +5,8 @@ #include <stddef.h> #include <assert.h> #include <linux/compiler.h> +#include <endian.h> +#include <byteswap.h> #ifndef UINT_MAX #define UINT_MAX (~0U) @@ -67,12 +69,33 @@ #endif #endif -/* - * Both need more care to handle endianness - * (Don't use bitmap_copy_le() for now) - */ -#define cpu_to_le64(x) (x) -#define cpu_to_le32(x) (x) +#if __BYTE_ORDER == __BIG_ENDIAN +#define cpu_to_le16 bswap_16 +#define cpu_to_le32 bswap_32 +#define cpu_to_le64 bswap_64 +#define le16_to_cpu bswap_16 +#define le32_to_cpu bswap_32 +#define le64_to_cpu bswap_64 +#define cpu_to_be16 +#define cpu_to_be32 +#define cpu_to_be64 +#define be16_to_cpu +#define be32_to_cpu +#define be64_to_cpu +#else +#define cpu_to_le16 +#define cpu_to_le32 +#define cpu_to_le64 +#define le16_to_cpu +#define le32_to_cpu +#define le64_to_cpu +#define cpu_to_be16 bswap_16 +#define cpu_to_be32 bswap_32 +#define cpu_to_be64 bswap_64 +#define be16_to_cpu bswap_16 +#define be32_to_cpu bswap_32 +#define be64_to_cpu bswap_64 +#endif int vscnprintf(char *buf, size_t size, const char *fmt, va_list args); int scnprintf(char * buf, size_t size, const char * fmt, ...); -- 1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Adrian Hunter <adrian.hunter@intel.com> |
|---|---|
| Date | 2017-05-26 10:40 +0200 |
| Subject | [PATCH V2 06/37] perf intel-pt: Ensure never to set 'last_ip' when packet 'count' is zero |
| Message-ID | <tLiWT-3x5-51@gated-at.bofh.it> |
| In reply to | #1651189 |
Intel PT uses IP compression based on the last IP. For decoding purposes,
'last IP' is not updated when a branch target has been suppressed, which is
indicated by IPBytes == 0. IPBytes is stored in the packet 'count', so
ensure never to set 'last_ip' when packet 'count' is zero.
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Cc: stable@vger.kernel.org
---
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c | 8 +++++---
1 file changed, 5 insertions(+), 3 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 62e2c2ad3f1d..72b9dc8135a2 100644
--- a/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
+++ b/tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
@@ -1470,7 +1470,8 @@ static int intel_pt_walk_psbend(struct intel_pt_decoder *decoder)
case INTEL_PT_FUP:
decoder->pge = true;
- intel_pt_set_last_ip(decoder);
+ if (decoder->packet.count)
+ intel_pt_set_last_ip(decoder);
break;
case INTEL_PT_MODE_TSX:
@@ -1756,8 +1757,9 @@ static int intel_pt_walk_trace(struct intel_pt_decoder *decoder)
static inline bool intel_pt_have_ip(struct intel_pt_decoder *decoder)
{
- return decoder->have_last_ip || decoder->packet.count == 0 ||
- decoder->packet.count == 3 || decoder->packet.count == 6;
+ return decoder->packet.count &&
+ (decoder->have_last_ip || decoder->packet.count == 3 ||
+ decoder->packet.count == 6);
}
/* Walk PSB+ packets to get in sync. */
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web