git: 5cc34a83e1cc - main - Revert "sound: Merge chn_intr() with chn_intr_locked()"
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 23 Nov 2025 13:50:42 UTC
The branch main has been updated by christos:
URL: https://cgit.FreeBSD.org/src/commit/?id=5cc34a83e1cc812871fd02a15b7d9f75342faaa0
commit 5cc34a83e1cc812871fd02a15b7d9f75342faaa0
Author: Christos Margiolis <christos@FreeBSD.org>
AuthorDate: 2025-11-23 13:48:51 +0000
Commit: Christos Margiolis <christos@FreeBSD.org>
CommitDate: 2025-11-23 13:48:51 +0000
Revert "sound: Merge chn_intr() with chn_intr_locked()"
It turns out that snd_uaudio(4) uses sound(4)'s channel lock for its USB
transfer callbacks. I will try to address this at some point, because
this is layering violation, but for now we need to revert the commit, as
it causes a lock recursion panic with USB audio devices.
This reverts commit e254ef87a30bfcaabc6e4d8e0ecf05f6949a4f06.
---
sys/dev/sound/pcm/channel.c | 20 ++++++++++++++++++--
sys/dev/sound/pcm/channel.h | 1 +
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
index 011dc1427c2e..7c3f0e3dc9f0 100644
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -581,14 +581,30 @@ chn_read(struct pcm_channel *c, struct uio *buf)
}
void
-chn_intr(struct pcm_channel *c)
+chn_intr_locked(struct pcm_channel *c)
{
- CHN_LOCK(c);
+
+ CHN_LOCKASSERT(c);
+
c->interrupts++;
+
if (c->direction == PCMDIR_PLAY)
chn_wrintr(c);
else
chn_rdintr(c);
+}
+
+void
+chn_intr(struct pcm_channel *c)
+{
+
+ if (CHN_LOCKOWNED(c)) {
+ chn_intr_locked(c);
+ return;
+ }
+
+ CHN_LOCK(c);
+ chn_intr_locked(c);
CHN_UNLOCK(c);
}
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
index 6415f5c88984..0b17c4a130a7 100644
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -298,6 +298,7 @@ int chn_oss_setorder(struct pcm_channel *, unsigned long long *);
int chn_oss_getmask(struct pcm_channel *, uint32_t *);
void chn_resetbuf(struct pcm_channel *c);
+void chn_intr_locked(struct pcm_channel *c);
void chn_intr(struct pcm_channel *c);
int chn_abort(struct pcm_channel *c);