perf/core: Fix risky smp_processor_id() usage in perf_event_read_local()

There's no requirement that perf_event_read_local() be used from a
context where CPU migration isn't possible, yet smp_processor_id() is
used with the assumption that the caller guarantees CPU migration can't
occur. Since IRQs are disabled here anyway, the smp_processor_id() can
simply be moved to the IRQ-disabled section to guarantee its safety.

Signed-off-by: Sultan Alsawaf <sultan@kerneltoast.com>
This commit is contained in:
Sultan Alsawaf 2021-10-20 20:50:45 -07:00 committed by spakkkk
parent e06cdf4ce5
commit 3e0eb86439

View File

@ -4006,8 +4006,8 @@ int perf_event_read_local(struct perf_event *event, u64 *value,
{
unsigned long flags;
int ret = 0;
int local_cpu = smp_processor_id();
bool readable = cpumask_test_cpu(local_cpu, &event->readable_on_cpus);
int local_cpu;
bool readable;
/*
* Disabling interrupts avoids all counter scheduling (context
* switches, timer based rotation and IPIs).
@ -4031,6 +4031,8 @@ int perf_event_read_local(struct perf_event *event, u64 *value,
}
/* If this is a per-CPU event, it must be for this CPU */
local_cpu = raw_smp_processor_id();
readable = cpumask_test_cpu(local_cpu, &event->readable_on_cpus);
if (!(event->attach_state & PERF_ATTACH_TASK) &&
event->cpu != local_cpu &&
!readable) {