aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephane Eranian <eranian@google.com>2014-05-15 11:56:44 -0400
committerThomas Gleixner <tglx@linutronix.de>2014-05-19 08:52:59 -0400
commit722e76e60f2775c21b087ff12c5e678cf0ebcaaf (patch)
tree55dba7d6ec8c33b7d40ed10c18f34459f16c5a2e
parent643fd0b9f5dc40fedbfbb908ebe6f1169284f7d8 (diff)
fix Haswell precise store data source encoding
This patch fixes a bug in precise_store_data_hsw() whereby it would set the data source memory level to the wrong value. As per the the SDM Vol 3b Table 18-41 (Layout of Data Linear Address Information in PEBS Record), when status bit 0 is set this is a L1 hit, otherwise this is a L1 miss. This patch encodes the memory level according to the specification. In V2, we added the filtering on the store events. Only the following events produce L1 information: * MEM_UOPS_RETIRED.STLB_MISS_STORES * MEM_UOPS_RETIRED.LOCK_STORES * MEM_UOPS_RETIRED.SPLIT_STORES * MEM_UOPS_RETIRED.ALL_STORES Cc: mingo@elte.hu Cc: acme@ghostprotocols.net Cc: jolsa@redhat.com Cc: jmario@redhat.com Cc: ak@linux.intel.com Tested-and-Reviewed-by: Don Zickus <dzickus@redhat.com> Signed-off-by: Stephane Eranian <eranian@google.com> Signed-off-by: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/20140515155644.GA3884@quad Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_ds.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c
index ae96cfa5eddd..980970cb744d 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -108,15 +108,31 @@ static u64 precise_store_data(u64 status)
108 return val; 108 return val;
109} 109}
110 110
111static u64 precise_store_data_hsw(u64 status) 111static u64 precise_store_data_hsw(struct perf_event *event, u64 status)
112{ 112{
113 union perf_mem_data_src dse; 113 union perf_mem_data_src dse;
114 u64 cfg = event->hw.config & INTEL_ARCH_EVENT_MASK;
114 115
115 dse.val = 0; 116 dse.val = 0;
116 dse.mem_op = PERF_MEM_OP_STORE; 117 dse.mem_op = PERF_MEM_OP_STORE;
117 dse.mem_lvl = PERF_MEM_LVL_NA; 118 dse.mem_lvl = PERF_MEM_LVL_NA;
119
120 /*
121 * L1 info only valid for following events:
122 *
123 * MEM_UOPS_RETIRED.STLB_MISS_STORES
124 * MEM_UOPS_RETIRED.LOCK_STORES
125 * MEM_UOPS_RETIRED.SPLIT_STORES
126 * MEM_UOPS_RETIRED.ALL_STORES
127 */
128 if (cfg != 0x12d0 && cfg != 0x22d0 && cfg != 0x42d0 && cfg != 0x82d0)
129 return dse.mem_lvl;
130
118 if (status & 1) 131 if (status & 1)
119 dse.mem_lvl = PERF_MEM_LVL_L1; 132 dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_HIT;
133 else
134 dse.mem_lvl = PERF_MEM_LVL_L1 | PERF_MEM_LVL_MISS;
135
120 /* Nothing else supported. Sorry. */ 136 /* Nothing else supported. Sorry. */
121 return dse.val; 137 return dse.val;
122} 138}
@@ -887,7 +903,7 @@ static void __intel_pmu_pebs_event(struct perf_event *event,
887 data.data_src.val = load_latency_data(pebs->dse); 903 data.data_src.val = load_latency_data(pebs->dse);
888 else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW) 904 else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST_HSW)
889 data.data_src.val = 905 data.data_src.val =
890 precise_store_data_hsw(pebs->dse); 906 precise_store_data_hsw(event, pebs->dse);
891 else 907 else
892 data.data_src.val = precise_store_data(pebs->dse); 908 data.data_src.val = precise_store_data(pebs->dse);
893 } 909 }