Skip to content

Commit 03e8bd2

Browse files
committed
lib-manager: store segment sizes locally
Currently segment sizes are calculated from page counts, stored in module manifests. This restricts us to only using page size-aligned segment sizes. In case of not page size-aligned ELF sections this can lead to wasted memory. To avoid this store segment sizes in full-size per-module variables to access them at any time. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent ec1864f commit 03e8bd2

2 files changed

Lines changed: 63 additions & 52 deletions

File tree

src/include/sof/lib_manager.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,11 @@ struct ipc_lib_msg {
7878
struct list_item list;
7979
};
8080

81+
struct lib_manager_mod_ctx;
82+
8183
struct ext_library {
8284
struct k_spinlock lock; /* last locking CPU record */
83-
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
85+
struct lib_manager_mod_ctx *desc[LIB_MANAGER_MAX_LIBS];
8486
uint32_t mods_exec_load_cnt;
8587
struct ipc_lib_msg *lib_notif_pool;
8688
uint32_t lib_notif_count;

src/library_manager/lib_manager.c

Lines changed: 60 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,42 @@ struct lib_manager_dma_ext {
4747

4848
static struct ext_library loader_ext_lib;
4949

50+
struct lib_manager_mod_ctx {
51+
struct sof_man_fw_desc *desc;
52+
size_t segment_size[3];
53+
};
54+
55+
static struct lib_manager_mod_ctx *lib_manager_get_mod_ctx(int module_id)
56+
{
57+
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
58+
struct ext_library *_ext_lib = ext_lib_get();
59+
60+
return _ext_lib->desc[lib_id];
61+
}
62+
63+
struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id)
64+
{
65+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
66+
uint8_t *buffptr = (uint8_t *)(ctx ? ctx->desc : NULL);
67+
68+
if (!buffptr)
69+
return NULL;
70+
return (struct sof_man_fw_desc *)(buffptr + SOF_MAN_ELF_TEXT_OFFSET);
71+
}
72+
73+
static void lib_manager_update_sof_ctx(struct sof_man_fw_desc *desc, uint32_t lib_id)
74+
{
75+
struct ext_library *_ext_lib = ext_lib_get();
76+
/* Never freed, will panic if fails */
77+
struct lib_manager_mod_ctx *ctx = rmalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM,
78+
sizeof(*ctx));
79+
80+
ctx->desc = desc;
81+
82+
_ext_lib->desc[lib_id] = ctx;
83+
/* TODO: maybe need to call dcache_writeback here? */
84+
}
85+
5086
#if IS_ENABLED(CONFIG_MM_DRV)
5187

5288
#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
@@ -155,23 +191,20 @@ static void lib_manager_unload_aux(struct sof_man_module *mod,
155191
static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mod,
156192
struct sof_man_fw_desc *desc)
157193
{
158-
struct ext_library *ext_lib = ext_lib_get();
159194
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
160-
size_t load_offset = (size_t)((void *)ext_lib->desc[lib_id]);
195+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
196+
uint8_t *load_base = (uint8_t *)ctx->desc;
161197
void __sparse_cache *va_base_text = (void __sparse_cache *)
162198
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
163-
void *src_txt = (void *)(mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset + load_offset);
164-
size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length;
199+
void *src_txt = (void *)(load_base + mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset);
200+
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
165201
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
166202
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
167-
void *src_rodata =
168-
(void *)(mod->segment[SOF_MAN_SEGMENT_RODATA].file_offset + load_offset);
169-
size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length;
203+
void *src_rodata = (void *)(load_base +
204+
mod->segment[SOF_MAN_SEGMENT_RODATA].file_offset);
205+
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
170206
int ret;
171207

172-
st_text_size = st_text_size * PAGE_SZ;
173-
st_rodata_size = st_rodata_size * PAGE_SZ;
174-
175208
/* Copy Code */
176209
ret = lib_manager_load_data_from_storage(va_base_text, src_txt, st_text_size,
177210
SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC);
@@ -203,18 +236,16 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
203236
static int lib_manager_unload_module(uint32_t module_id, struct sof_man_module *mod,
204237
struct sof_man_fw_desc *desc)
205238
{
239+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
206240
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
207241
void __sparse_cache *va_base_text = (void __sparse_cache *)
208242
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
209-
size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length;
243+
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
210244
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
211245
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
212-
size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length;
246+
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
213247
int ret;
214248

215-
st_text_size = st_text_size * PAGE_SZ;
216-
st_rodata_size = st_rodata_size * PAGE_SZ;
217-
218249
ret = lib_manager_align_unmap(va_base_text, st_text_size);
219250
if (ret < 0)
220251
return ret;
@@ -253,15 +284,10 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module
253284
static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id,
254285
uint32_t is_pages, struct sof_man_module *mod)
255286
{
287+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
288+
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
256289
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
257290
instance_id, mod);
258-
size_t bss_size;
259-
260-
if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT)
261-
bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length * PAGE_SZ;
262-
else
263-
bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length /
264-
mod->instance_max_count) * PAGE_SZ;
265291

