Skip to content

Commit bd9a877

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 bd9a877

2 files changed

Lines changed: 59 additions & 47 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: 56 additions & 46 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
@@ -158,20 +194,18 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
158194
struct ext_library *ext_lib = ext_lib_get();
159195
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
160196
size_t load_offset = (size_t)((void *)ext_lib->desc[lib_id]);
197+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
161198
void __sparse_cache *va_base_text = (void __sparse_cache *)
162199
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
163200
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;
201+
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
165202
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
166203
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
167204
void *src_rodata =
168205
(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;
206+
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
170207
int ret;
171208

172-
st_text_size = st_text_size * PAGE_SZ;
173-
st_rodata_size = st_rodata_size * PAGE_SZ;
174-
175209
/* Copy Code */
176210
ret = lib_manager_load_data_from_storage(va_base_text, src_txt, st_text_size,
177211
SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC);
@@ -203,18 +237,16 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
203237
static int lib_manager_unload_module(uint32_t module_id, struct sof_man_module *mod,
204238
struct sof_man_fw_desc *desc)
205239
{
240+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
206241
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
207242
void __sparse_cache *va_base_text = (void __sparse_cache *)
208243
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
209-
size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length;
244+
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
210245
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
211246
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
212-
size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length;
247+
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
213248
int ret;
214249

215-
st_text_size = st_text_size * PAGE_SZ;
216-
st_rodata_size = st_rodata_size * PAGE_SZ;
217-
218250
ret = lib_manager_align_unmap(va_base_text, st_text_size);
219251
if (ret < 0)
220252
return ret;
@@ -253,15 +285,10 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module
253285
static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id,
254286
uint32_t is_pages, struct sof_man_module *mod)
255287
{
288+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
289+
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
256290
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
257291
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;
265292

266293
if ((is_pages * PAGE_SZ) > bss_size) {
267294
tr_err(&lib_manager_tr,
@@ -282,16 +309,11 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins
282309
static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id,
283310
struct sof_man_module *mod)
284311
{
285-
size_t bss_size;
312+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
313+
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
286314
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
287315
instance_id, mod);
288316

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-
295317
/* Unmap bss memory. */
296318
return lib_manager_align_unmap(va_base, bss_size);
297319
}
@@ -306,19 +328,26 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
306328
int ret;
307329
uint32_t module_id = IPC4_MOD_ID(ipc_config->id);
308330
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
331+
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
309332

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

313335
desc = lib_manager_get_library_module_desc(module_id);
314-
if (!desc) {
336+
if (!ctx || !desc) {
315337
tr_err(&lib_manager_tr,
316338
"lib_manager_allocate_module(): failed to get module descriptor");
317339
return 0;
318340
}
319341

320342
mod = (struct sof_man_module *)((char *)desc + SOF_MAN_MODULE_OFFSET(entry_index));
321343

344+
for (unsigned int i = 0; i < ARRAY_SIZE(ctx->segment_size); i++) {
345+
ctx->segment_size[i] = mod->segment[i].flags.r.length * PAGE_SZ;
346+
347+
if (i == SOF_MAN_SEGMENT_BSS && mod->type.load_type != SOF_MAN_MOD_TYPE_LLEXT)
348+
ctx->segment_size[i] /= mod->instance_max_count;
349+
}
350+
322351
ret = lib_manager_load_module(module_id, mod, desc);
323352
if (ret < 0)
324353
return 0;
@@ -391,25 +420,6 @@ void lib_manager_init(void)
391420
sof->ext_library = &loader_ext_lib;
392421
}
393422

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-
413423
#if CONFIG_INTEL_MODULES
414424
int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id)
415425
{

0 commit comments

Comments
 (0)