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, | ||||
| 			 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; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user