sound: Simplify logic in dsp_io_ops()

Use CHN_LOCK()/CHN_UNLOCK() directly, instead of
dsp_lock_chans()/dsp_unlock_chans(). These functions are useful when we
want to potentially lock both channels. Here we know which channel we
are locking, so we can just lock it directly. This way we get rid of the
prio variable as well.

Related to runpid again, there is no reason to assign it when
CHN_F_RUNNING is not set. channel->pid (as well as channel->comm) is
always assigned in dsp_chn_alloc().

Get rid of runpid. I do not see how we can end up with channel->pid
(td->td_proc->p_pid) not matching buf->uio_td->td_proc->p_pid.

Also improve errno values.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D53736
This commit is contained in:
Christos Margiolis
2025-11-21 17:14:13 +01:00
parent e13664f6a4
commit b4c32d67d4
+10 -22
View File
@@ -464,8 +464,7 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
struct snddev_info *d;
struct pcm_channel *ch;
int (*chn_io)(struct pcm_channel *, struct uio *);
int prio, ret;
pid_t runpid;
int ret;
d = priv->sc;
if (!DSP_REGISTERED(d))
@@ -475,37 +474,27 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
switch (buf->uio_rw) {
case UIO_READ:
prio = FREAD;
ch = priv->rdch;
chn_io = chn_read;
break;
case UIO_WRITE:
prio = FWRITE;
ch = priv->wrch;
chn_io = chn_write;
break;
}
runpid = buf->uio_td->td_proc->p_pid;
dsp_lock_chans(priv, prio);
if (ch == NULL || !(ch->flags & CHN_F_BUSY)) {
if (priv->rdch != NULL || priv->wrch != NULL)
dsp_unlock_chans(priv, prio);
if (ch == NULL) {
PCM_GIANT_EXIT(d);
return (EBADF);
return (ENXIO);
}
CHN_LOCK(ch);
if (ch->flags & (CHN_F_MMAP | CHN_F_DEAD) ||
(ch->flags & CHN_F_RUNNING && ch->pid != runpid)) {
dsp_unlock_chans(priv, prio);
if (!(ch->flags & CHN_F_BUSY) ||
(ch->flags & (CHN_F_MMAP | CHN_F_DEAD))) {
CHN_UNLOCK(ch);
PCM_GIANT_EXIT(d);
return (EINVAL);
} else if (!(ch->flags & CHN_F_RUNNING)) {
return (ENXIO);
} else if (!(ch->flags & CHN_F_RUNNING))
ch->flags |= CHN_F_RUNNING;
ch->pid = runpid;
}
/*
* chn_read/write must give up channel lock in order to copy bytes
@@ -517,8 +506,7 @@ dsp_io_ops(struct dsp_cdevpriv *priv, struct uio *buf)
ch->inprog--;
CHN_BROADCAST(&ch->cv);
dsp_unlock_chans(priv, prio);
CHN_UNLOCK(ch);
PCM_GIANT_LEAVE(d);