mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-02-06 11:19:56 +00:00
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 <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>
This commit is contained in:
parent
6d1a2adef7
commit
8eb0984bf4
@ -106,10 +106,21 @@ static struct irq_chip arcv2_irq_chip = {
|
|||||||
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
|
static int arcv2_irq_map(struct irq_domain *d, unsigned int irq,
|
||||||
irq_hw_number_t hw)
|
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);
|
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);
|
irq_set_chip_and_handler(irq, &arcv2_irq_chip, handle_level_irq);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user