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.
 -----BEGIN PGP SIGNATURE-----
 
 iQJHBAABCgAxFiEEQp8+kY+LLUocC4bMphj1TA10mKEFAmCqWZQTHHRnbHhAbGlu
 dXRyb25peC5kZQAKCRCmGPVMDXSYoZe6D/9vKZRfmbdvOwfE0Z7dBil2dyBoqYHw
 yTfnGs0pNpmj2mY7ZPig3gmXnryt4cwMcTtVJZFdmYJBBS28tqGeJb7eMIxtSqAu
 aBChANXVOnbAS8vXe555nS/BVxEtfkIBgOLyYlD0hE4PIZpBbqTzhxj4daLTk4bg
 h4hyIzDMBs+4tLupVhOahg6ZaHd97S61e7gBR9I5D7tHAUMo8Ea0ChQD5p2kDYI5
 leKroBnjUFMP0o2DYPUR+6Zma50JQ29QK1u34q4mx0IhIdgqtNs8eZE/kYUu2FSZ
 Nf4GG2ALzxWjXniqRPrXbkP/ScrwVdhg7ULOG34aNT1Jx04KaMSkav93gbOdozV9
 IYvf99zwptD3g9W4yDveWjGrhEoxiARI4VUQJBnIbQP9rZ2YIRwOHIXwux1AxWQh
 ok6CP94m16AWp0wbm9HRJS80MUv1zHPK5oW3B1vkchxHihkV4XdoP6vny03Z2FcC
 elMgFquDxP4l5i3ao0Ryn4YaCAFc3MiWvw3x4YXpv9dCE6Al+iKdclkYPJgrYWYE
 wUN8jdODfIyBIOI94GnwYl5rHIoS2fH8LSpP36gIX7DMKPh5y7184jUQWjHTN6PT
 /D94us3m8Cvq+sfZrhGDHPY4BEaYeczTo6vbVoN4iBthElLYRkHp7lc7gcDpsU8B
 dzHcwyMFQAnKLQ==
 =7WGT
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2021-05-23 06:32:40 -10:00
commit 6ebb6814a1
4 changed files with 31 additions and 9 deletions

View File

@ -396,10 +396,12 @@ int x86_reserve_hardware(void)
if (!atomic_inc_not_zero(&pmc_refcount)) {
mutex_lock(&pmc_reserve_mutex);
if (atomic_read(&pmc_refcount) == 0) {
if (!reserve_pmc_hardware())
if (!reserve_pmc_hardware()) {
err = -EBUSY;
else
} else {
reserve_ds_buffers();
reserve_lbr_buffers();
}
}
if (!err)
atomic_inc(&pmc_refcount);

View File

@ -6253,7 +6253,7 @@ __init int intel_pmu_init(void)
* Check all LBT MSR here.
* Disable LBR access if any LBR MSRs can not be accessed.
*/
if (x86_pmu.lbr_nr && !check_msr(x86_pmu.lbr_tos, 0x3UL))
if (x86_pmu.lbr_tos && !check_msr(x86_pmu.lbr_tos, 0x3UL))
x86_pmu.lbr_nr = 0;
for (i = 0; i < x86_pmu.lbr_nr; i++) {
if (!(check_msr(x86_pmu.lbr_from + i, 0xffffUL) &&

View File

@ -658,7 +658,6 @@ static inline bool branch_user_callstack(unsigned br_sel)
void intel_pmu_lbr_add(struct perf_event *event)
{
struct kmem_cache *kmem_cache = event->pmu->task_ctx_cache;
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
if (!x86_pmu.lbr_nr)
@ -696,11 +695,6 @@ void intel_pmu_lbr_add(struct perf_event *event)
perf_sched_cb_inc(event->ctx->pmu);
if (!cpuc->lbr_users++ && !event->total_time_running)
intel_pmu_lbr_reset();
if (static_cpu_has(X86_FEATURE_ARCH_LBR) &&
kmem_cache && !cpuc->lbr_xsave &&
(cpuc->lbr_users != cpuc->lbr_pebs_users))
cpuc->lbr_xsave = kmem_cache_alloc(kmem_cache, GFP_KERNEL);
}
void release_lbr_buffers(void)
@ -722,6 +716,26 @@ void release_lbr_buffers(void)
}
}
void reserve_lbr_buffers(void)
{
struct kmem_cache *kmem_cache;
struct cpu_hw_events *cpuc;
int cpu;
if (!static_cpu_has(X86_FEATURE_ARCH_LBR))
return;
for_each_possible_cpu(cpu) {
cpuc = per_cpu_ptr(&cpu_hw_events, cpu);
kmem_cache = x86_get_pmu(cpu)->task_ctx_cache;
if (!kmem_cache || cpuc->lbr_xsave)
continue;
cpuc->lbr_xsave = kmem_cache_alloc_node(kmem_cache, GFP_KERNEL,
cpu_to_node(cpu));
}
}
void intel_pmu_lbr_del(struct perf_event *event)
{
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);

View File

@ -1244,6 +1244,8 @@ void reserve_ds_buffers(void);
void release_lbr_buffers(void);
void reserve_lbr_buffers(void);
extern struct event_constraint bts_constraint;
extern struct event_constraint vlbr_constraint;
@ -1393,6 +1395,10 @@ static inline void release_lbr_buffers(void)
{
}
static inline void reserve_lbr_buffers(void)
{
}
static inline int intel_pmu_init(void)
{
return 0;