[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150512132557.GQ21418@twins.programming.kicks-ass.net>
Date: Tue, 12 May 2015 15:25:57 +0200
From: Peter Zijlstra <peterz@...radead.org>
To: Kan Liang <kan.liang@...el.com>
Cc: mingo@...nel.org, acme@...radead.org, eranian@...gle.com,
andi@...stfloor.org, linux-kernel@...r.kernel.org
Subject: [RFC][PATCH] perf, pebs: Add PEBS v3 record decoding
So seeing how I have both this series and Andi's SKL patches, I did the
below on top of them both.
Could someone try that?
---
Subject: perf, pebs: Add PEBS v3 record decoding
From: Peter Zijlstra <peterz@...radead.org>
Date: Tue May 12 15:18:18 CEST 2015
PEBS v3 as present on Skylake fixed the long standing issue of the
status bits. They now really reflect the events that generated the
record.
Signed-off-by: Peter Zijlstra (Intel) <peterz@...radead.org>
---
arch/x86/kernel/cpu/perf_event_intel_ds.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
--- a/arch/x86/kernel/cpu/perf_event_intel_ds.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c
@@ -1034,6 +1034,9 @@ get_next_pebs_record_by_bit(void *base,
struct pebs_record_nhm *p = at;
if (test_bit(bit, (unsigned long *)&p->status)) {
+ /* PEBS v3 has accurate status bits */
+ if (x86_pmu.intel_cap.pebs_format >= 3)
+ return at;
if (p->status == (1 << bit))
return at;
@@ -1055,20 +1058,18 @@ static void __intel_pmu_pebs_event(struc
{
struct perf_sample_data data;
struct pt_regs regs;
- int i;
void *at = get_next_pebs_record_by_bit(base, top, bit);
if (!intel_pmu_save_and_restart(event) &&
!(event->hw.flags & PERF_X86_EVENT_AUTO_RELOAD))
return;
- if (count > 1) {
- for (i = 0; i < count - 1; i++) {
- setup_pebs_sample_data(event, iregs, at, &data, ®s);
- perf_event_output(event, &data, ®s);
- at += x86_pmu.pebs_record_size;
- at = get_next_pebs_record_by_bit(at, top, bit);
- }
+ while (count > 1) {
+ setup_pebs_sample_data(event, iregs, at, &data, ®s);
+ perf_event_output(event, &data, ®s);
+ at += x86_pmu.pebs_record_size;
+ at = get_next_pebs_record_by_bit(at, top, bit);
+ count--;
}
setup_pebs_sample_data(event, iregs, at, &data, ®s);
@@ -1124,9 +1125,9 @@ static void intel_pmu_drain_pebs_nhm(str
struct debug_store *ds = cpuc->ds;
struct perf_event *event;
void *base, *at, *top;
- int bit;
short counts[MAX_PEBS_EVENTS] = {};
short error[MAX_PEBS_EVENTS] = {};
+ int bit, i;
if (!x86_pmu.pebs_active)
return;
@@ -1142,6 +1143,15 @@ static void intel_pmu_drain_pebs_nhm(str
for (at = base; at < top; at += x86_pmu.pebs_record_size) {
struct pebs_record_nhm *p = at;
+ /* PEBS v3 has accurate status bits */
+ if (x86_pmu.intel_cap.pebs_format >= 3) {
+ for_each_set_bit(bit, (unsigned long *)&p->status,
+ MAX_PEBS_EVENTS)
+ counts[bit]++;
+
+ continue;
+ }
+
bit = find_first_bit((unsigned long *)&p->status,
x86_pmu.max_pebs_events);
if (bit >= x86_pmu.max_pebs_events)
@@ -1171,8 +1181,6 @@ static void intel_pmu_drain_pebs_nhm(str
pebs_status = p->status & cpuc->pebs_enabled;
pebs_status &= (1ULL << MAX_PEBS_EVENTS) - 1;
if (pebs_status != (1 << bit)) {
- u8 i;
-
for_each_set_bit(i, (unsigned long *)&pebs_status,
MAX_PEBS_EVENTS)
error[i]++;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists