sparc64: fix out of order spin_lock_irqsave and spin_unlock_restore
After enabling spinlocks debug option, kernel prints out call trace
suggesting that the function ldom_req_sp_token executes a might_sleep
function while IRQs is disabled. IRQs is disabled because the
spin_lock_irqsave and spin_unlock_irqrestore are out of order.
Normal correct sequence is:
spin_lock_irqsave(ds_dev_list_lock, data_flags)
LOCK_DS_DEV()/* spin_lock_irqsave(ds_lock, ds_flags) */
.
.
UNLOCK_DS_DEV()/* spin_unlock_irqrestore(ds_lock, ds_flags) */
spin_unlock_irqrestore(ds_dev_list_lock, data_flags)
Out or order sequence:
spin_lock_irqsave(ds_dev_list_lock, data_flags)
LOCK_DS_DEV()/* spin_lock_irqsave(ds_lock, ds_flags) */
spin_unlock_irqrestore(ds_dev_list_lock, data_flags)
UNLOCK_DS_DEV()/* spin_unlock_irqrestore(ds_lock, ds_flags) */
The last UNLOCK_DS_DEV() ends up restoring IRQs to disabled state,
because the previous LOCK_DS_DEV() is in irqs_disabled().
To fix the issue, follows the order of irqsave()/irqrestore().
Orabug:
26265190
Orabug:
25421812
Signed-off-by: Thomas Tai <thomas.tai@oracle.com>
Reviewed-by: Aaron Young <aaron.young@oracle.com>