From: Julien Thierry <julien.thie...@arm.com>

perf_event_overflow() can queue an irq_work on the current PE, which is
executed via an IPI. Move the processing of the irq_work from the PMU IRQ
handler to the IPI handler, which gets executed immediately afterwards.

This also makes the IRQ handler NMI safe, because it removes the call to
irq_work_run().

Cc: Julien Thierry <julien.thierry.k...@gmail.com>
Cc: Will Deacon <will.dea...@arm.com>
Cc: Mark Rutland <mark.rutl...@arm.com>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Ingo Molnar <mi...@redhat.com>
Cc: Arnaldo Carvalho de Melo <a...@kernel.org>
Cc: Alexander Shishkin <alexander.shish...@linux.intel.com>
Cc: Jiri Olsa <jo...@redhat.com>
Cc: Namhyung Kim <namhy...@kernel.org>
Cc: Catalin Marinas <catalin.mari...@arm.com>
Signed-off-by: Julien Thierry <julien.thie...@arm.com>
[Reworded commit]
Signed-off-by: Alexandru Elisei <alexandru.eli...@arm.com>
---
 arch/arm64/kernel/perf_event.c | 14 +++++---------
 1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/arm64/kernel/perf_event.c b/arch/arm64/kernel/perf_event.c
index a6195022be7d..cf1d92030790 100644
--- a/arch/arm64/kernel/perf_event.c
+++ b/arch/arm64/kernel/perf_event.c
@@ -750,20 +750,16 @@ static irqreturn_t armv8pmu_handle_irq(struct arm_pmu 
*cpu_pmu)
                if (!armpmu_event_set_period(event))
                        continue;
 
+               /*
+                * Perf event overflow will queue the processing of the event as
+                * an irq_work which will be taken care of in the handling of
+                * IPI_IRQ_WORK.
+                */
                if (perf_event_overflow(event, &data, regs))
                        cpu_pmu->disable(event);
        }
        armv8pmu_start(cpu_pmu);
 
-       /*
-        * Handle the pending perf events.
-        *
-        * Note: this call *must* be run with interrupts disabled. For
-        * platforms that can have the PMU interrupts raised as an NMI, this
-        * will not work.
-        */
-       irq_work_run();
-
        return IRQ_HANDLED;
 }
 
-- 
2.27.0

Reply via email to