Skip to content

Commit 900498a

Browse files
committed
ALSA: pcm: Allow aborting mutex lock at OSS read/write loops
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. Cc: <[email protected]> Signed-off-by: Takashi Iwai <[email protected]>
1 parent 29159a4 commit 900498a

File tree

1 file changed

+21
-15
lines changed

1 file changed

+21
-15
lines changed

sound/core/oss/pcm_oss.c

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,8 +1334,11 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
13341334

13351335
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
13361336
return tmp;
1337-
mutex_lock(&runtime->oss.params_lock);
13381337
while (bytes > 0) {
1338+
if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
1339+
tmp = -ERESTARTSYS;
1340+
break;
1341+
}
13391342
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
13401343
tmp = bytes;
13411344
if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
@@ -1379,18 +1382,18 @@ static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const cha
13791382
xfer += tmp;
13801383
if ((substream->f_flags & O_NONBLOCK) != 0 &&
13811384
tmp != runtime->oss.period_bytes)
1382-
break;
1385+
tmp = -EAGAIN;
13831386
}
1387+
err:
1388+
mutex_unlock(&runtime->oss.params_lock);
1389+
if (tmp < 0)
1390+
break;
13841391
if (signal_pending(current)) {
13851392
tmp = -ERESTARTSYS;
1386-
goto err;
1393+
break;
13871394
}
1395+
tmp = 0;
13881396
}
1389-
mutex_unlock(&runtime->oss.params_lock);
1390-
return xfer;
1391-
1392-
err:
1393-
mutex_unlock(&runtime->oss.params_lock);
13941397
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
13951398
}
13961399

@@ -1438,8 +1441,11 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
14381441

14391442
if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
14401443
return tmp;
1441-
mutex_lock(&runtime->oss.params_lock);
14421444
while (bytes > 0) {
1445+
if (mutex_lock_interruptible(&runtime->oss.params_lock)) {
1446+
tmp = -ERESTARTSYS;
1447+
break;
1448+
}
14431449
if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
14441450
if (runtime->oss.buffer_used == 0) {
14451451
tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
@@ -1470,16 +1476,16 @@ static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __use
14701476
bytes -= tmp;
14711477
xfer += tmp;
14721478
}
1479+
err:
1480+
mutex_unlock(&runtime->oss.params_lock);
1481+
if (tmp < 0)
1482+
break;
14731483
if (signal_pending(current)) {
14741484
tmp = -ERESTARTSYS;
1475-
goto err;
1485+
break;
14761486
}
1487+
tmp = 0;
14771488
}
1478-
mutex_unlock(&runtime->oss.params_lock);
1479-
return xfer;
1480-
1481-
err:
1482-
mutex_unlock(&runtime->oss.params_lock);
14831489
return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
14841490
}
14851491

0 commit comments

Comments
 (0)