Skip to content

Commit 4bbf5a1

Browse files
Jyri Sarhakv2019i
authored andcommitted
modules: Allocate memory containers in chunks
Do not allocate module memory containers one by one, but allocate them in chunks. The bookkeeping of allocated resources is done using containers that are allocated from heap. This effectively doubles the amount of heap allocations. This is not very efficient especially since the containers are only 20 bytes in size. This commit changes the allocation of containers so that they are always allocated in chunks of 16 containers, or what is selected with MODULE_MEMORY_API_CONTAINER_CHUNK_SIZE Kconfig option. The unused containers are not freed when the associated resource is freed. Instead the unused containers are kept in free containers list. All the containers are freed when mod_free_all() is called, for instance when the module unloads. Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
1 parent cf8944e commit 4bbf5a1

5 files changed

Lines changed: 92 additions & 26 deletions

File tree

src/audio/module_adapter/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,16 @@
33
menu "Processing modules"
44
visible if COMP_MODULE_ADAPTER
55

6+
config MODULE_MEMORY_API_CONTAINER_CHUNK_SIZE
7+
int "Number of memory containers to allocate at once"
8+
default 16
9+
help
10+
The per module resource containers are allocated in
11+
chunks. The unused containers are kept in free
12+
list. When the free list is empty the amount of
13+
containers to allocate at once is selected by this
14+
config option.
15+
616
config CADENCE_CODEC
717
bool "Cadence codec"
818
default n

src/audio/module_adapter/module/generic.c

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,9 @@ int module_init(struct processing_module *mod)
9292
}
9393

9494
/* Init memory list */
95-
list_init(&md->memory.mem_list);
95+
list_init(&md->resources.mem_list);
96+
list_init(&md->resources.free_cont_list);
97+
list_init(&md->resources.cont_chunk_list);
9698

9799
/* Now we can proceed with module specific initialization */
98100
ret = interface->init(mod);
@@ -110,6 +112,42 @@ int module_init(struct processing_module *mod)
110112
return 0;
111113
}
112114

