Skip to content

Commit cf89794

Browse files
committed
Tools: Testbench: Fix notification pool memory leak
In capture direction testbench runs, pipeline_comp_copy() triggers send_process_data_error_notif_msg() which allocates a notification from the pool and queues it to the IPC message list via ipc_msg_send(). On Zephyr targets a work handler calls ipc_send_queued_msg() to process the queue and invoke the free callback. In the testbench no such handler exists, so queued notifications are never freed. Add ipc_notification_pool_free() to notification_pool.c to release all pool items. In tb_free(), drain the IPC message queue by calling ipc_send_queued_msg() in a loop, then call ipc_notification_pool_free() to free the pool before releasing IPC resources. Signed-off-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
1 parent 8d75e2c commit cf89794

3 files changed

Lines changed: 39 additions & 0 deletions

File tree

src/include/sof/ipc/notification_pool.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,15 @@
2323
*/
2424
struct ipc_msg *ipc_notification_pool_get(size_t size);
2525

26+
#if CONFIG_LIBRARY
27+
/**
28+
* @brief Frees all IPC notification messages in the pool.
29+
*
30+
* This function frees all notification messages currently held in
31+
* the pool free list and resets the pool depth counter. It is
32+
* required only in library (testbench) build.
33+
*/
34+
void ipc_notification_pool_free(void);
35+
#endif /* CONFIG_LIBRARY */
36+
2637
#endif /* __SOF_IPC_NOTIFICATION_POOL_H__ */

src/ipc/notification_pool.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,22 @@ struct ipc_msg *ipc_notification_pool_get(size_t size)
100100
item->msg.tx_size = size;
101101
return &item->msg;
102102
}
103+
104+
#if CONFIG_LIBRARY
105+
void ipc_notification_pool_free(void)
106+
{
107+
struct ipc_notif_pool_item *item;
108+
k_spinlock_key_t key;
109+
110+
key = k_spin_lock(&pool_free_list_lock);
111+
while (!list_is_empty(&pool_free_list)) {
112+
item = list_first_item(&pool_free_list, struct ipc_notif_pool_item, msg.list);
113+
list_item_del(&item->msg.list);
114+
--pool_depth;
115+
k_spin_unlock(&pool_free_list_lock, key);
116+
rfree(item);
117+
key = k_spin_lock(&pool_free_list_lock);
118+
}
119+
k_spin_unlock(&pool_free_list_lock, key);
120+
}
121+
#endif /* CONFIG_LIBRARY */

tools/testbench/utils.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <platform/lib/ll_schedule.h>
77
#include <sof/audio/component.h>
88
#include <sof/ipc/topology.h>
9+
#include <sof/ipc/msg.h>
10+
#include <sof/ipc/notification_pool.h>
911
#include <sof/lib/notifier.h>
1012

1113
#include <ctype.h>
@@ -211,6 +213,13 @@ void tb_free(struct sof *sof)
211213
}
212214
free(*arch_schedulers_get());
213215

216+
/* Drain IPC message queue to free queued notifications */
217+
while (!list_is_empty(&sof->ipc->msg_list))
218+
ipc_send_queued_msg();
219+
220+
/* Free notification pool items */
221+
ipc_notification_pool_free();
222+
214223
/* free IPC data */
215224
iipc = sof->ipc->private;
216225
free(sof->ipc->comp_data);

0 commit comments

Comments
 (0)