git: b5c1ab6c8f28 - main - snd_hdsp*: malloc(9) with M_WAITOK

Christos Margiolis <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a899acc.31fcc.547b8295__12950.8225176082$1787402978$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by christos:

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

commit b5c1ab6c8f2811278b801084713a6618f3b783d3
Author:     Christos Margiolis <[email protected]>
AuthorDate: 2026-08-22 12:48:50 +0000
Commit:     Christos Margiolis <[email protected]>
CommitDate: 2026-08-22 12:48:50 +0000

    snd_hdsp*: malloc(9) with M_WAITOK
    
    Perform the allocations outside the lock section so that we can use
    M_WAITOK. Holding the lock here is actually not really necessary and we
    could just as well remove it, but keep it for consistency.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 month
    Reviewed by:    kib
    Differential Revision:  https://reviews.freebsd.org/D59079
---
 sys/dev/sound/pci/hdsp-pcm.c  | 17 +++++++++++++++--
 sys/dev/sound/pci/hdspe-pcm.c | 17 +++++++++++++++--
 2 files changed, 30 insertions(+), 4 deletions(-)

diff --git a/sys/dev/sound/pci/hdsp-pcm.c b/sys/dev/sound/pci/hdsp-pcm.c
index b4df8ca90555..7f4f7dc76557 100644
--- a/sys/dev/sound/pci/hdsp-pcm.c
+++ b/sys/dev/sound/pci/hdsp-pcm.c
@@ -676,10 +676,13 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 	struct sc_pcminfo *scp;
 	struct sc_chinfo *ch;
 	struct sc_info *sc;
+	struct pcmchan_caps *caps;
+	uint32_t *data;
 	int num;
 
 	scp = devinfo;
 	sc = scp->sc;
+	caps = malloc(sizeof(struct pcmchan_caps), M_HDSP, M_WAITOK);
 
 	mtx_lock(&sc->lock);
 	num = scp->chnum;
@@ -704,7 +707,7 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 	    SND_FORMAT(AFMT_S32_LE, hdsp_port_slot_count(ch->ports, 192000), 0);
 	ch->cap_fmts[3] = 0;
 
-	ch->caps = malloc(sizeof(struct pcmchan_caps), M_HDSP, M_NOWAIT);
+	ch->caps = caps;
 	*(ch->caps) = (struct pcmchan_caps) {32000, 192000, ch->cap_fmts, 0};
 
 	/* HDSP 9652 does not support quad speed sample rates. */
@@ -715,7 +718,6 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 
 	/* Allocate maximum buffer size. */
 	ch->size = HDSP_CHANBUF_SIZE * hdsp_port_slot_count_max(ch->ports);
-	ch->data = malloc(ch->size, M_HDSP, M_NOWAIT);
 	ch->position = 0;
 
 	ch->buffer = b;
@@ -726,6 +728,17 @@ hdspchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 
 	mtx_unlock(&sc->lock);
 
+	/*
+	 * It is safe to access ch->size here without holding the lock, because
+	 * 1) as of now, ch->size is written only once, here, and 2) ch's
+	 * lifetime is equal to scp's lifetime so it cannot go away yet.
+	 */
+	data = malloc(ch->size, M_HDSP, M_WAITOK);
+
+	mtx_lock(&sc->lock);
+	ch->data = data;
+	mtx_unlock(&sc->lock);
+
 	if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) {
 		device_printf(scp->dev, "Can't setup sndbuf.\n");
 		hdspchan_free(obj, ch);
diff --git a/sys/dev/sound/pci/hdspe-pcm.c b/sys/dev/sound/pci/hdspe-pcm.c
index e0b6168efcba..a814c80127b1 100644
--- a/sys/dev/sound/pci/hdspe-pcm.c
+++ b/sys/dev/sound/pci/hdspe-pcm.c
@@ -670,10 +670,13 @@ hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 	struct sc_pcminfo *scp;
 	struct sc_chinfo *ch;
 	struct sc_info *sc;
+	struct pcmchan_caps *caps;
+	uint32_t *data;
 	int num;
 
 	scp = devinfo;
 	sc = scp->sc;
+	caps = malloc(sizeof(struct pcmchan_caps), M_HDSPE, M_WAITOK);
 
 	mtx_lock(&sc->lock);
 	num = scp->chnum;
@@ -697,12 +700,11 @@ hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 	ch->cap_fmts[2] =
 	    SND_FORMAT(AFMT_S32_LE, hdspe_channel_count(ch->ports, 8), 0);
 	ch->cap_fmts[3] = 0;
-	ch->caps = malloc(sizeof(struct pcmchan_caps), M_HDSPE, M_NOWAIT);
+	ch->caps = caps;
 	*(ch->caps) = (struct pcmchan_caps) {32000, 192000, ch->cap_fmts, 0};
 
 	/* Allocate maximum buffer size. */
 	ch->size = HDSPE_CHANBUF_SIZE * hdspe_channel_count(ch->ports, 8);
-	ch->data = malloc(ch->size, M_HDSPE, M_NOWAIT);
 	ch->position = 0;
 
 	ch->buffer = b;
@@ -713,6 +715,17 @@ hdspechan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
 
 	mtx_unlock(&sc->lock);
 
+	/*
+	 * It is safe to access ch->size here without holding the lock, because
+	 * 1) as of now, ch->size is written only once, here, and 2) ch's
+	 * lifetime is equal to scp's lifetime so it cannot go away yet.
+	 */
+	data = malloc(ch->size, M_HDSPE, M_WAITOK);
+
+	mtx_lock(&sc->lock);
+	ch->data = data;
+	mtx_unlock(&sc->lock);
+
 	if (sndbuf_setup(ch->buffer, ch->data, ch->size) != 0) {
 		device_printf(scp->dev, "Can't setup sndbuf.\n");
 		hdspechan_free(obj, ch);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.