From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755622AbdESJBT (ORCPT ); Fri, 19 May 2017 05:01:19 -0400 Received: from mga07.intel.com ([134.134.136.100]:55399 "EHLO mga07.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753225AbdESJBO (ORCPT ); Fri, 19 May 2017 05:01:14 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,363,1491289200"; d="scan'208";a="1132489342" From: Adrian Hunter To: Arnaldo Carvalho de Melo , Andi Kleen Cc: linux-kernel@vger.kernel.org Subject: [PATCH 24/37] perf script: Add synthesized Intel PT power and ptwrite events Date: Fri, 19 May 2017 11:54:23 +0300 Message-Id: <1495184076-23805-25-git-send-email-adrian.hunter@intel.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1495184076-23805-1-git-send-email-adrian.hunter@intel.com> References: <1495184076-23805-1-git-send-email-adrian.hunter@intel.com> Organization: Intel Finland Oy, Registered Address: PL 281, 00181 Helsinki, Business Identity Code: 0357606 - 4, Domiciled in Helsinki Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Add definitions for synthesized Intel PT events for power and ptwrite. Signed-off-by: Adrian Hunter --- tools/perf/builtin-script.c | 114 +++++++++++++++++++++++++++++++++++++++++++- tools/perf/util/event.h | 90 ++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 1 deletion(-) diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index f7a5130d2fd0..4a13daacba25 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c @@ -1120,10 +1120,122 @@ static void print_sample_bpf_output(struct perf_sample *sample) (char *)(sample->raw_data)); } -static void print_sample_synth(struct perf_sample *sample __maybe_unused, +static void print_sample_spacing(int len, int spacing) +{ + if (len > 0 && len < spacing) + printf("%*s", spacing - len, ""); +} + +static void print_sample_pt_spacing(int len) +{ + print_sample_spacing(len, 34); +} + +static void print_sample_synth_ptwrite(struct perf_sample *sample) +{ + struct perf_synth_intel_ptwrite *data = sample->raw_data; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + len = printf(" IP: %u payload: %#" PRIx64 " ", + data->ip, le64_to_cpu(data->payload)); + print_sample_pt_spacing(len); +} + +static void print_sample_synth_mwait(struct perf_sample *sample) +{ + struct perf_synth_intel_mwait *data = sample->raw_data; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + len = printf(" hints: %#x extensions: %#x ", + data->hints, data->extensions); + print_sample_pt_spacing(len); +} + +static void print_sample_synth_pwre(struct perf_sample *sample) +{ + struct perf_synth_intel_pwre *data = sample->raw_data; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + len = printf(" hw: %u cstate: %u sub-cstate: %u ", + data->hw, data->cstate, data->subcstate); + print_sample_pt_spacing(len); +} + +static void print_sample_synth_exstop(struct perf_sample *sample) +{ + struct perf_synth_intel_exstop *data = sample->raw_data; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + len = printf(" IP: %u ", data->ip); + print_sample_pt_spacing(len); +} + +static void print_sample_synth_pwrx(struct perf_sample *sample) +{ + struct perf_synth_intel_pwrx *data = sample->raw_data; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + len = printf(" deepest cstate: %u last cstate: %u wake reason: %#x ", + data->deepest_cstate, data->last_cstate, + data->wake_reason); + print_sample_pt_spacing(len); +} + +static void print_sample_synth_cbr(struct perf_sample *sample) +{ + struct perf_synth_intel_cbr *data = sample->raw_data; + unsigned int percent, freq; + int len; + + if (sample->raw_size < sizeof(*data)) + return; + + freq = (le32_to_cpu(data->freq) + 500) / 1000; + len = printf(" cbr: %2u freq: %4u MHz ", data->cbr, freq); + if (data->max_nonturbo) { + percent = (5 + (1000 * data->cbr) / data->max_nonturbo) / 10; + len += printf("(%3u%%) ", percent); + } + print_sample_pt_spacing(len); +} + +static void print_sample_synth(struct perf_sample *sample, struct perf_evsel *evsel) { switch (evsel->attr.config) { + case PERF_SYNTH_INTEL_PTWRITE: + print_sample_synth_ptwrite(sample); + break; + case PERF_SYNTH_INTEL_MWAIT: + print_sample_synth_mwait(sample); + break; + case PERF_SYNTH_INTEL_PWRE: + print_sample_synth_pwre(sample); + break; + case PERF_SYNTH_INTEL_EXSTOP: + print_sample_synth_exstop(sample); + break; + case PERF_SYNTH_INTEL_PWRX: + print_sample_synth_pwrx(sample); + break; + case PERF_SYNTH_INTEL_CBR: + print_sample_synth_cbr(sample); + break; default: break; } diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index af285ed951f4..7823d43315b7 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h @@ -255,6 +255,96 @@ enum auxtrace_error_type { /* Attribute type for custom synthesized events */ #define PERF_TYPE_SYNTH 3000000000 +/* Attribute config for custom synthesized events */ +enum perf_synth_id { + PERF_SYNTH_INTEL_PTWRITE, + PERF_SYNTH_INTEL_MWAIT, + PERF_SYNTH_INTEL_PWRE, + PERF_SYNTH_INTEL_EXSTOP, + PERF_SYNTH_INTEL_PWRX, + PERF_SYNTH_INTEL_CBR, +}; + +/* + * Raw data formats for synthesized events. Note that raw data plus the raw data + * size (4 bytes) must align to 8-bytes. + */ + +struct perf_synth_intel_ptwrite { + union { + struct { + u32 ip : 1, + reserved : 31; + }; + u32 flags; + }; + u64 payload; +} __packed; + +struct perf_synth_intel_mwait { + u32 reserved; + union { + struct { + u64 hints : 8, + reserved1 : 24, + extensions : 2, + reserved2 : 30; + }; + u64 payload; + }; +} __packed; + +struct perf_synth_intel_pwre { + u32 reserved; + union { + struct { + u64 reserved1 : 7, + hw : 1, + subcstate : 4, + cstate : 4, + reserved2 : 48; + }; + u64 payload; + }; +} __packed; + +struct perf_synth_intel_exstop { + union { + struct { + u32 ip : 1, + reserved : 31; + }; + u32 flags; + }; +}; + +struct perf_synth_intel_pwrx { + u32 reserved; + union { + struct { + u64 deepest_cstate : 4, + last_cstate : 4, + wake_reason : 4, + reserved1 : 52; + }; + u64 payload; + }; +} __packed; + +struct perf_synth_intel_cbr { + union { + struct { + u32 cbr : 8, + reserved1 : 8, + max_nonturbo : 8, + reserved2 : 8; + }; + u32 flags; + }; + u32 freq; + u32 reserved3; +}; + /* * The kernel collects the number of events it couldn't send in a stretch and * when possible sends this number in a PERF_RECORD_LOST event. The number of -- 1.9.1