Skip to content

Commit 8eb0984

Browse files
committed
ARCv2: intc: Fix random perf irq disabling in SMP setup
As part of fixing another perf issue, observed that after a perf run, the interrupt got disabled on one/more cores. Turns out that despite requesting perf irq as percpu, the flow handler registered was not handle_percpu_irq() Given that on ARCv2 cores, IRQs < 24 are always private to cpu, we register the right handler at the very onset. Before Fix | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 0 0 0 0 ARCv2 core Intc 20 ARC perf counters | | [ARCLinux]# perf record -c 20000 /sbin/hackbench | Running with 10*40 (== 400) tasks. | | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 0 522 8 51916 ARCv2 core Intc 20 ARC perf counters | | [ARCLinux]# perf record -c 20000 /sbin/hackbench | Running with 10*40 (== 400) tasks. | | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 0 522 8 104368 ARCv2 core Intc 20 ARC perf counters After Fix | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 0 0 0 0 ARCv2 core Intc 20 ARC perf counters | | [ARCLinux]# perf record -c 20000 /sbin/hackbench | Running with 10*40 (== 400) tasks. | | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 64198 62012 62697 67803 ARCv2 core Intc 20 ARC perf counters | | [ARCLinux]# perf record -c 20000 /sbin/hackbench | Running with 10*40 (== 400) tasks. | | [ARCLinux]# cat /proc/interrupts | grep perf | 20: 126014 122792 123301 133654 ARCv2 core Intc 20 ARC perf counters Cc: Marc Zyngier <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Alexey Brodkin <[email protected]> Cc: [email protected] #4.2+ Cc: [email protected] Signed-off-by: Vineet Gupta <[email protected]>
1 parent 6d1a2ad commit 8eb0984

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

arch/arc/kernel/intc-arcv2.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
106106
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
107107
irq_hw_number_t hw)
108108
{
109-
if (irq == TIMER0_IRQ || irq == IPI_IRQ)
109+
/*
110+
* core intc IRQs [16, 23]:
111+
* Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
112+
*/
113+
if (hw < 24) {
114+
/*
115+
* A subsequent request_percpu_irq() fails if percpu_devid is
116+
* not set. That in turns sets NOAUTOEN, meaning each core needs
117+
* to call enable_percpu_irq()
118+
*/
119+
irq_set_percpu_devid(irq);
110120
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
111-
else
121+
} else {
112122
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
123+
}
113124

114125
return 0;
115126
}

0 commit comments

Comments
 (0)