• Dylan Reid's avatar
    ALSA: hda - Fix hang caused by race during suspend. · d17344b3
    Dylan Reid authored
    There was a race condition when the system suspends while hda_power_work
    is running in the work queue.  If system suspend (snd_hda_suspend)
    happens after the work queue releases power_lock but before it calls
    hda_call_codec_suspend,  codec_suspend runs with power_on=0, causing the
    codec to power up for register reads, and hanging when it calls
    cancel_delayed_work_sync from the running work queue.
    
    The call chain from the work queue will look like this:
    hda_power_work <<- power_on = 1, unlock, then power_on cleard by suspend
      hda_call_codec_suspend
        hda_set_power_state
          snd_hda_codec_read
            codec_exec_verb
              snd_hda_power_up
    	    snd_hda_power_save
    	      __snd_hda_power_up
    	        cancel_delayed_work_sync <<-- cancelling executing wq
    
    Fix this by waiting for the work queue to finish before starting suspend
    if suspend is not happening on the work queue.
    Signed-off-by: default avatarDylan Reid <dgreid@chromium.org>
    Cc: <stable@vger.kernel.org>
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    d17344b3
hda_codec.c 139 KB