[linux-yocto] [PATCH 1/2] arm/perf: run irq-work under softirq context in rt

Xufeng Zhang xufeng.zhang at windriver.com
Wed Apr 24 01:00:30 PDT 2013


ARM PMU interrupt is not threaded and we run all handlers with interrupts
disabled, but irq_work_run() would be called at the end of the interrupt
handler, so below warning would be triggered by the sleeppable spin_lock
when run 'perf top' command:
BUG: sleeping function called from invalid context at linux/kernel/rtmutex.c:658
in_atomic(): 1, irqs_disabled(): 128, pid: 1731, name: perf
[<80017d6c>] (unwind_backtrace+0x0/0x104) from [<806416c4>] (dump_stack+0x20/0x24)
[<806416c4>] (dump_stack+0x20/0x24) from [<80061208>] (__might_sleep+0xf4/0x108)
[<80061208>] (__might_sleep+0xf4/0x108) from [<8064a74c>] (rt_spin_lock+0x2c/0x38)
[<8064a74c>] (rt_spin_lock+0x2c/0x38) from [<800642e8>] (__wake_up+0x34/0x60)
[<800642e8>] (__wake_up+0x34/0x60) from [<800e2610>] (perf_event_wakeup+0x40/0x84)
[<800e2610>] (perf_event_wakeup+0x40/0x84) from [<800e2690>] (perf_pending_event+0x3c/0x60)
[<800e2690>] (perf_pending_event+0x3c/0x60) from [<800dd36c>] (irq_work_run+0x74/0xa4)
[<800dd36c>] (irq_work_run+0x74/0xa4) from [<8001b018>] (armv7pmu_handle_irq+0x12c/0x19c)
[<8001b018>] (armv7pmu_handle_irq+0x12c/0x19c) from [<800a87b0>] (handle_irq_event_percpu+0xf0/0x438)
[<800a87b0>] (handle_irq_event_percpu+0xf0/0x438) from [<800a8b70>] (handle_irq_event+0x78/0xa0)
[<800a8b70>] (handle_irq_event+0x78/0xa0) from [<800abdac>] (handle_fasteoi_irq+0xd4/0x18c)
[<800abdac>] (handle_fasteoi_irq+0xd4/0x18c) from [<800a7e70>] (generic_handle_irq+0x40/0x50)
[<800a7e70>] (generic_handle_irq+0x40/0x50) from [<8000f7a4>] (handle_IRQ+0x68/0xbc)
[<8000f7a4>] (handle_IRQ+0x68/0xbc) from [<800084e8>] (gic_handle_irq+0x38/0x68)
[<800084e8>] (gic_handle_irq+0x38/0x68) from [<8064b100>] (__irq_svc+0x40/0x70)

Inspired by upstream(git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-stable-rt.git)
commit 8baf86762 "x86-no-perf-irq-work-rt.patch", we can run the irq-work under softirq
context in rt kernel to resolve this problem.

Signed-off-by: Xufeng Zhang <xufeng.zhang at windriver.com>
---
 arch/arm/kernel/perf_event_v6.c     |    2 ++
 arch/arm/kernel/perf_event_v7.c     |    2 ++
 arch/arm/kernel/perf_event_xscale.c |    4 ++++
 3 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/arm/kernel/perf_event_v6.c b/arch/arm/kernel/perf_event_v6.c
index b78af0c..b432a65 100644
--- a/arch/arm/kernel/perf_event_v6.c
+++ b/arch/arm/kernel/perf_event_v6.c
@@ -524,7 +524,9 @@ armv6pmu_handle_irq(int irq_num,
 	 * platforms that can have the PMU interrupts raised as an NMI, this
 	 * will not work.
 	 */
+#ifndef CONFIG_PREEMPT_RT_FULL
 	irq_work_run();
+#endif
 
 	return IRQ_HANDLED;
 }
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 00755d8..4331eab 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -1112,7 +1112,9 @@ static irqreturn_t armv7pmu_handle_irq(int irq_num, void *dev)
 	 * platforms that can have the PMU interrupts raised as an NMI, this
 	 * will not work.
 	 */
+#ifndef CONFIG_PREEMPT_RT_FULL
 	irq_work_run();
+#endif
 
 	return IRQ_HANDLED;
 }
diff --git a/arch/arm/kernel/perf_event_xscale.c b/arch/arm/kernel/perf_event_xscale.c
index 71a21e6..9bb9a0f 100644
--- a/arch/arm/kernel/perf_event_xscale.c
+++ b/arch/arm/kernel/perf_event_xscale.c
@@ -271,7 +271,9 @@ xscale1pmu_handle_irq(int irq_num, void *dev)
 			cpu_pmu->disable(hwc, idx);
 	}
 
+#ifndef CONFIG_PREEMPT_RT_FULL
 	irq_work_run();
+#endif
 
 	/*
 	 * Re-enable the PMU.
@@ -611,7 +613,9 @@ xscale2pmu_handle_irq(int irq_num, void *dev)
 			cpu_pmu->disable(hwc, idx);
 	}
 
+#ifndef CONFIG_PREEMPT_RT_FULL
 	irq_work_run();
+#endif
 
 	/*
 	 * Re-enable the PMU.
-- 
1.7.1




More information about the linux-yocto mailing list