• Takashi Iwai's avatar
    ALSA: control: Track in-flight control read/write/tlv accesses · e94fdbd7
    Takashi Iwai authored
    Although the power state check is performed in various places (e.g. at
    the entrance of quite a few ioctls), there can be still some pending
    tasks that already went into the ioctl handler or other ops, and those
    may access the hardware even after the power state check.  For
    example, kcontrol access ioctl paths that call info/get/put callbacks
    may update the hardware registers.  If a system wants to assure the
    free from such hw access (like the case of PCI rescan feature we're
    going to implement in future), this situation must be avoided, and we
    have to sync such in-flight tasks finishing beforehand.
    
    For that purpose, this patch introduces a few new things in core code:
    - A refcount, power_ref, and a wait queue, power_ref_sleep, to the
      card object
    - A few new helpers, snd_power_ref(), snd_power_unref(),
      snd_power_ref_and_wait(), and snd_power_sync_ref()
    
    In the code paths that call kctl info/read/write/tlv ops, we check the
    power state with the newly introduced snd_power_ref_and_wait().  This
    function also takes the card.power_ref refcount for tracking this
    in-flight task.  Once after the access finishes, snd_power_unref() is
    called to released the refcount in return.  So the driver can sync via
    snd_power_sync_ref() assuring that all in-flight tasks have been
    finished.
    
    As of this patch, snd_power_sync_ref() is called only at
    snd_card_disconnect(), but it'll be used in other places in future.
    
    Note that atomic_t is used for power_ref intentionally instead of
    refcount_t.  It's because of the design of refcount_t type; refcount_t
    cannot be zero-based, and it cannot do dec_and_test() call for
    multiple times, hence it's not suitable for our purpose.
    
    Also, this patch changes snd_power_wait() to accept only
    SNDRV_CTL_POWER_D0, which is the only value that makes sense.
    In later patch, the snd_power_wait() calls will be cleaned up.
    Reviewed-by: default avatarJaroslav Kysela <perex@perex.cz>
    Link: https://lore.kernel.org/r/20210523090920.15345-3-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    e94fdbd7
init.c 27.2 KB