Skip to content

Commit 8ef9b84

Browse files
Peter ZijlstraIngo Molnar
authored andcommitted
perf/x86/intel: Fix PEBSv3 record drain
Alexander hit the WARN_ON_ONCE(!event) on his Skylake while running the perf fuzzer. This means the PEBSv3 record included a status bit for an inactive event, something that _should_ not happen. Move the code that filters the status bits against our known PEBS events up a spot to guarantee we only deal with events we know about. Further add "continue" statements to the WARN_ON_ONCE()s such that we'll not die nor generate silly events in case we ever do hit them again. Reported-by: Alexander Shishkin <[email protected]> Tested-by: Alexander Shishkin <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Cc: [email protected] Fixes: a3d8654 ("perf/x86/intel/pebs: Add PEBSv3 decoding") Signed-off-by: Ingo Molnar <[email protected]>
1 parent ef9ef3b commit 8ef9b84

File tree

1 file changed

+11
-8
lines changed
  • arch/x86/events/intel

1 file changed

+11
-8
lines changed

arch/x86/events/intel/ds.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,18 +1274,18 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
12741274
struct pebs_record_nhm *p = at;
12751275
u64 pebs_status;
12761276

1277-
/* PEBS v3 has accurate status bits */
1277+
pebs_status = p->status & cpuc->pebs_enabled;
1278+
pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
1279+
1280+
/* PEBS v3 has more accurate status bits */
12781281
if (x86_pmu.intel_cap.pebs_format >= 3) {
1279-
for_each_set_bit(bit, (unsigned long *)&p->status,
1280-
MAX_PEBS_EVENTS)
1282+
for_each_set_bit(bit, (unsigned long *)&pebs_status,
1283+
x86_pmu.max_pebs_events)
12811284
counts[bit]++;
12821285

12831286
continue;
12841287
}
12851288

1286-
pebs_status = p->status & cpuc->pebs_enabled;
1287-
pebs_status &= (1ULL << x86_pmu.max_pebs_events) - 1;
1288-
12891289
/*
12901290
* On some CPUs the PEBS status can be zero when PEBS is
12911291
* racing with clearing of GLOBAL_STATUS.
@@ -1333,8 +1333,11 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
13331333
continue;
13341334

13351335
event = cpuc->events[bit];
1336-
WARN_ON_ONCE(!event);
1337-
WARN_ON_ONCE(!event->attr.precise_ip);
1336+
if (WARN_ON_ONCE(!event))
1337+
continue;
1338+
1339+
if (WARN_ON_ONCE(!event->attr.precise_ip))
1340+
continue;
13381341

13391342
/* log dropped samples number */
13401343
if (error[bit])

0 commit comments

Comments
 (0)