@samitouri / QOSamiQemu / commits / 2fd2f50e9b

virtio-snd: remove a redundant memory allocation

This change also makes its lifetime explicit and prevents NULL dereferences. Signed-off-by: Roman Kiryanov <rkir@google.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org> Message-ID: <20260305042523.335493-1-rkir@google.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org>

Roman Kiryanov committed Mar 5, 2026 at 04:25 UTC 2fd2f50e9b42362c8dc10bc38c21a1fb34eaa66b
2 files changed +25 -30
hw/audio/virtio-snd.c
+24 -29
@@ -130,7 +130,7 @@ static VirtIOSoundPCMStream *virtio_snd_pcm_get_stream(VirtIOSound *s,
130 uint32_t stream_id)
131 {
132 return stream_id >= s->snd_conf.streams ? NULL :
133 - s->pcm->streams[stream_id];
133 + s->pcm.streams[stream_id];
134 }
135
136 /*
@@ -143,7 +143,7 @@ static virtio_snd_pcm_set_params *virtio_snd_pcm_get_params(VirtIOSound *s,
143 uint32_t stream_id)
144 {
145 return stream_id >= s->snd_conf.streams ? NULL
146 - : &s->pcm->pcm_params[stream_id];
146 + : &s->pcm.pcm_params[stream_id];
147 }
148
149 /*
@@ -260,7 +260,7 @@ uint32_t virtio_snd_set_pcm_params(VirtIOSound *s,
260 {
261 virtio_snd_pcm_set_params *st_params;
262
263 - if (stream_id >= s->snd_conf.streams || s->pcm->pcm_params == NULL) {
263 + if (stream_id >= s->snd_conf.streams || s->pcm.pcm_params == NULL) {
264 virtio_error(VIRTIO_DEVICE(s), "Streams have not been initialized.\n");
265 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
266 }
@@ -424,8 +424,8 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
424 virtio_snd_pcm_set_params *params;
425 VirtIOSoundPCMStream *stream;
426
427 - if (s->pcm->streams == NULL ||
428 - s->pcm->pcm_params == NULL ||
427 + if (s->pcm.streams == NULL ||
428 + s->pcm.pcm_params == NULL ||
429 stream_id >= s->snd_conf.streams) {
430 return cpu_to_le32(VIRTIO_SND_S_BAD_MSG);
431 }
@@ -440,7 +440,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
440 stream = g_new0(VirtIOSoundPCMStream, 1);
441 stream->active = false;
442 stream->id = stream_id;
443 - stream->pcm = s->pcm;
443 + stream->pcm = &s->pcm;
444 stream->s = s;
445 stream->latency_bytes = 0;
446 qemu_mutex_init(&stream->queue_mutex);
@@ -450,7 +450,7 @@ static uint32_t virtio_snd_pcm_prepare(VirtIOSound *s, uint32_t stream_id)
450 * stream_id >= s->snd_conf.streams was checked before so this is
451 * in-bounds
452 */
453 - s->pcm->streams[stream_id] = stream;
453 + s->pcm.streams[stream_id] = stream;
454 }
455
456 virtio_snd_get_qemu_audsettings(&as, params);
@@ -884,11 +884,11 @@ static void virtio_snd_handle_tx_xfer(VirtIODevice *vdev, VirtQueue *vq)
884 stream_id = le32_to_cpu(hdr.stream_id);
885
886 if (stream_id >= vsnd->snd_conf.streams
887 - || vsnd->pcm->streams[stream_id] == NULL) {
887 + || vsnd->pcm.streams[stream_id] == NULL) {
888 goto tx_err;
889 }
890
891 - stream = vsnd->pcm->streams[stream_id];
891 + stream = vsnd->pcm.streams[stream_id];
892 if (stream->info.direction != VIRTIO_SND_D_OUTPUT) {
893 goto tx_err;
894 }
@@ -966,11 +966,11 @@ static void virtio_snd_handle_rx_xfer(VirtIODevice *vdev, VirtQueue *vq)
966 stream_id = le32_to_cpu(hdr.stream_id);
967
968 if (stream_id >= vsnd->snd_conf.streams
969 - || !vsnd->pcm->streams[stream_id]) {
969 + || !vsnd->pcm.streams[stream_id]) {
970 goto rx_err;
971 }
972
973 - stream = vsnd->pcm->streams[stream_id];
973 + stream = vsnd->pcm.streams[stream_id];
974 if (stream == NULL || stream->info.direction != VIRTIO_SND_D_INPUT) {
975 goto rx_err;
976 }
@@ -1064,11 +1064,10 @@ static void virtio_snd_realize(DeviceState *dev, Error **errp)
1064 vsnd->vmstate =
1065 qemu_add_vm_change_state_handler(virtio_snd_vm_state_change, vsnd);
1066
1067 - vsnd->pcm = g_new0(VirtIOSoundPCM, 1);
1068 - vsnd->pcm->snd = vsnd;
1069 - vsnd->pcm->streams =
1067 + vsnd->pcm.snd = vsnd;
1068 + vsnd->pcm.streams =
1069 g_new0(VirtIOSoundPCMStream *, vsnd->snd_conf.streams);
1071 - vsnd->pcm->pcm_params =
1070 + vsnd->pcm.pcm_params =
1071 g_new0(virtio_snd_pcm_set_params, vsnd->snd_conf.streams);
1072
1073 virtio_init(vdev, VIRTIO_ID_SOUND, sizeof(virtio_snd_config));
@@ -1335,23 +1334,19 @@ static void virtio_snd_unrealize(DeviceState *dev)
1334 qemu_del_vm_change_state_handler(vsnd->vmstate);
1335 trace_virtio_snd_unrealize(vsnd);
1336
1338 - if (vsnd->pcm) {
1339 - if (vsnd->pcm->streams) {
1340 - for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1341 - stream = vsnd->pcm->streams[i];
1342 - if (stream) {
1343 - virtio_snd_process_cmdq(stream->s);
1344 - virtio_snd_pcm_close(stream);
1345 - qemu_mutex_destroy(&stream->queue_mutex);
1346 - g_free(stream);
1347 - }
1337 + if (vsnd->pcm.streams) {
1338 + for (uint32_t i = 0; i < vsnd->snd_conf.streams; i++) {
1339 + stream = vsnd->pcm.streams[i];
1340 + if (stream) {
1341 + virtio_snd_process_cmdq(stream->s);
1342 + virtio_snd_pcm_close(stream);
1343 + qemu_mutex_destroy(&stream->queue_mutex);
1344 + g_free(stream);
1345 }
1349 - g_free(vsnd->pcm->streams);
1346 }
1351 - g_free(vsnd->pcm->pcm_params);
1352 - g_free(vsnd->pcm);
1353 - vsnd->pcm = NULL;
1347 + g_free(vsnd->pcm.streams);
1348 }
1349 + g_free(vsnd->pcm.pcm_params);
1350 qemu_mutex_destroy(&vsnd->cmdq_mutex);
1351 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_CONTROL]);
1352 virtio_delete_queue(vsnd->queues[VIRTIO_SND_VQ_EVENT]);
include/hw/audio/virtio-snd.h
+1 -1
@@ -216,7 +216,7 @@ struct VirtIOSound {
216
217 VirtQueue *queues[VIRTIO_SND_VQ_MAX];
218 uint64_t features;
219 - VirtIOSoundPCM *pcm;
219 + VirtIOSoundPCM pcm;
220 AudioBackend *audio_be;
221 VMChangeStateEntry *vmstate;
222 virtio_snd_config snd_conf;