[IMPACT]
The CPU x doesn't have a chance to exit the xgene_msi_cascade function to unlock desc->lock before Linux scheduce and call xgene_msi_set_affinity (irqbalance is caller) in the same CPU x. In irq_set_affinity, call raw_spin_lock_irqsave(&desc->lock, flags) which cause deadlock to CPU x because it disables preempt.
Use chained_irq_enter and exit as the standard way to cascade interrupt functions.
[TEST CASE]
Turn off irqbalance
Run a single tcp stream
Randomly change the affinity of the receiving ring:
@ ethtool -S $INTF | grep rx[0-9].*_pac @ - to detect the rx ring
@ grep $INTF /proc/interrupts@ - to find it's interrupt
@ printf "%x" $(( 2 ** $((RANDOM % 8)) )) > /proc/irq/$IRQ/smp_affinity @ - to change the affinity
[Regression Potential]
Fix specific to the xgene pci msi code.
[IMPACT] set_affinity (irqbalance is caller) in the same CPU x. In irq_set_affinity, call raw_spin_ lock_irqsave( &desc-> lock, flags) which cause deadlock to CPU x because it disables preempt.
The CPU x doesn't have a chance to exit the xgene_msi_cascade function to unlock desc->lock before Linux scheduce and call xgene_msi_
Use chained_irq_enter and exit as the standard way to cascade interrupt functions.
[TEST CASE]
Turn off irqbalance
Run a single tcp stream
Randomly change the affinity of the receiving ring:
@ ethtool -S $INTF | grep rx[0-9].*_pac @ - to detect the rx ring $IRQ/smp_ affinity @ - to change the affinity
@ grep $INTF /proc/interrupts@ - to find it's interrupt
@ printf "%x" $(( 2 ** $((RANDOM % 8)) )) > /proc/irq/
[Regression Potential]
Fix specific to the xgene pci msi code.