diff options
author | Stephane Eranian <eranian@google.com> | 2014-05-15 11:56:44 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2014-05-19 08:52:59 -0400 |
commit | 722e76e60f2775c21b087ff12c5e678cf0ebcaaf (patch) | |
tree | 55dba7d6ec8c33b7d40ed10c18f34459f16c5a2e | |
parent | 643fd0b9f5dc40fedbfbb908ebe6f1169284f7d8 (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.c | 22 |
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 | ||
111 | static u64 precise_store_data_hsw(u64 status) | 111 | static 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 | } |