lkml.org 
[lkml]   [2018]   [Feb]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 182/254] ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
    3.16.55-rc1 review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Takashi Iwai <tiwai@suse.de>

    commit 900498a34a3ac9c611e9b425094c8106bdd7dc1c upstream.

    PCM OSS read/write loops keep taking the mutex lock for the whole
    read/write, and this might take very long when the exceptionally high
    amount of data is given. Also, since it invokes with mutex_lock(),
    the concurrent read/write becomes unbreakable.

    This patch tries to address these issues by replacing mutex_lock()
    with mutex_lock_interruptible(), and also splits / re-takes the lock
    at each read/write period chunk, so that it can switch the context
    more finely if requested.

    Signed-off-by: Takashi Iwai <tiwai@suse.de>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    sound/core/oss/pcm_oss.c | 36 +++++++++++++++++++++---------------
    1 file changed, 21 insertions(+), 15 deletions(-)

    --- a/sound/core/oss/pcm_oss.c
    +++ b/sound/core/oss/pcm_oss.c
    @@ -1370,8 +1370,11 @@ static ssize_t snd_pcm_oss_write1(struct

    if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
    return tmp;
    - mutex_lock(&runtime->oss.params_lock);
    while (bytes > 0) {
    + if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
    + tmp = -ERESTARTSYS;
    + break;
    + }
    if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
    tmp = bytes;
    if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
    @@ -1415,18 +1418,18 @@ static ssize_t snd_pcm_oss_write1(struct
    xfer += tmp;
    if ((substream->f_flags & O_NONBLOCK) != 0 &&
    tmp != runtime->oss.period_bytes)
    - break;
    + tmp = -EAGAIN;
    }
    + err:
    + mutex_unlock(&runtime->oss.params_lock);
    + if (tmp < 0)
    + break;
    if (signal_pending(current)) {
    tmp = -ERESTARTSYS;
    - goto err;
    + break;
    }
    + tmp = 0;
    }
    - mutex_unlock(&runtime->oss.params_lock);
    - return xfer;
    -
    - err:
    - mutex_unlock(&runtime->oss.params_lock);
    return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
    }

    @@ -1474,8 +1477,11 @@ static ssize_t snd_pcm_oss_read1(struct

    if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
    return tmp;
    - mutex_lock(&runtime->oss.params_lock);
    while (bytes > 0) {
    + if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
    + tmp = -ERESTARTSYS;
    + break;
    + }
    if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
    if (runtime->oss.buffer_used == 0) {
    tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
    @@ -1506,16 +1512,16 @@ static ssize_t snd_pcm_oss_read1(struct
    bytes -= tmp;
    xfer += tmp;
    }
    + err:
    + mutex_unlock(&runtime->oss.params_lock);
    + if (tmp < 0)
    + break;
    if (signal_pending(current)) {
    tmp = -ERESTARTSYS;
    - goto err;
    + break;
    }
    + tmp = 0;
    }
    - mutex_unlock(&runtime->oss.params_lock);
    - return xfer;
    -
    - err:
    - mutex_unlock(&runtime->oss.params_lock);
    return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
    }

    \
     
     \ /
      Last update: 2018-02-28 17:43    [W:4.031 / U:0.012 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site