diff options
author | Alexander Shishkin <alexander.shishkin@linux.intel.com> | 2015-08-19 10:02:10 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2016-05-05 04:16:28 -0400 |
commit | 65c7e6f1c4810e9bce935520f44f6d2613cd1b40 (patch) | |
tree | 843648e962ce8f25e343fc489d0b6a764a46305c | |
parent | ccbebba4c6bfda8e3ef9e431ce2c3d91c5fc5a63 (diff) |
perf/x86/intel/pt: Export CPU frequency ratios needed by PT decoders
Intel PT decoders need access to various bits of timing related
information to be able to correctly decode timing packets from a PT
stream (MTC and CBR packets). This patch exports all the necessary
bits as sysfs attributes for the sake of consistency:
* max_nonturbo_ratio: ratio between the invariant TSC and base clock;
* tsc_art_ratio: TSC to core crystal clock ratio (also available as CPUID.15H).
Signed-off-by: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mathieu Poirier <mathieu.poirier@linaro.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: vince@deater.net
Link: http://lkml.kernel.org/r/87zisdvibe.fsf@ashishki-desk.ger.corp.intel.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/events/intel/pt.c | 54 | ||||
-rw-r--r-- | arch/x86/events/intel/pt.h | 6 |
2 files changed, 60 insertions, 0 deletions
diff --git a/arch/x86/events/intel/pt.c b/arch/x86/events/intel/pt.c index 2d1ce2c6ac7b..c3a359cf670e 100644 --- a/arch/x86/events/intel/pt.c +++ b/arch/x86/events/intel/pt.c | |||
@@ -127,9 +127,46 @@ static struct attribute_group pt_format_group = { | |||
127 | .attrs = pt_formats_attr, | 127 | .attrs = pt_formats_attr, |
128 | }; | 128 | }; |
129 | 129 | ||
130 | static ssize_t | ||
131 | pt_timing_attr_show(struct device *dev, struct device_attribute *attr, | ||
132 | char *page) | ||
133 | { | ||
134 | struct perf_pmu_events_attr *pmu_attr = | ||
135 | container_of(attr, struct perf_pmu_events_attr, attr); | ||
136 | |||
137 | switch (pmu_attr->id) { | ||
138 | case 0: | ||
139 | return sprintf(page, "%lu\n", pt_pmu.max_nonturbo_ratio); | ||
140 | case 1: | ||
141 | return sprintf(page, "%u:%u\n", | ||
142 | pt_pmu.tsc_art_num, | ||
143 | pt_pmu.tsc_art_den); | ||
144 | default: | ||
145 | break; | ||
146 | } | ||
147 | |||
148 | return -EINVAL; | ||
149 | } | ||
150 | |||
151 | PMU_EVENT_ATTR(max_nonturbo_ratio, timing_attr_max_nonturbo_ratio, 0, | ||
152 | pt_timing_attr_show); | ||
153 | PMU_EVENT_ATTR(tsc_art_ratio, timing_attr_tsc_art_ratio, 1, | ||
154 | pt_timing_attr_show); | ||
155 | |||
156 | static struct attribute *pt_timing_attr[] = { | ||
157 | &timing_attr_max_nonturbo_ratio.attr.attr, | ||
158 | &timing_attr_tsc_art_ratio.attr.attr, | ||
159 | NULL, | ||
160 | }; | ||
161 | |||
162 | static struct attribute_group pt_timing_group = { | ||
163 | .attrs = pt_timing_attr, | ||
164 | }; | ||
165 | |||
130 | static const struct attribute_group *pt_attr_groups[] = { | 166 | static const struct attribute_group *pt_attr_groups[] = { |
131 | &pt_cap_group, | 167 | &pt_cap_group, |
132 | &pt_format_group, | 168 | &pt_format_group, |
169 | &pt_timing_group, | ||
133 | NULL, | 170 | NULL, |
134 | }; | 171 | }; |
135 | 172 | ||
@@ -142,6 +179,23 @@ static int __init pt_pmu_hw_init(void) | |||
142 | int ret; | 179 | int ret; |
143 | long i; | 180 | long i; |
144 | 181 | ||
182 | rdmsrl(MSR_PLATFORM_INFO, reg); | ||
183 | pt_pmu.max_nonturbo_ratio = (reg & 0xff00) >> 8; | ||
184 | |||
185 | /* | ||
186 | * if available, read in TSC to core crystal clock ratio, | ||
187 | * otherwise, zero for numerator stands for "not enumerated" | ||
188 | * as per SDM | ||
189 | */ | ||
190 | if (boot_cpu_data.cpuid_level >= CPUID_TSC_LEAF) { | ||
191 | u32 eax, ebx, ecx, edx; | ||
192 | |||
193 | cpuid(CPUID_TSC_LEAF, &eax, &ebx, &ecx, &edx); | ||
194 | |||
195 | pt_pmu.tsc_art_num = ebx; | ||
196 | pt_pmu.tsc_art_den = eax; | ||
197 | } | ||
198 | |||
145 | if (boot_cpu_has(X86_FEATURE_VMX)) { | 199 | if (boot_cpu_has(X86_FEATURE_VMX)) { |
146 | /* | 200 | /* |
147 | * Intel SDM, 36.5 "Tracing post-VMXON" says that | 201 | * Intel SDM, 36.5 "Tracing post-VMXON" says that |
diff --git a/arch/x86/events/intel/pt.h b/arch/x86/events/intel/pt.h index ca6459996d2d..efffa4a09f68 100644 --- a/arch/x86/events/intel/pt.h +++ b/arch/x86/events/intel/pt.h | |||
@@ -82,6 +82,9 @@ struct topa_entry { | |||
82 | #define PT_CPUID_LEAVES 2 | 82 | #define PT_CPUID_LEAVES 2 |
83 | #define PT_CPUID_REGS_NUM 4 /* number of regsters (eax, ebx, ecx, edx) */ | 83 | #define PT_CPUID_REGS_NUM 4 /* number of regsters (eax, ebx, ecx, edx) */ |
84 | 84 | ||
85 | /* TSC to Core Crystal Clock Ratio */ | ||
86 | #define CPUID_TSC_LEAF 0x15 | ||
87 | |||
85 | enum pt_capabilities { | 88 | enum pt_capabilities { |
86 | PT_CAP_max_subleaf = 0, | 89 | PT_CAP_max_subleaf = 0, |
87 | PT_CAP_cr3_filtering, | 90 | PT_CAP_cr3_filtering, |
@@ -102,6 +105,9 @@ struct pt_pmu { | |||
102 | struct pmu pmu; | 105 | struct pmu pmu; |
103 | u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; | 106 | u32 caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES]; |
104 | bool vmx; | 107 | bool vmx; |
108 | unsigned long max_nonturbo_ratio; | ||
109 | unsigned int tsc_art_num; | ||
110 | unsigned int tsc_art_den; | ||
105 | }; | 111 | }; |
106 | 112 | ||
107 | /** | 113 | /** |