Skip to content

Commit

Permalink
ARCv2: intc: Fix random perf irq disabling in SMP setup
Browse files Browse the repository at this point in the history
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 <marc.zyngier@arm.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Alexey Brodkin <abrodkin@synopsys.com>
Cc: stable@vger.kernel.org #4.2+
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
  • Loading branch information
vineetgarc committed Dec 12, 2015
1 parent 6d1a2ad commit 8eb0984
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions arch/arc/kernel/intc-arcv2.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
irq_hw_number_t hw)
{
if (irq == TIMER0_IRQ || irq == IPI_IRQ)
/*
* core intc IRQs [16, 23]:
* Statically assigned always private-per-core (Timers, WDT, IPI, PCT)
*/
if (hw < 24) {
/*
* A subsequent request_percpu_irq() fails if percpu_devid is
* not set. That in turns sets NOAUTOEN, meaning each core needs
* to call enable_percpu_irq()
*/
irq_set_percpu_devid(irq);
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_percpu_irq);
else
} else {
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
}

return 0;
}
Expand Down

0 comments on commit 8eb0984

Please sign in to comment.