• Takashi Iwai's avatar
    ALSA: hda: Manage concurrent reg access more properly · 1a462be5
    Takashi Iwai authored
    In the commit 8e85def5 ("ALSA: hda: enable regmap internal
    locking"), we re-enabled the regmap lock due to the reported
    regression that showed the possible concurrent accesses.  It was a
    temporary workaround, and there are still a few opened races even
    after the revert.  In this patch, we cover those still opened windows
    with a proper mutex lock and disable the regmap internal lock again.
    
    First off, the patch introduces a new snd_hdac_device.regmap_lock
    mutex that is applied for each snd_hdac_regmap_*() call, including
    read, write and update helpers.  The mutex is applied carefully so
    that it won't block the self-power-up procedure in the helper
    function.  Also, this assures the protection for the accesses without
    regmap, too.
    
    The snd_hdac_regmap_update_raw() is refactored to use the standard
    regmap_update_bits_check() function instead of the open-code.  The
    non-regmap case is still open-coded but it's an easy part.  The all
    read and write operations are in the single mutex protection, so it's
    now race-free.
    
    In addition, a couple of new helper functions are added:
    snd_hdac_regmap_update_raw_once() and snd_hdac_regmap_sync().  Both
    are called from HD-audio legacy driver.  The former is to initialize
    the given verb bits but only once when it's not initialized yet.  Due
    to this condition, the function invokes regcache_cache_only(), and
    it's now performed inside the regmap_lock (formerly it was racy) too.
    The latter function is for simply invoking regcache_sync() inside the
    regmap_lock, which is called from the codec resume call path.
    Along with that, the HD-audio codec driver code is slightly modified /
    simplified to adapt those new functions.
    
    And finally, snd_hdac_regmap_read_raw(), *_write_raw(), etc are
    rewritten with the helper macro.  It's just for simplification because
    the code logic is identical among all those functions.
    Tested-by: default avatarKai Vehmanen <kai.vehmanen@linux.intel.com>
    Link: https://lore.kernel.org/r/20200109090104.26073-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    1a462be5
hda_codec.c 108 KB