Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 12ab854d authored by Peter Zijlstra's avatar Peter Zijlstra Committed by Ingo Molnar
Browse files

perf, x86: Deal with multiple state bits for pebs-fmt1



Its unclear if the PEBS state record will have only a single bit set, in
case it does not and accumulates bits, deal with that by only processing
each event once.

Also, robustify some of the code.

Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@infradead.org>
Cc: paulus@samba.org
Cc: eranian@google.com
Cc: robert.richter@amd.com
Cc: fweisbec@gmail.com
LKML-Reference: <new-submission>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent d329527e
Loading
Loading
Loading
Loading
+13 −3
Original line number Original line Diff line number Diff line
@@ -538,6 +538,7 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)
	struct perf_event *event = NULL;
	struct perf_event *event = NULL;
	struct perf_raw_record raw;
	struct perf_raw_record raw;
	struct pt_regs regs;
	struct pt_regs regs;
	u64 status = 0;
	int bit, n;
	int bit, n;


	if (!ds || !x86_pmu.pebs)
	if (!ds || !x86_pmu.pebs)
@@ -561,13 +562,22 @@ static void intel_pmu_drain_pebs_nhm(struct pt_regs *iregs)


	for ( ; at < top; at++) {
	for ( ; at < top; at++) {
		for_each_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) {
		for_each_bit(bit, (unsigned long *)&at->status, MAX_PEBS_EVENTS) {
			if (!cpuc->events[bit]->attr.precise)
			event = cpuc->events[bit];
			if (!test_bit(bit, cpuc->active_mask))
				continue;
				continue;


			event = cpuc->events[bit];
			WARN_ON_ONCE(!event);

			if (!event->attr.precise)
				continue;

			if (__test_and_set_bit(bit, (unsigned long *)&status))
				continue;

			break;
		}
		}


		if (!event)
		if (!event || bit >= MAX_PEBS_EVENTS)
			continue;
			continue;


		if (!intel_pmu_save_and_restart(event))
		if (!intel_pmu_save_and_restart(event))