powerpc/perf: Invoke per-CPU variable access with disabled interrupts
PATCH 1/1 powerpc/perf: Invoke per-CPU variable access with disabled interrupts
The power_pmu_event_init() callback access per-cpu variable (cpu_hw_events) to check for event constraints and Branch Stack (BHRB). Current usage is to disable preemption when accessing the per-cpu variable, but this does not prevent timer callback from interrupting event_init. Fix this by using 'local_irq_save/restore' to make sure the code path is invoked with disabled interrupts.
This change is tested in mambo simulator to ensure that, if a timer interrupt comes in during the per-cpu access in event_init, it will be soft masked and replayed later. For testing purpose, introduced a udelay() in power_pmu_event_init() to make sure a timer interrupt arrives while in per-cpu variable access code between local_irq_save/resore. As expected the timer interrupt was replayed later during local_irq_restore called from power_pmu_event_init. This was confirmed by adding breakpoint in mambo and checking the backtrace when timer_interrupt was hit.
--- arch/powerpc/perf/core-book3s.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
arch/powerpc/perf/core-book3s.c +6 -4
@@ -1909,7 +1909,7 @@ static bool is_event_blacklisted(u64 ev)static int power_pmu_event_init (struct perf_event *event) {u64 ev; -unsigned long flags; +unsigned long flags, irq_flags;struct perf_event *ctrs[MAX_HWEVENTS ];u64 events[MAX_HWEVENTS ];unsigned int cflags[MAX_HWEVENTS ];
@@ -2017,7 +2017,9 @@ static int power_pmu_event_init(struct perf_event *event)if (check_excludes (ctrs, cflags, n,1 ))return -EINVAL ; - cpuhw = &get_cpu_var (cpu_hw_events); +local_irq_save (irq_flags); + cpuhw =this_cpu_ptr (&cpu_hw_events); + err =power_check_constraints (cpuhw, events, cflags, n +1 );if (has_branch_stack (event)) {
@@ -2028,13 +2030,13 @@ static int power_pmu_event_init(struct perf_event *event) event->attr.branch_sample_type);if (bhrb_filter ==-1 ) { -put_cpu_var (cpu_hw_events); +local_irq_restore (irq_flags);return -EOPNOTSUPP ; } cpuhw->bhrb_filter = bhrb_filter; } -put_cpu_var (cpu_hw_events); +local_irq_restore (irq_flags);if (err)return -EINVAL ;
Signature · 1 line
1.8.3.1
Michael Ellerman
AppliedQuoted 8 lines · Athira Rajeev
The
power_pmu_event_init()callback access per-cpu variable (cpu_hw_events) to check for event constraints and Branch Stack (BHRB). Current usage is to disable preemption when accessing the per-cpu variable, but this does not prevent timer callback from interruptingevent_init. Fix this by using 'local_irq_save/restore' to make sure the code path is invoked with disabled interrupts.[...]
Applied to powerpc/next.
[1/1] powerpc/perf: Invoke per-CPU variable access with disabled interrupts
https://git.kernel.org/powerpc/c/f66de7ac4849eb42a7b18e26b8ee49e08130fd27
cheers