266292
if ((is_pages * PAGE_SZ) > bss_size) {
267293
tr_err(&lib_manager_tr,
@@ -282,16 +308,11 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins
282308
static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id,
283309
struct sof_man_module *mod)
284310
{
285-
size_t bss_size;
311+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
312+
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
286313
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
287314
instance_id, mod);
288315

289-
if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT)
290-
bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length * PAGE_SZ;
291-
else
292-
bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length /
293-
mod->instance_max_count) * PAGE_SZ;
294-
295316
/* Unmap bss memory. */
296317
return lib_manager_align_unmap(va_base, bss_size);
297318
}
@@ -306,19 +327,26 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
306327
int ret;
307328
uint32_t module_id = IPC4_MOD_ID(ipc_config->id);
308329
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
330+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
309331

310-
tr_dbg(&lib_manager_tr, "lib_manager_allocate_module(): mod_id: %#x",
311-
ipc_config->id);
332+
tr_dbg(&lib_manager_tr, "lib_manager_allocate_module(): mod_id: %#x", module_id);
312333

313334
desc = lib_manager_get_library_module_desc(module_id);
314-
if (!desc) {
335+
if (!ctx || !desc) {
315336
tr_err(&lib_manager_tr,
316337
"lib_manager_allocate_module(): failed to get module descriptor");
317338
return 0;
318339
}
319340

320341
mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
321342

343+
for (unsigned int i = 0; i < ARRAY_SIZE(ctx->segment_size); i++) {
344+
ctx->segment_size[i] = mod->segment[i].flags.r.length * PAGE_SZ;
345+
346+
if (i == SOF_MAN_SEGMENT_BSS && mod->type.load_type != SOF_MAN_MOD_TYPE_LLEXT)
347+
ctx->segment_size[i] /= mod->instance_max_count;
348+
}
349+
322350
ret = lib_manager_load_module(module_id, mod, desc);
323351
if (ret < 0)
324352
return 0;
@@ -391,25 +419,6 @@ void lib_manager_init(void)
391419
sof->ext_library = &loader_ext_lib;
392420
}
393421

394-
struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id)
395-
{
396-
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
397-
struct ext_library *_ext_lib = ext_lib_get();
398-
uint8_t *buffptr = (uint8_t *)_ext_lib->desc[lib_id];
399-
400-
if (!buffptr)
401-
return NULL;
402-
return (struct sof_man_fw_desc *)(buffptr + SOF_MAN_ELF_TEXT_OFFSET);
403-
}
404-
405-
static void lib_manager_update_sof_ctx(struct sof_man_fw_desc *desc, uint32_t lib_id)
406-
{
407-
struct ext_library *_ext_lib = ext_lib_get();
408-
409-
_ext_lib->desc[lib_id] = desc;
410-
/* TODO: maybe need to call here dcache_writeback here? */
411-
}
412-
413422
#if CONFIG_INTEL_MODULES
414423
int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id)
415424
{

0 commit comments

Comments
 (0)