• Takashi Iwai's avatar
    ALSA: line6: Reorganize PCM stream handling · 63e20df1
    Takashi Iwai authored
    The current code deals with the stream start / stop solely via
    line6_pcm_acquire() and line6_pcm_release().  This was (supposedly)
    intended to avoid the races, but it doesn't work as expected.  The
    concurrent acquire and release calls can be performed without proper
    protections, thus this might result in memory corruption.
    Furthermore, we can't take a mutex to protect the whole function
    because it can be called from the PCM trigger callback that is an
    atomic context.  Also spinlock isn't appropriate because the function
    allocates with kmalloc with GFP_KERNEL.  That is, these function just
    lead to singular problems.
    
    This is an attempt to reduce the existing races.  First off, separate
    both the stream buffer management and the stream URB management.  The
    former is protected via a newly introduced state_mutex while the
    latter is protected via each line6_pcm_stream lock.
    
    Secondly, the stream state are now managed in opened and running bit
    flags of each line6_pcm_stream.  Not only this a bit clearer than
    previous combined bit flags, this also gives a better abstraction.
    These rewrites allows us to make common hw_params and hw_free
    callbacks for both playback and capture directions.
    
    For the monitor and impulse operations, still line6_pcm_acquire() and
    line6_pcm_release() are used.  They call internally the corresponding
    functions for both playback and capture streams with proper lock or
    mutex.  Unlike the previous versions, these function don't take the
    bit masks but the only single type value.  Also they are supposed to
    be applied only as duplex operations.
    Tested-by: default avatarChris Rorvick <chris@rorvick.com>
    Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    63e20df1
playback.c 11 KB