The branch main has been updated by christos:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=bbb37ddf3669f77d78446b9f1e37f58c63dc0a1c

commit bbb37ddf3669f77d78446b9f1e37f58c63dc0a1c
Author:     Christos Margiolis <[email protected]>
AuthorDate: 2026-06-12 06:14:05 +0000
Commit:     Christos Margiolis <[email protected]>
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;

Reply via email to