perf/x86/intel/pt: Export CPU frequency ratios needed by PT decoders
authorAlexander Shishkin <alexander.shishkin@linux.intel.com>
Wed, 19 Aug 2015 14:02:10 +0000 (17:02 +0300)
committerIngo Molnar <mingo@kernel.org>
Thu, 5 May 2016 08:16:28 +0000 (10:16 +0200)
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>
arch/x86/events/intel/pt.c
arch/x86/events/intel/pt.h

index 2d1ce2c6ac7bd397f0589f0969c0736049a14ade..c3a359cf670e55b9dc4b629faf6408d8faa73033 100644 (file)
@@ -127,9 +127,46 @@ static struct attribute_group pt_format_group = {
        .attrs  = pt_formats_attr,
 };
 
+static ssize_t
+pt_timing_attr_show(struct device *dev, struct device_attribute *attr,
+                   char *page)
+{
+       struct perf_pmu_events_attr *pmu_attr =
+               container_of(attr, struct perf_pmu_events_attr, attr);
+
+       switch (pmu_attr->id) {
+       case 0:
+               return sprintf(page, "%lu\n", pt_pmu.max_nonturbo_ratio);
+       case 1:
+               return sprintf(page, "%u:%u\n",
+                              pt_pmu.tsc_art_num,
+                              pt_pmu.tsc_art_den);
+       default:
+               break;
+       }
+
+       return -EINVAL;
+}
+
+PMU_EVENT_ATTR(max_nonturbo_ratio, timing_attr_max_nonturbo_ratio, 0,
+              pt_timing_attr_show);
+PMU_EVENT_ATTR(tsc_art_ratio, timing_attr_tsc_art_ratio, 1,
+              pt_timing_attr_show);
+
+static struct attribute *pt_timing_attr[] = {
+       &timing_attr_max_nonturbo_ratio.attr.attr,
+       &timing_attr_tsc_art_ratio.attr.attr,
+       NULL,
+};
+
+static struct attribute_group pt_timing_group = {
+       .attrs  = pt_timing_attr,
+};
+
 static const struct attribute_group *pt_attr_groups[] = {
        &pt_cap_group,
        &pt_format_group,
+       &pt_timing_group,
        NULL,
 };
 
@@ -142,6 +179,23 @@ static int __init pt_pmu_hw_init(void)
        int ret;
        long i;
 
+       rdmsrl(MSR_PLATFORM_INFO, reg);
+       pt_pmu.max_nonturbo_ratio = (reg & 0xff00) >> 8;
+
+       /*
+        * if available, read in TSC to core crystal clock ratio,
+        * otherwise, zero for numerator stands for "not enumerated"
+        * as per SDM
+        */
+       if (boot_cpu_data.cpuid_level >= CPUID_TSC_LEAF) {
+               u32 eax, ebx, ecx, edx;
+
+               cpuid(CPUID_TSC_LEAF, &eax, &ebx, &ecx, &edx);
+
+               pt_pmu.tsc_art_num = ebx;
+               pt_pmu.tsc_art_den = eax;
+       }
+
        if (boot_cpu_has(X86_FEATURE_VMX)) {
                /*
                 * Intel SDM, 36.5 "Tracing post-VMXON" says that
index ca6459996d2df8d344752f04072c1bc31f36b25f..efffa4a09f687f9578a6d8b99a89b3d2595ded4c 100644 (file)
@@ -82,6 +82,9 @@ struct topa_entry {
 #define PT_CPUID_LEAVES                2
 #define PT_CPUID_REGS_NUM      4 /* number of regsters (eax, ebx, ecx, edx) */
 
+/* TSC to Core Crystal Clock Ratio */
+#define CPUID_TSC_LEAF         0x15
+
 enum pt_capabilities {
        PT_CAP_max_subleaf = 0,
        PT_CAP_cr3_filtering,
@@ -102,6 +105,9 @@ struct pt_pmu {
        struct pmu              pmu;
        u32                     caps[PT_CPUID_REGS_NUM * PT_CPUID_LEAVES];
        bool                    vmx;
+       unsigned long           max_nonturbo_ratio;
+       unsigned int            tsc_art_num;
+       unsigned int            tsc_art_den;
 };
 
 /**