linux/arch/arm64/kernel
Mark Rutland 61d0386273 arm_pmu: fix event CPU filtering
Janne reports that perf has been broken on Apple M1 as of commit:

  bd27568117 ("perf: Rewrite core context handling")

That commit replaced the pmu::filter_match() callback with
pmu::filter(), whose return value has the opposite polarity, with true
implying events should be ignored rather than scheduled. While an
attempt was made to update the logic in armv8pmu_filter() and
armpmu_filter() accordingly, the return value remains inverted in a
couple of cases:

* If the arm_pmu does not have an arm_pmu::filter() callback,
  armpmu_filter() will always return whether the CPU is supported rather
  than whether the CPU is not supported.

  As a result, the perf core will not schedule events on supported CPUs,
  resulting in a loss of events. Additionally, the perf core will
  attempt to schedule events on unsupported CPUs, but this will be
  rejected by armpmu_add(), which may result in a loss of events from
  other PMUs on those unsupported CPUs.

* If the arm_pmu does have an arm_pmu::filter() callback, and
  armpmu_filter() is called on a CPU which is not supported by the
  arm_pmu, armpmu_filter() will return false rather than true.

  As a result, the perf core will attempt to schedule events on
  unsupported CPUs, but this will be rejected by armpmu_add(), which may
  result in a loss of events from other PMUs on those unsupported CPUs.

This means a loss of events can be seen with any arm_pmu driver, but
with the ARMv8 PMUv3 driver (which is the only arm_pmu driver with an
arm_pmu::filter() callback) the event loss will be more limited and may
go unnoticed, which is how this issue evaded testing so far.

Fix the CPU filtering by performing this consistently in
armpmu_filter(), and remove the redundant arm_pmu::filter() callback and
armv8pmu_filter() implementation.

Commit bd27568117 also silently removed the CHAIN event filtering from
armv8pmu_filter(), which will be addressed by a separate patch without
using the filter callback.

