Skip to content

Commit d3ff967

Browse files
committed
module: cadence / ipc4: Fix memory leak of notification IPC message
Each notification that that is sent by the module could cause a memory leak in theory. Notification is only sent in case of DRAIN or EOL and multiple notification sending will be blocked by the eos_notification_sent flag. Since pipelines cannot recover from EOS state, this is theoretical until that is fixed, but it is a bug in the code never the less. Follow the example of other modules and store and allocate the notification message for the lifetime of the module to manage the allocation properly. Fixes: f6cfc4c ("module: cadence / ipc4: Support for EOS handling and notification to host") Reported-by: Jyri Sarha <jyri.sarha@linux.intel.com> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
1 parent c351193 commit d3ff967

2 files changed

Lines changed: 54 additions & 26 deletions

File tree

src/audio/module_adapter/module/cadence_ipc4.c

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,33 @@ static int cadence_configure_codec_params(struct processing_module *mod)
217217
return -EINVAL;
218218
}
219219

220+
static struct ipc_msg *cadence_codec_notification_init(struct processing_module *mod)
221+
{
222+
struct cadence_codec_data *cd = module_get_private_data(mod);
223+
struct comp_dev *dev = mod->dev;
224+
struct comp_ipc_config *ipc_config = &dev->ipc_config;
225+
union ipc4_notification_header primary;
226+
struct sof_ipc4_notify_module_data *msg_module_data;
227+
struct ipc_msg *msg;
228+
229+
primary.dat = 0;
230+
primary.r.notif_type = SOF_IPC4_MODULE_NOTIFICATION;
231+
primary.r.type = SOF_IPC4_GLB_NOTIFICATION;
232+
primary.r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
233+
primary.r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
234+
msg = ipc_msg_w_ext_init(primary.dat, 0, sizeof(*msg_module_data));
235+
if (!msg)
236+
return NULL;
237+
238+
msg_module_data = (struct sof_ipc4_notify_module_data *)msg->tx_data;
239+
msg_module_data->instance_id = IPC4_INST_ID(ipc_config->id);
240+
msg_module_data->module_id = IPC4_MOD_ID(ipc_config->id);
241+
msg_module_data->event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL;
242+
msg_module_data->event_data_size = 0;
243+
244+
return msg;
245+
}
246+
220247
static int cadence_codec_init(struct processing_module *mod)
221248
{
222249
struct module_data *codec = &mod->priv;
@@ -237,6 +264,13 @@ static int cadence_codec_init(struct processing_module *mod)
237264
}
238265

239266
codec->private = cd;
267+
cd->msg = cadence_codec_notification_init(mod);
268+
if (!cd->msg) {
269+
comp_err(dev, "failed to allocate IPC notification template");
270+
ret = -ENOMEM;
271+
goto free_cd;
272+
}
273+
240274
memcpy_s(&cd->base_cfg, sizeof(cd->base_cfg), &cfg->base_cfg, sizeof(cd->base_cfg));
241275

242276
codec->mpd.init_done = 0;
@@ -253,7 +287,7 @@ static int cadence_codec_init(struct processing_module *mod)
253287
if (!setup_cfg->data) {
254288
comp_err(dev, "failed to alloc setup config");
255289
ret = -ENOMEM;
256-
goto free_cd;
290+
goto free_notification;
257291
}
258292

259293
setup_cfg->size = size;
@@ -315,6 +349,8 @@ static int cadence_codec_init(struct processing_module *mod)
315349
free_cfg:
316350
if (setup_cfg)
317351
mod_free(mod, setup_cfg->data);
352+
free_notification:
353+
ipc_msg_free(cd->msg);
318354
free_cd:
319355
mod_free(mod, cd);
320356

@@ -472,30 +508,10 @@ static int cadence_codec_process(struct processing_module *mod, struct sof_sourc
472508
}
473509

474510
if (codec->mpd.eos_reached && !codec->mpd.eos_notification_sent) {
475-
struct ipc_msg msg_proto;
476-
struct comp_ipc_config *ipc_config = &dev->ipc_config;
477-
union ipc4_notification_header *primary =
478-
(union ipc4_notification_header *)&msg_proto.header;
479-
struct sof_ipc4_notify_module_data *msg_module_data;
480-
struct ipc_msg *msg;
481-
482-
memset_s(&msg_proto, sizeof(msg_proto), 0, sizeof(msg_proto));
483-
primary->r.notif_type = SOF_IPC4_MODULE_NOTIFICATION;
484-
primary->r.type = SOF_IPC4_GLB_NOTIFICATION;
485-
primary->r.rsp = SOF_IPC4_MESSAGE_DIR_MSG_REQUEST;
486-
primary->r.msg_tgt = SOF_IPC4_MESSAGE_TARGET_FW_GEN_MSG;
487-
msg = ipc_msg_w_ext_init(msg_proto.header, msg_proto.extension,
488-
sizeof(*msg_module_data));
489-
if (msg) {
490-
msg_module_data = (struct sof_ipc4_notify_module_data *)msg->tx_data;
491-
msg_module_data->instance_id = IPC4_INST_ID(ipc_config->id);
492-
msg_module_data->module_id = IPC4_MOD_ID(ipc_config->id);
493-
msg_module_data->event_id = SOF_IPC4_NOTIFY_MODULE_EVENTID_COMPR_MAGIC_VAL;
494-
msg_module_data->event_data_size = 0;
495-
496-
ipc_msg_send(msg, NULL, false);
497-
codec->mpd.eos_notification_sent = true;
498-
}
511+
struct cadence_codec_data *cd = module_get_private_data(mod);
512+
513+
ipc_msg_send(cd->msg, NULL, false);
514+
codec->mpd.eos_notification_sent = true;
499515

500516
/* Set EOS for the sink as we are not going to produce more data */
501517
audio_buffer_set_eos(sof_audio_buffer_from_sink(sinks[0]));
@@ -568,13 +584,22 @@ static bool cadence_is_ready_to_process(struct processing_module *mod,
568584
return true;
569585
}
570586

587+
static int ipc4_cadence_codec_free(struct processing_module *mod)
588+
{
589+
struct cadence_codec_data *cd = module_get_private_data(mod);
590+
591+
ipc_msg_free(cd->msg);
592+
593+
return cadence_codec_free(mod);
594+
}
595+
571596
static const struct module_interface cadence_codec_interface = {
572597
.init = cadence_codec_init,
573598
.prepare = cadence_codec_prepare,
574599
.process = cadence_codec_process,
575600
.set_configuration = cadence_codec_set_configuration,
576601
.reset = cadence_codec_reset,
577-
.free = cadence_codec_free,
602+
.free = ipc4_cadence_codec_free,
578603
.is_ready_to_process = cadence_is_ready_to_process,
579604
};
580605

src/include/sof/audio/module_adapter/module/cadence.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,13 @@ struct cadence_api {
5151
xa_codec_func_t *api;
5252
};
5353

54+
struct ipc_msg;
55+
5456
struct cadence_codec_data {
5557
#if CONFIG_IPC_MAJOR_4
5658
struct ipc4_base_module_cfg base_cfg;
5759
uint32_t direction;
60+
struct ipc_msg *msg;
5861
#endif
5962
char name[LIB_NAME_MAX_LEN];
6063
void *self;

0 commit comments

Comments
 (0)