Skip to content

Commit 2fa783a

Browse files
committed
Audio: MFCC: Fix memory leak on reset-prepare cycles
mfcc_reset() did not free buffers allocated by mfcc_setup(), so a stop->reset->prepare->start cycle would leak all MFCC allocations (FFT buffers, mel filterbank, DCT matrix, lifter, VAD buffers). This patch fixes the issue by calling mfcc_free_buffers() from mfcc_reset(). The pointers are set to NULL after free via a helper function mfcc_free_and_null(), so mfcc_free() won't double-free when it calls mfcc_free_buffers() again later. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 5537875 commit 2fa783a

2 files changed

Lines changed: 27 additions & 9 deletions

File tree

src/audio/mfcc/mfcc.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,15 +175,18 @@ static int mfcc_prepare(struct processing_module *mod,
175175
cd->mfcc_func = mfcc_find_func(source_format, sink_format, mfcc_fm, ARRAY_SIZE(mfcc_fm));
176176
if (!cd->mfcc_func) {
177177
comp_err(dev, "No proc func");
178+
mfcc_free_buffers(mod);
178179
return -EINVAL;
179180
}
180181

181182
/* Initialize VAD switch control notification if enabled */
182183
if (cd->config->enable_vad && cd->config->update_controls) {
183184
if (!cd->msg) {
184185
ret = mfcc_ipc_notification_init(mod);
185-
if (ret < 0)
186+
if (ret < 0) {
187+
mfcc_free_buffers(mod);
186188
return ret;
189+
}
187190
}
188191
}
189192

@@ -197,6 +200,11 @@ static int mfcc_reset(struct processing_module *mod)
197200

198201
comp_info(mod->dev, "entry");
199202

203+
/* Free MFCC buffers to prevent leaks on reset->prepare cycles.
204+
* mfcc_free_buffers() NULLs the pointers after free.
205+
*/
206+
mfcc_free_buffers(mod);
207+
200208
/* Reset to similar state as init() */
201209
cd->mfcc_func = NULL;
202210
return 0;

src/audio/mfcc/mfcc_setup.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -396,17 +396,27 @@ int mfcc_setup(struct processing_module *mod, int max_frames, int sample_rate, i
396396
return ret;
397397
}
398398

399+
static void mfcc_free_and_null(struct processing_module *mod, void **ptr)
400+
{
401+
mod_free(mod, *ptr);
402+
*ptr = NULL;
403+
}
404+
405+
/* Free MFCC buffers to prevent leaks on reset->prepare cycles.
406+
* mfcc_free_buffers() NULLs the pointers after free.
407+
*/
399408
void mfcc_free_buffers(struct processing_module *mod)
400409
{
401410
struct mfcc_comp_data *cd = module_get_private_data(mod);
402411

403412
mod_fft_plan_free(mod, cd->state.fft.fft_plan);
404-
mod_free(mod, cd->state.fft.fft_buf);
405-
mod_free(mod, cd->state.fft.fft_out);
406-
mod_free(mod, cd->state.buffers);
407-
mod_free(mod, cd->state.melfb.data);
408-
mod_free(mod, cd->state.dct.matrix);
409-
mod_free(mod, cd->state.lifter.matrix);
410-
mod_free(mod, cd->vad.noise_floor);
411-
mod_free(mod, cd->vad.weights);
413+
cd->state.fft.fft_plan = NULL;
414+
mfcc_free_and_null(mod, (void **)&cd->state.fft.fft_buf);
415+
mfcc_free_and_null(mod, (void **)&cd->state.fft.fft_out);
416+
mfcc_free_and_null(mod, (void **)&cd->state.buffers);
417+
mfcc_free_and_null(mod, (void **)&cd->state.melfb.data);
418+
mfcc_free_and_null(mod, (void **)&cd->state.dct.matrix);
419+
mfcc_free_and_null(mod, (void **)&cd->state.lifter.matrix);
420+
mfcc_free_and_null(mod, (void **)&cd->vad.noise_floor);
421+
mfcc_free_and_null(mod, (void **)&cd->vad.weights);
412422
}

0 commit comments

Comments
 (0)