git: bbb37ddf3669 - main - sound: Use and lock only the appropriate channel in dsp_mmap_single()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 20 Jun 2026 19:05:33 UTC
The branch main has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=bbb37ddf3669f77d78446b9f1e37f58c63dc0a1c
commit bbb37ddf3669f77d78446b9f1e37f58c63dc0a1c
Author: Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2026-06-12 06:14:05 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2026-06-20 19:04:49 +0000
sound: Use and lock only the appropriate channel in dsp_mmap_single()
dsp_mmap_single() mmaps one of the channels associated with a
dsp_cdevpriv, based on the nprot argument. PROT_WRITE and
PROT_READ|PROT_WRITE select the output channel for mmaping, and
PROT_READ the input one. Instead of locking and modifying the flags of
all dsp_cdevpriv channels, do it only for the one we actually use.
While here, retire the now unused dsp_lock_chans() and
dsp_unlock_chans().
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Reviewed by: markj, kib
Pull-Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/30
---
sys/dev/sound/pcm/dsp.c | 57 +++++++++++++++----------------------------------
1 file changed, 17 insertions(+), 40 deletions(-)
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index df9e241881c0..337eb4e175b2 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -144,24 +144,6 @@ dsp_destroy_dev(device_t dev)
destroy_dev(d->dsp_dev);
}
-static void
-dsp_lock_chans(struct dsp_cdevpriv *priv, uint32_t prio)
-{
- if (priv->rdch != NULL && DSP_F_READ(prio))
- CHN_LOCK(priv->rdch);
- if (priv->wrch != NULL && DSP_F_WRITE(prio))
- CHN_LOCK(priv->wrch);
-}
-
-static void
-dsp_unlock_chans(struct dsp_cdevpriv *priv, uint32_t prio)
-{
- if (priv->rdch != NULL && DSP_F_READ(prio))
- CHN_UNLOCK(priv->rdch);
- if (priv->wrch != NULL && DSP_F_WRITE(prio))
- CHN_UNLOCK(priv->wrch);
-}
-
static int
dsp_chn_alloc(struct snddev_info *d, struct pcm_channel **ch, int direction,
int flags, struct thread *td)
@@ -1973,7 +1955,7 @@ dsp_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
struct dsp_mmap_handle *handle;
struct dsp_cdevpriv *priv;
struct snddev_info *d;
- struct pcm_channel *wrch, *rdch, *c;
+ struct pcm_channel *c;
int err;
if (*offset >= *offset + size)
@@ -1987,11 +1969,6 @@ dsp_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
SV_CURPROC_ABI() != SV_ABI_LINUX)))
return (EINVAL);
- /*
- * PROT_READ (alone) selects the input buffer.
- * PROT_WRITE (alone) selects the output buffer.
- * PROT_WRITE|PROT_READ together select the output buffer.
- */
if ((nprot & (PROT_READ | PROT_WRITE)) == 0)
return (EINVAL);
@@ -2003,27 +1980,27 @@ dsp_mmap_single(struct cdev *cdev, vm_ooffset_t *offset,
PCM_GIANT_ENTER(d);
- dsp_lock_chans(priv, FREAD | FWRITE);
- wrch = priv->wrch;
- rdch = priv->rdch;
-
- c = ((nprot & PROT_WRITE) != 0) ? wrch : rdch;
- if (c == NULL || (c->flags & CHN_F_MMAP_INVALID) ||
- (*offset + size) > c->bufsoft->allocsize ||
- (wrch != NULL && (wrch->flags & CHN_F_MMAP_INVALID)) ||
- (rdch != NULL && (rdch->flags & CHN_F_MMAP_INVALID))) {
- dsp_unlock_chans(priv, FREAD | FWRITE);
+ /*
+ * PROT_READ (alone) selects the input buffer.
+ * PROT_WRITE (alone) selects the output buffer.
+ * PROT_WRITE|PROT_READ together select the output buffer.
+ */
+ c = ((nprot & PROT_WRITE) != 0) ? priv->wrch : priv->rdch;
+ if (c == NULL) {
PCM_GIANT_EXIT(d);
return (EINVAL);
}
- if (wrch != NULL)
- wrch->flags |= CHN_F_MMAP;
- if (rdch != NULL)
- rdch->flags |= CHN_F_MMAP;
-
+ CHN_LOCK(c);
+ if ((c->flags & CHN_F_MMAP_INVALID) ||
+ *offset + size > c->bufsoft->allocsize) {
+ CHN_UNLOCK(c);
+ PCM_GIANT_EXIT(d);
+ return (EINVAL);
+ }
+ c->flags |= CHN_F_MMAP;
*offset = (uintptr_t)sndbuf_getbufofs(c->bufsoft, *offset);
- dsp_unlock_chans(priv, FREAD | FWRITE);
+ CHN_UNLOCK(c);
handle = malloc(sizeof(*handle), M_DEVBUF, M_WAITOK);
handle->cdev = cdev;