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

Commit d3617b98 authored by Andi Kleen's avatar Andi Kleen Committed by Ingo Molnar
Browse files

perf/x86/lbr: Avoid reading the LBRs when adaptive PEBS handles them



With adaptive PEBS the CPU can directly supply the LBR information,
so we don't need to read it again. But the LBRs still need to be
enabled. Add a special count to the cpuc that distinguishes these
two cases, and avoid reading the LBRs unnecessarily when PEBS is
active.

Signed-off-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Cc: acme@kernel.org
Cc: jolsa@kernel.org
Link: https://lkml.kernel.org/r/20190402194509.2832-7-kan.liang@linux.intel.com


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent c22497f5
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
@@ -488,6 +488,8 @@ void intel_pmu_lbr_add(struct perf_event *event)
	 * be 'new'. Conversely, a new event can get installed through the
	 * context switch path for the first time.
	 */
	if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip > 0)
		cpuc->lbr_pebs_users++;
	perf_sched_cb_inc(event->ctx->pmu);
	if (!cpuc->lbr_users++ && !event->total_time_running)
		intel_pmu_lbr_reset();
@@ -507,8 +509,11 @@ void intel_pmu_lbr_del(struct perf_event *event)
		task_ctx->lbr_callstack_users--;
	}

	if (x86_pmu.intel_cap.pebs_baseline && event->attr.precise_ip > 0)
		cpuc->lbr_pebs_users--;
	cpuc->lbr_users--;
	WARN_ON_ONCE(cpuc->lbr_users < 0);
	WARN_ON_ONCE(cpuc->lbr_pebs_users < 0);
	perf_sched_cb_dec(event->ctx->pmu);
}

@@ -658,7 +663,13 @@ void intel_pmu_lbr_read(void)
{
	struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

	if (!cpuc->lbr_users)
	/*
	 * Don't read when all LBRs users are using adaptive PEBS.
	 *
	 * This could be smarter and actually check the event,
	 * but this simple approach seems to work for now.
	 */
	if (!cpuc->lbr_users || cpuc->lbr_users == cpuc->lbr_pebs_users)
		return;

	if (x86_pmu.intel_cap.lbr_format == LBR_FORMAT_32)
+1 −0
Original line number Diff line number Diff line
@@ -233,6 +233,7 @@ struct cpu_hw_events {
	 * Intel LBR bits
	 */
	int				lbr_users;
	int				lbr_pebs_users;
	struct perf_branch_stack	lbr_stack;
	struct perf_branch_entry	lbr_entries[MAX_LBR_ENTRIES];
	struct er_account		*lbr_sel;