• Rex Zhang's avatar
    dmaengine: idxd: use spin_lock_irqsave before wait_event_lock_irq · c0409dd3
    Rex Zhang authored
    In idxd_cmd_exec(), wait_event_lock_irq() explicitly calls
    spin_unlock_irq()/spin_lock_irq(). If the interrupt is on before entering
    wait_event_lock_irq(), it will become off status after
    wait_event_lock_irq() is called. Later, wait_for_completion() may go to
    sleep but irq is disabled. The scenario is warned in might_sleep().
    
    Fix it by using spin_lock_irqsave() instead of the primitive spin_lock()
    to save the irq status before entering wait_event_lock_irq() and using
    spin_unlock_irqrestore() instead of the primitive spin_unlock() to restore
    the irq status before entering wait_for_completion().
    
    Before the change:
    idxd_cmd_exec() {
    interrupt is on
    spin_lock()                        // interrupt is on
    	wait_event_lock_irq()
    		spin_unlock_irq()  // interrupt is enabled
    		...
    		spin_lock_irq()    // interrupt is disabled
    spin_unlock()                      // interrupt is still disabled
    wait_for_completion()              // report "BUG: sleeping function
    				   // called from invalid context...
    				   // in_atomic() irqs_disabled()"
    }
    
    After applying spin_lock_irqsave():
    idxd_cmd_exec() {
    interrupt is on
    spin_lock_irqsave()                // save the on state
    				   // interrupt is disabled
    	wait_event_lock_irq()
    		spin_unlock_irq()  // interrupt is enabled
    		...
    		spin_lock_irq()    // interrupt is disabled
    spin_unlock_irqrestore()           // interrupt is restored to on
    wait_for_completion()              // No Call trace
    }
    
    Fixes: f9f4082d ("dmaengine: idxd: remove interrupt disable for cmd_lock")
    Signed-off-by: default avatarRex Zhang <rex.zhang@intel.com>
    Signed-off-by: default avatarLijun Pan <lijun.pan@intel.com>
    Reviewed-by: default avatarDave Jiang <dave.jiang@intel.com>
    Reviewed-by: default avatarFenghua Yu <fenghua.yu@intel.com>
    Link: https://lore.kernel.org/r/20230916060619.3744220-1-rex.zhang@intel.comSigned-off-by: default avatarVinod Koul <vkoul@kernel.org>
    c0409dd3
device.c 38.7 KB