• Takashi Iwai's avatar
    ALSA: hda - Fix deadlock of controller device lock at unbinding · ab949d51
    Takashi Iwai authored
    Imre Deak reported a deadlock of HD-audio driver at unbinding while
    it's still in probing.  Since we probe the codecs asynchronously in a
    work, the codec driver probe may still be kicked off while the
    controller itself is being unbound.  And, azx_remove() tries to
    process all pending tasks via cancel_work_sync() for fixing the other
    races (see commit [0b8c8219: ALSA: hda - Cancel probe work instead
    of flush at remove]), now we may meet a bizarre deadlock:
    
    Unbind snd_hda_intel via sysfs:
      device_release_driver() ->
        device_lock(snd_hda_intel) ->
          azx_remove() ->
            cancel_work_sync(azx_probe_work)
    
    azx_probe_work():
      codec driver probe() ->
         __driver_attach() ->
           device_lock(snd_hda_intel)
    
    This deadlock is caused by the fact that both device_release_driver()
    and driver_probe_device() take both the device and its parent locks at
    the same time.  The codec device sets the controller device as its
    parent, and this lock is taken before the probe() callback is called,
    while the controller remove() callback gets called also with the same
    lock.
    
    In this patch, as an ugly workaround, we unlock the controller device
    temporarily during cancel_work_sync() call.  The race against another
    bind call should be still suppressed by the parent's device lock.
    Reported-by: default avatarImre Deak <imre.deak@intel.com>
    Fixes: 0b8c8219 ("ALSA: hda - Cancel probe work instead of flush at remove")
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    ab949d51
hda_intel.c 68.1 KB