Commit c2b98a86 authored by Alexey Budankov's avatar Alexey Budankov Committed by Ingo Molnar
Browse files

perf/x86: Synchronize PMU task contexts on optimized context switches



Install Intel specific PMU task context synchronization adapter and
extend optimized context switch path with PMU specific task context
synchronization to fix LBR callstack virtualization on context switches.

Signed-off-by: default avatarAlexey Budankov <alexey.budankov@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@kernel.org>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Song Liu <songliubraving@fb.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Vince Weaver <vincent.weaver@maine.edu>
Link: https://lkml.kernel.org/r/9c6445a9-bdba-ef03-3859-f1f91198f27a@linux.intel.com


Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
parent 421ca868
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -3820,6 +3820,12 @@ static void intel_pmu_sched_task(struct perf_event_context *ctx,
	intel_pmu_lbr_sched_task(ctx, sched_in);
}

static void intel_pmu_swap_task_ctx(struct perf_event_context *prev,
				    struct perf_event_context *next)
{
	intel_pmu_lbr_swap_task_ctx(prev, next);
}

static int intel_pmu_check_period(struct perf_event *event, u64 value)
{
	return intel_pmu_has_bts_period(event, value) ? -EINVAL : 0;
@@ -3955,6 +3961,7 @@ static __initconst const struct x86_pmu intel_pmu = {

	.guest_get_msrs		= intel_guest_get_msrs,
	.sched_task		= intel_pmu_sched_task,
	.swap_task_ctx		= intel_pmu_swap_task_ctx,

	.check_period		= intel_pmu_check_period,

+12 −1
Original line number Diff line number Diff line
@@ -3204,9 +3204,20 @@ static void perf_event_context_sched_out(struct task_struct *task, int ctxn,
		raw_spin_lock(&ctx->lock);
		raw_spin_lock_nested(&next_ctx->lock, SINGLE_DEPTH_NESTING);
		if (context_equiv(ctx, next_ctx)) {
			struct pmu *pmu = ctx->pmu;

			WRITE_ONCE(ctx->task, next);
			WRITE_ONCE(next_ctx->task, task);

			/*
			 * PMU specific parts of task perf context can require
			 * additional synchronization. As an example of such
			 * synchronization see implementation details of Intel
			 * LBR call stack data profiling;
			 */
			if (pmu->swap_task_ctx)
				pmu->swap_task_ctx(ctx, next_ctx);
			else
				swap(ctx->task_ctx_data, next_ctx->task_ctx_data);

			/*