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);