Skip to content

Commit 6ebb681

Browse files
committed
Merge tag 'perf-urgent-2021-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Thomas Gleixner: "Two perf fixes: - Do not check the LBR_TOS MSR when setting up unrelated LBR MSRs as this can cause malfunction when TOS is not supported - Allocate the LBR XSAVE buffers along with the DS buffers upfront because allocating them when adding an event can deadlock" * tag 'perf-urgent-2021-05-23' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/x86/lbr: Remove cpuc->lbr_xsave allocation from atomic context perf/x86: Avoid touching LBR_TOS MSR for Arch LBR
2 parents 0898678 + 488e13a commit 6ebb681

File tree

4 files changed

+31
-9
lines changed

4 files changed

+31
-9
lines changed

arch/x86/events/core.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,12 @@ int x86_reserve_hardware(void)
396396
if (!atomic_inc_not_zero(&pmc_refcount)) {
397397
mutex_lock(&pmc_reserve_mutex);
398398
if (atomic_read(&pmc_refcount) == 0) {
399-
if (!reserve_pmc_hardware())
399+
if (!reserve_pmc_hardware()) {
400400
err = -EBUSY;
401-
else
401+
} else {
402402
reserve_ds_buffers();
403+
reserve_lbr_buffers();
404+
}
403405
}
404406
if (!err)
405407
atomic_inc(&pmc_refcount);

arch/x86/events/intel/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6253,7 +6253,7 @@ __init int intel_pmu_init(void)
62536253
* Check all LBT MSR here.
62546254
* Disable LBR access if any LBR MSRs can not be accessed.
62556255
*/
6256-
if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
6256+
if (x86_pmu.lbr_tos && !check_msr(x86_pmu.lbr_tos, 0x3UL))
62576257
x86_pmu.lbr_nr = 0;
62586258
for (i = 0; i < x86_pmu.lbr_nr; i++) {
62596259
if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&

arch/x86/events/intel/lbr.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,6 @@ static inline bool branch_user_callstack(unsigned br_sel)
658658

659659
void intel_pmu_lbr_add(struct perf_event *event)
660660
{
661-
struct kmem_cache *kmem_cache = event->pmu->task_ctx_cache;
662661
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
663662

664663
if (!x86_pmu.lbr_nr)
@@ -696,11 +695,6 @@ void intel_pmu_lbr_add(struct perf_event *event)
696695
perf_sched_cb_inc(event->ctx->pmu);
697696
if (!cpuc->lbr_users++ && !event->total_time_running)
698697
intel_pmu_lbr_reset();
699-
700-
if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
701-
kmem_cache && !cpuc->lbr_xsave &&
702-
(cpuc->lbr_users != cpuc->lbr_pebs_users))
703-
cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, GFP_KERNEL);
704698
}
705699

706700
void release_lbr_buffers(void)
@@ -722,6 +716,26 @@ void release_lbr_buffers(void)
722716
}
723717
}
724718

719+
void reserve_lbr_buffers(void)
720+
{
721+
struct kmem_cache *kmem_cache;
722+
struct cpu_hw_events *cpuc;
723+
int cpu;
724+
725+
if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
726+
return;
727+
728+
for_each_possible_cpu(cpu) {
729+
cpuc = per_cpu_ptr(&cpu_hw_events, cpu);
730+
kmem_cache = x86_get_pmu(cpu)->task_ctx_cache;
731+
if (!kmem_cache || cpuc->lbr_xsave)
732+
continue;
733+
734+
cpuc->lbr_xsave = kmem_cache_alloc_node(kmem_cache, GFP_KERNEL,
735+
cpu_to_node(cpu));
736+
}
737+
}
738+
725739
void intel_pmu_lbr_del(struct perf_event *event)
726740
{
727741
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

arch/x86/events/perf_event.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,6 +1244,8 @@ void reserve_ds_buffers(void);
12441244

12451245
void release_lbr_buffers(void);
12461246

1247+
void reserve_lbr_buffers(void);
1248+
12471249
extern struct event_constraint bts_constraint;
12481250
extern struct event_constraint vlbr_constraint;
12491251

@@ -1393,6 +1395,10 @@ static inline void release_lbr_buffers(void)
13931395
{
13941396
}
13951397

1398+
static inline void reserve_lbr_buffers(void)
1399+
{
1400+
}
1401+
13961402
static inline int intel_pmu_init(void)
13971403
{
13981404
return 0;

0 commit comments

Comments
 (0)