Fixes: bd27568117 ("perf: Rewrite core context handling")
Reported-by: Janne Grunau <j@jannau.net>
Link: https://lore.kernel.org/asahi/20230215-arm_pmu_m1_regression-v1-1-f5a266577c8d@jannau.net/
Signed-off-by: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Asahi Lina <lina@asahilina.net>
Cc: Eric Curtin <ecurtin@redhat.com>
Tested-by: Janne Grunau <j@jannau.net>
Link: https://lore.kernel.org/r/20230216141240.3833272-2-mark.rutland@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
2023-02-16 21:23:52 +00:00
..
pi arm64: unwind: add asynchronous unwind tables to kernel and modules 2022-11-09 18:06:35 +00:00
probes Merge branch 'for-next/kprobes' into for-next/core 2022-12-06 11:20:21 +00:00
vdso kbuild: upgrade the orphan section warning to an error if CONFIG_WERROR is set 2022-11-01 10:04:52 -07:00
vdso32 kbuild: upgrade the orphan section warning to an error if CONFIG_WERROR is set 2022-11-01 10:04:52 -07:00
.gitignore
acpi_numa.c
acpi_parking_protocol.c treewide: Drop function_nocfi 2022-09-26 10:13:14 -07:00
acpi.c arm64: Add architecture specific ACPI FFH Opregion callbacks 2022-11-14 19:09:07 +01:00
alternative.c arm64: alternatives: add __init/__initconst to some functions/variables 2022-12-05 13:47:06 +00:00
armv8_deprecated.c arm64: armv8_deprecated: fix unused-function error 2022-11-25 12:16:22 +00:00
asm-offsets.c ftrace: arm64: move from REGS to ARGS 2022-11-18 13:56:41 +00:00
cacheinfo.c
compat_alignment.c
cpu_errata.c arm64: errata: Workaround possible Cortex-A715 [ESR|FAR]_ELx corruption 2023-01-06 17:14:55 +00:00
cpu_ops.c
cpu-reset.S
cpufeature.c ARM64: 2022-12-15 11:12:21 -08:00
cpuidle.c
cpuinfo.c arm64/hwcap: Add support for SVE 2.1 2022-11-09 17:54:53 +00:00
crash_core.c
crash_dump.c
debug-monitors.c
efi-header.S
efi-rt-wrapper.S arm64: efi: Recover from synchronous exceptions occurring in firmware 2022-12-08 18:33:34 +01:00
efi.c arm64: efi: Recover from synchronous exceptions occurring in firmware 2022-12-08 18:33:34 +01:00
elfcore.c arm64: mte: Avoid the racy walk of the vma list during core dump 2023-01-05 15:12:12 +00:00
entry-common.c Merge branch 'for-next/undef-traps' into for-next/core 2022-12-06 11:34:25 +00:00
entry-fpsimd.S
entry-ftrace.S arm64 updates for 6.2 2022-12-12 09:50:05 -08:00
entry.S arm64: Enable data independent timing (DIT) in the kernel 2022-11-08 14:55:10 +00:00
fpsimd.c arm64/sme: Fix context switch for SME only systems 2023-01-05 15:31:18 +00:00
ftrace.c ftrace: arm64: remove static ftrace 2022-11-25 12:11:50 +00:00
head.S arm64: implement dynamic shadow call stack for Clang 2022-11-09 18:06:35 +00:00
hibernate-asm.S
hibernate.c arm64: mte: Fix/clarify the PG_mte_tagged semantics 2022-11-29 09:26:07 +00:00
hw_breakpoint.c
hyp-stub.S
idle.c
idreg-override.c
image-vars.h ARM64: 2022-12-15 11:12:21 -08:00
image.h
io.c
irq.c Merge branch 'for-next/stacks' into for-next/core 2022-12-06 11:26:40 +00:00
jump_label.c
kaslr.c
kexec_image.c
kgdb.c
kuser32.S
machine_kexec_file.c
machine_kexec.c treewide: Drop function_nocfi 2022-09-26 10:13:14 -07:00
Makefile EFI updates for v6.2: 2022-12-13 14:31:47 -08:00
module-plts.c arm64: module: Make plt_equals_entry() static 2022-09-29 17:47:18 +01:00
module.c Merge branch 'for-next/ftrace' into for-next/core 2022-12-06 11:07:39 +00:00
mte.c arm64: mte: Lock a page for MTE tag initialisation 2022-11-29 09:26:07 +00:00
paravirt.c arm64: paravirt: remove conduit check in has_pv_steal_clock 2022-11-09 18:11:56 +00:00
patch-scs.c arm64: implement dynamic shadow call stack for Clang 2022-11-09 18:06:35 +00:00
patching.c
pci.c
perf_callchain.c
perf_event.c arm_pmu: fix event CPU filtering 2023-02-16 21:23:52 +00:00
perf_regs.c
pointer_auth.c
process.c Random number generator updates for Linux 6.2-rc1. 2022-12-12 16:22:22 -08:00
proton-pack.c arm64: factor out EL1 SSBS emulation hook 2022-11-15 13:46:18 +00:00
psci.c treewide: Drop function_nocfi 2022-09-26 10:13:14 -07:00
ptrace.c arm64: ptrace: Use ARM64_SME to guard the SME register enumerations 2023-01-05 15:08:31 +00:00
reloc_test_core.c ARM64: reloc_test: add __init/__exit annotations to module init/exit funcs 2022-09-29 18:04:25 +01:00
reloc_test_syms.S
relocate_kernel.S
return_address.c
sdei.c arm64: implement dynamic shadow call stack for Clang 2022-11-09 18:06:35 +00:00
setup.c arm64: implement dynamic shadow call stack for Clang 2022-11-09 18:06:35 +00:00
signal32.c
signal.c arm64/signal: Always allocate SVE signal frames on SME only systems 2023-01-05 15:31:18 +00:00
sigreturn32.S
sleep.S
smccc-call.S
smp_spin_table.c treewide: Drop function_nocfi 2022-09-26 10:13:14 -07:00
smp.c
stacktrace.c arm64: Prohibit instrumentation on arch_stack_walk() 2022-12-05 14:20:08 +00:00
suspend.c arm64: Enable data independent timing (DIT) in the kernel 2022-11-08 14:55:10 +00:00
sys32.c
sys_compat.c
sys.c
syscall.c arm64/sve: Leave SVE enabled on syscall if we don't context switch 2022-11-29 15:01:56 +00:00
time.c
topology.c RISC-V Patches for the 6.1 Merge Window, Part 1 2022-10-09 13:24:01 -07:00
trace-events-emulation.h
traps.c arm64: armv8_deprecated: rework deprected instruction handling 2022-11-15 13:46:19 +00:00
vdso32-wrap.S
vdso-wrap.S
vdso.c vdso/timens: Refactor copy-pasted find_timens_vvar_page() helper into one copy 2022-12-01 11:35:40 +01:00
vmlinux.lds.S arm64: unwind: add asynchronous unwind tables to kernel and modules 2022-11-09 18:06:35 +00:00