diff options
author | Marc-André Lureau <marcandre.lureau@redhat.com> | 2024-10-08 16:50:11 +0400 |
---|---|---|
committer | Michael Tokarev <mjt@tls.msk.ru> | 2024-10-16 11:14:24 +0300 |
commit | 6d03242a7e47815ed56687ecd13f683d8da3f2fe (patch) | |
tree | 14430f3925e01dcb4b6d9c43d4222c5e4c817a25 | |
parent | 2787ca0e0abec57be2c2989520b7a19997b592f6 (diff) |
hw/audio/hda: fix memory leak on audio setup
When SET_STREAM_FORMAT is called, we should clear the existing setup.
Factor out common function to close a stream.
Direct leak of 144 byte(s) in 3 object(s) allocated from:
#0 0x7f91d38f7350 in calloc (/lib64/libasan.so.8+0xf7350) (BuildId: a4ad7eb954b390cf00f07fa10952988a41d9fc7a)
#1 0x7f91d2ab7871 in g_malloc0 (/lib64/libglib-2.0.so.0+0x64871) (BuildId: 36b60dbd02e796145a982d0151ce37202ec05649)
#2 0x562fa2f447ee in timer_new_full /home/elmarco/src/qemu/include/qemu/timer.h:538
#3 0x562fa2f4486f in timer_new /home/elmarco/src/qemu/include/qemu/timer.h:559
#4 0x562fa2f448a9 in timer_new_ns /home/elmarco/src/qemu/include/qemu/timer.h:577
#5 0x562fa2f47955 in hda_audio_setup ../hw/audio/hda-codec.c:490
#6 0x562fa2f4897e in hda_audio_command ../hw/audio/hda-codec.c:605
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Akihiko Odaki <akihiko.odaki@daynix.com>
Message-ID: <20241008125028.1177932-3-marcandre.lureau@redhat.com>
(cherry picked from commit 6d6e23361fc732e4fe36a8bc5873b85f264ed53a)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
-rw-r--r-- | hw/audio/hda-codec.c | 33 |
1 files changed, 20 insertions, 13 deletions
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index ee3d0a7dec..4373565371 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -472,6 +472,24 @@ static void hda_audio_set_amp(HDAAudioStream *st) } } +static void hda_close_stream(HDAAudioState *a, HDAAudioStream *st) +{ + if (st->node == NULL) { + return; + } + if (a->use_timer) { + timer_free(st->buft); + st->buft = NULL; + } + if (st->output) { + AUD_close_out(&a->card, st->voice.out); + st->voice.out = NULL; + } else { + AUD_close_in(&a->card, st->voice.in); + st->voice.in = NULL; + } +} + static void hda_audio_setup(HDAAudioStream *st) { bool use_timer = st->state->use_timer; @@ -484,6 +502,7 @@ static void hda_audio_setup(HDAAudioStream *st) trace_hda_audio_format(st->node->name, st->as.nchannels, fmt2name[st->as.fmt], st->as.freq); + hda_close_stream(st->state, st); if (st->output) { if (use_timer) { cb = hda_audio_output_cb; @@ -741,23 +760,11 @@ static void hda_audio_init(HDACodecDevice *hda, static void hda_audio_exit(HDACodecDevice *hda) { HDAAudioState *a = HDA_AUDIO(hda); - HDAAudioStream *st; int i; dprint(a, 1, "%s\n", __func__); for (i = 0; i < ARRAY_SIZE(a->st); i++) { - st = a->st + i; - if (st->node == NULL) { - continue; - } - if (a->use_timer) { - timer_free(st->buft); - } - if (st->output) { - AUD_close_out(&a->card, st->voice.out); - } else { - AUD_close_in(&a->card, st->voice.in); - } + hda_close_stream(a, a->st + i); } AUD_remove_card(&a->card); } |