Skip to content

Commit 421ca86

Browse files
Alexey BudankovIngo Molnar
authored andcommitted
perf/x86/intel: Implement LBR callstack context synchronization
Implement intel_pmu_lbr_swap_task_ctx() method updating counters of the events that requested LBR callstack data on a sample. The counter can be zero for the case when task context belongs to a thread that has just come from a block on a futex and the context contains saved (lbr_stack_state == LBR_VALID) LBR register values. For the values to be restored at LBR registers on the next thread's switch-in event it swaps the counter value with the one that is expected to be non zero at the previous equivalent task perf event context. Swap operation type ensures the previous task perf event context stays consistent with the amount of events that requested LBR callstack data on a sample. Signed-off-by: Alexey Budankov <[email protected]> Signed-off-by: Peter Zijlstra (Intel) <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Arnaldo Carvalho de Melo <[email protected]> Cc: Ian Rogers <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Kan Liang <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Song Liu <[email protected]> Cc: Stephane Eranian <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Vince Weaver <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ingo Molnar <[email protected]>
1 parent a443997 commit 421ca86

File tree

2 files changed

+26
-0
lines changed

2 files changed

+26
-0
lines changed

arch/x86/events/intel/lbr.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,29 @@ static void __intel_pmu_lbr_save(struct x86_perf_task_context *task_ctx)
417417
cpuc->last_log_id = ++task_ctx->log_id;
418418
}
419419

420+
void intel_pmu_lbr_swap_task_ctx(struct perf_event_context *prev,
421+
struct perf_event_context *next)
422+
{
423+
struct x86_perf_task_context *prev_ctx_data, *next_ctx_data;
424+
425+
swap(prev->task_ctx_data, next->task_ctx_data);
426+
427+
/*
428+
* Architecture specific synchronization makes sense in
429+
* case both prev->task_ctx_data and next->task_ctx_data
430+
* pointers are allocated.
431+
*/
432+
433+
prev_ctx_data = next->task_ctx_data;
434+
next_ctx_data = prev->task_ctx_data;
435+
436+
if (!prev_ctx_data || !next_ctx_data)
437+
return;
438+
439+
swap(prev_ctx_data->lbr_callstack_users,
440+
next_ctx_data->lbr_callstack_users);
441+
}
442+
420443
void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in)
421444
{
422445
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

arch/x86/events/perf_event.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,9 @@ void intel_pmu_store_pebs_lbrs(struct pebs_lbr *lbr);
10241024

10251025
void intel_ds_init(void);
10261026

1027+
void intel_pmu_lbr_swap_task_ctx(struct perf_event_context *prev,
1028+
struct perf_event_context *next);
1029+
10271030
void intel_pmu_lbr_sched_task(struct perf_event_context *ctx, bool sched_in);
10281031

10291032
u64 lbr_from_signext_quirk_wr(u64 val);

0 commit comments

Comments
 (0)