115+
struct container_chunk {
116+
struct list_item chunk_list;
117+
struct module_memory containers[CONFIG_MODULE_MEMORY_API_CONTAINER_CHUNK_SIZE];
118+
};
119+
120+
static struct module_memory *container_get(struct processing_module *mod)
121+
{
122+
struct module_resources *res = &mod->priv.resources;
123+
struct module_memory *container;
124+
125+
if (list_is_empty(&res->free_cont_list)) {
126+
struct container_chunk *chunk = rzalloc(SOF_MEM_FLAG_USER, sizeof(*chunk));
127+
int i;
128+
129+
if (!chunk) {
130+
comp_err(mod->dev, "allocating more containers failed");
131+
return NULL;
132+
}
133+
134+
list_item_append(&chunk->chunk_list, &res->cont_chunk_list);
135+
for (i = 0; i < ARRAY_SIZE(chunk->containers); i++)
136+
list_item_append(&chunk->containers[i].mem_list, &res->free_cont_list);
137+
}
138+
139+
container = list_first_item(&res->free_cont_list, struct module_memory, mem_list);
140+
list_item_del(&container->mem_list);
141+
return container;
142+
}
143+
144+
static void container_put(struct processing_module *mod, struct module_memory *container)
145+
{
146+
struct module_resources *res = &mod->priv.resources;
147+
148+
list_item_append(&container->mem_list, &res->free_cont_list);
149+
}
150+
113151
/**
114152
* Allocates aligned memory block for module.
115153
* @param mod Pointer to the module this memory block is allocatd for.
@@ -121,20 +159,16 @@ int module_init(struct processing_module *mod)
121159
*/
122160
void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t alignment)
123161
{
124-
struct comp_dev *dev = mod->dev;
125-
struct module_memory *container;
162+
struct module_memory *container = container_get(mod);
163+
struct module_resources *res = &mod->priv.resources;
126164
void *ptr;
127165

128-
if (!size) {
129-
comp_err(dev, "mod_alloc: requested allocation of 0 bytes.");
166+
if (!container)
130167
return NULL;
131-
}
132168

133-
/* Allocate memory container */
134-
container = rzalloc(SOF_MEM_FLAG_USER,
135-
sizeof(struct module_memory));
136-
if (!container) {
137-
comp_err(dev, "mod_alloc: failed to allocate memory container.");
169+
if (!size) {
170+
comp_err(mod->dev, "mod_alloc: requested allocation of 0 bytes.");
171+
container_put(mod, container);
138172
return NULL;
139173
}
140174

@@ -145,15 +179,15 @@ void *mod_alloc_align(struct processing_module *mod, uint32_t size, uint32_t ali
145179
ptr = rballoc(SOF_MEM_FLAG_USER, size);
146180

147181
if (!ptr) {
148-
comp_err(dev, "mod_alloc: failed to allocate memory for comp %x.",
149-
dev_comp_id(dev));
150-
rfree(container);
182+
comp_err(mod->dev, "mod_alloc: failed to allocate memory for comp %x.",
183+
dev_comp_id(mod->dev));
184+
container_put(mod, container);
151185
return NULL;
152186
}
153187
/* Store reference to allocated memory */
154188
container->ptr = ptr;
155189
container->size = size;
156-
list_item_prepend(&container->mem_list, &mod->priv.memory.mem_list);
190+
list_item_prepend(&container->mem_list, &res->mem_list);
157191

158192
return ptr;
159193
}
@@ -200,6 +234,7 @@ EXPORT_SYMBOL(mod_zalloc);
200234
*/
201235
int mod_free(struct processing_module *mod, void *ptr)
202236
{
237+
struct module_resources *res = &mod->priv.resources;
203238
struct module_memory *mem;
204239
struct list_item *mem_list;
205240
struct list_item *_mem_list;
@@ -208,12 +243,12 @@ int mod_free(struct processing_module *mod, void *ptr)
208243
return 0;
209244

210245
/* Find which container keeps this memory */
211-
list_for_item_safe(mem_list, _mem_list, &mod->priv.memory.mem_list) {
246+
list_for_item_safe(mem_list, _mem_list, &res->mem_list) {
212247
mem = container_of(mem_list, struct module_memory, mem_list);
213248
if (mem->ptr == ptr) {
214249
rfree(mem->ptr);
215250
list_item_del(&mem->mem_list);
216-
rfree(mem);
251+
container_put(mod, mem);
217252
return 0;
218253
}
219254
}
@@ -403,16 +438,24 @@ int module_reset(struct processing_module *mod)
403438
*/
404439
void mod_free_all(struct processing_module *mod)
405440
{
406-
struct module_memory *mem;
407-
struct list_item *mem_list;
408-
struct list_item *_mem_list;
441+
struct module_resources *res = &mod->priv.resources;
442+
struct list_item *list;
443+
struct list_item *_list;
409444

410445
/* Find which container keeps this memory */
411-
list_for_item_safe(mem_list, _mem_list, &mod->priv.memory.mem_list) {
412-
mem = container_of(mem_list, struct module_memory, mem_list);
446+
list_for_item_safe(list, _list, &res->mem_list) {
447+
struct module_memory *mem = container_of(list, struct module_memory, mem_list);
448+
413449
rfree(mem->ptr);
414450
list_item_del(&mem->mem_list);
415-
rfree(mem);
451+
}
452+
453+
list_for_item_safe(list, _list, &res->cont_chunk_list) {
454+
struct container_chunk *chunk =
455+
container_of(list, struct container_chunk, chunk_list);
456+
457+
list_item_del(&chunk->chunk_list);
458+
rfree(chunk);
416459
}
417460
}
418461
EXPORT_SYMBOL(mod_free_all);

src/audio/module_adapter/module_adapter.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1292,10 +1292,11 @@ EXPORT_SYMBOL(module_adapter_free);
12921292

12931293
size_t module_adapter_heap_usage(struct processing_module *mod)
12941294
{
1295+
struct module_resources *res = &mod->priv.resources;
12951296
struct list_item *mem_list, *_mem_list;
12961297
size_t size = 0;
12971298

1298-
list_for_item_safe(mem_list, _mem_list, &mod->priv.memory.mem_list) {
1299+
list_for_item_safe(mem_list, _mem_list, &res->mem_list) {
12991300
struct module_memory *mem = container_of(mem_list, struct module_memory, mem_list);
13001301

13011302
size += mem->size;

src/include/module/module/base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct module_data {
5959
enum module_state state;
6060
size_t new_cfg_size; /**< size of new module config data */
6161
void *runtime_params;
62-
struct module_memory memory; /**< memory allocated by module */
62+
struct module_resources resources; /**< resources allocated by module */
6363
struct module_processing_data mpd; /**< shared data comp <-> module */
6464
#endif /* SOF_MODULE_PRIVATE */
6565
};

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,19 @@ struct module_param {
117117

118118
/**
119119
* \struct module_memory
120-
* \brief module memory block - used for every memory allocated by module
120+
* \brief module resources block - used for module allocation records
121+
* The allocations are recorded so that they can be automatically freed
122+
* when the module unloads.
123+
*/
124+
struct module_resources {
125+
struct list_item mem_list; /**< Allocad memory containers */
126+
struct list_item free_cont_list; /**< Unused memory containers */
127+
struct list_item cont_chunk_list; /**< Memory container chunks */
128+
};
129+
130+
/**
131+
* \struct module_memory
132+
* \brief module memory container - used for every memory allocated by module
121133
*/
122134
struct module_memory {
123135
void *ptr; /**< A pointr to particular memory block */

0 commit comments

Comments
 (0)