[PATCH v2 0/9] arm_pmu: Use NMI for perf interrupt

Julien Thierry julien.thierry at arm.com
Fri Mar 22 09:23:55 PDT 2019


On arm64, perf reports that counter overflow very often (too often)
happen in function that potentially enabled interrutps:

$ perf record -a -- sleep 60; perf report -F overhead,symbol
# Overhead  Symbol
# ........  ..........................................
     6.58%  [k] _raw_spin_unlock_irq
     6.10%  [k] _raw_spin_unlock_irqrestore
     5.52%  [k] ___bpf_prog_run
     4.37%  [k] el0_svc_common
     2.58%  [k] arch_cpu_idle
     2.39%  [k] kmem_cache_alloc
     2.06%  [k] __seccomp_filter

The root issue is, if an overflow happens while executing with
interrupts disabled, the perf event will only be handled when interrupts
are reenabled (i.e. when the PMU interrupt is taken). The result being
the event being reported at the interrupt enabling location rather than
where the overflow actually happened.

Now that we have support for pseudo-NMI on arm64 with GICv3, we can use
it to improve the profiling done using the PMU interrupt.

With these changes, on the same machine, we get:
# Overhead  Symbol
# ........  ..................................
     7.06%  [k] ___bpf_prog_run
     4.08%  [k] __update_load_avg_se
     4.02%  [k] ktime_get_ts64
     3.77%  [k] __ll_sc_arch_atomic_add_return
     3.71%  [k] file_ra_state_init
     3.62%  [k] __ll_sc_arch_atomic64_sub
     3.53%  [k] __ll_sc___cmpxchg_case_acq_32

_raw_spin_unlock_irq/irqrestore don't event appear anymore in the
perf trace.

* Patches 1 to 4 remove the need to use spinlocks for the Arm PMU
  driver for Armv7 and Armv8 (aarch64).
* Patches 5 moves the locking to Armv6 specific code which is the sole
* Patches 6 and 7 make the PMU interrupt handler NMI-safe
* Patches 8 and 9 enable using pseudo-NMI for the PMU interrupt when
  the feature is available

Changes since v1[1]:
- Rebased on v5.1-rc1
- Pseudo-NMI has changed a lot since then, use the (now merged) NMI API
- Remove locking from armv7 perf_event
- Use locking only in armv6 perf_event
- Use direct counter/type registers insted of selector register for armv8

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2018-January/554611.html




Julien Thierry (8):
  arm64: perf: Remove PMU locking
  arm: perf: save/resore pmsel
  arm: perf: Remove Remove PMU locking
  perf/arm_pmu: Move PMU lock to ARMv6 events
  arm64: perf: Do not call irq_work_run in NMI context
  arm/arm64: kvm: pmu: Make overflow handler NMI safe
  arm_pmu: Introduce pmu_irq_ops
  arm_pmu: Use NMIs for PMU

Mark Rutland (1):
  arm64: perf: avoid PMXEV* indirection

 arch/arm/kernel/perf_event_v6.c |  26 +++++---
 arch/arm/kernel/perf_event_v7.c |  77 +++++++---------------
 arch/arm64/kernel/perf_event.c  | 122 ++++++++++++++++++++++------------
 drivers/perf/arm_pmu.c          | 143 ++++++++++++++++++++++++++++++++++------
 include/kvm/arm_pmu.h           |   1 +
 include/linux/perf/arm_pmu.h    |   5 --
 virt/kvm/arm/pmu.c              |  37 +++++++++--
 7 files changed, 277 insertions(+), 134 deletions(-)


More information about the linux-arm-kernel mailing list