mbox series

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

Message ID 1553271844-49003-1-git-send-email-julien.thierry@arm.com (mailing list archive)
Headers show
Series arm_pmu: Use NMI for perf interrupt | expand

Message

Julien Thierry March 22, 2019, 4:23 p.m. UTC
Hi,

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
  user
* 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

Cheers,

Julien

-->

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(-)

--
1.9.1

Comments

Peter Zijlstra March 22, 2019, 4:49 p.m. UTC | #1
On Fri, Mar 22, 2019 at 04:23:55PM +0000, Julien Thierry wrote:
> Hi,
> 
> 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.

Very nice; I've little useful to say about the patches themselves, they
appear ok, but this is not code I know well. But it is good to see perf
becoming more useful on arm64.