Skip to content

Commit

Permalink
lib-manager: store segment sizes locally
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
lyakh committed Jan 19, 2024
1 parent ec1864f commit bd9a877
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 47 deletions.
4 changes: 3 additions & 1 deletion src/include/sof/lib_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,11 @@ struct ipc_lib_msg {
struct list_item list;
};

struct lib_manager_mod_ctx;

struct ext_library {
struct k_spinlock lock; /* last locking CPU record */
struct sof_man_fw_desc *desc[LIB_MANAGER_MAX_LIBS];
struct lib_manager_mod_ctx *desc[LIB_MANAGER_MAX_LIBS];
uint32_t mods_exec_load_cnt;
struct ipc_lib_msg *lib_notif_pool;
uint32_t lib_notif_count;
Expand Down
102 changes: 56 additions & 46 deletions src/library_manager/lib_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,42 @@ struct lib_manager_dma_ext {

static struct ext_library loader_ext_lib;

struct lib_manager_mod_ctx {
struct sof_man_fw_desc *desc;
size_t segment_size[3];
};

static struct lib_manager_mod_ctx *lib_manager_get_mod_ctx(int module_id)
{
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
struct ext_library *_ext_lib = ext_lib_get();

return _ext_lib->desc[lib_id];
}

struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id)
{
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
uint8_t *buffptr = (uint8_t *)(ctx ? ctx->desc : NULL);

if (!buffptr)
return NULL;
return (struct sof_man_fw_desc *)(buffptr + SOF_MAN_ELF_TEXT_OFFSET);
}

static void lib_manager_update_sof_ctx(struct sof_man_fw_desc *desc, uint32_t lib_id)
{
struct ext_library *_ext_lib = ext_lib_get();
/* Never freed, will panic if fails */
struct lib_manager_mod_ctx *ctx = rmalloc(SOF_MEM_ZONE_SYS, 0, SOF_MEM_CAPS_RAM,
sizeof(*ctx));

ctx->desc = desc;

_ext_lib->desc[lib_id] = ctx;
/* TODO: maybe need to call dcache_writeback here? */
}

#if IS_ENABLED(CONFIG_MM_DRV)

#define PAGE_SZ CONFIG_MM_DRV_PAGE_SIZE
Expand Down Expand Up @@ -158,20 +194,18 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
struct ext_library *ext_lib = ext_lib_get();
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
size_t load_offset = (size_t)((void *)ext_lib->desc[lib_id]);
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
void __sparse_cache *va_base_text = (void __sparse_cache *)
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
void *src_txt = (void *)(mod->segment[SOF_MAN_SEGMENT_TEXT].file_offset + load_offset);
size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length;
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
void *src_rodata =
(void *)(mod->segment[SOF_MAN_SEGMENT_RODATA].file_offset + load_offset);
size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length;
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
int ret;

st_text_size = st_text_size * PAGE_SZ;
st_rodata_size = st_rodata_size * PAGE_SZ;

/* Copy Code */
ret = lib_manager_load_data_from_storage(va_base_text, src_txt, st_text_size,
SYS_MM_MEM_PERM_RW | SYS_MM_MEM_PERM_EXEC);
Expand Down Expand Up @@ -203,18 +237,16 @@ static int lib_manager_load_module(uint32_t module_id, struct sof_man_module *mo
static int lib_manager_unload_module(uint32_t module_id, struct sof_man_module *mod,
struct sof_man_fw_desc *desc)
{
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
void __sparse_cache *va_base_text = (void __sparse_cache *)
mod->segment[SOF_MAN_SEGMENT_TEXT].v_base_addr;
size_t st_text_size = mod->segment[SOF_MAN_SEGMENT_TEXT].flags.r.length;
size_t st_text_size = ctx->segment_size[SOF_MAN_SEGMENT_TEXT];
void __sparse_cache *va_base_rodata = (void __sparse_cache *)
mod->segment[SOF_MAN_SEGMENT_RODATA].v_base_addr;
size_t st_rodata_size = mod->segment[SOF_MAN_SEGMENT_RODATA].flags.r.length;
size_t st_rodata_size = ctx->segment_size[SOF_MAN_SEGMENT_RODATA];
int ret;

st_text_size = st_text_size * PAGE_SZ;
st_rodata_size = st_rodata_size * PAGE_SZ;

ret = lib_manager_align_unmap(va_base_text, st_text_size);
if (ret < 0)
return ret;
Expand Down Expand Up @@ -253,15 +285,10 @@ static void __sparse_cache *lib_manager_get_instance_bss_address(uint32_t module
static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t instance_id,
uint32_t is_pages, struct sof_man_module *mod)
{
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
instance_id, mod);
size_t bss_size;

if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT)
bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length * PAGE_SZ;
else
bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length /
mod->instance_max_count) * PAGE_SZ;

if ((is_pages * PAGE_SZ) > bss_size) {
tr_err(&lib_manager_tr,
Expand All @@ -282,16 +309,11 @@ static int lib_manager_allocate_module_instance(uint32_t module_id, uint32_t ins
static int lib_manager_free_module_instance(uint32_t module_id, uint32_t instance_id,
struct sof_man_module *mod)
{
size_t bss_size;
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);
size_t bss_size = ctx->segment_size[SOF_MAN_SEGMENT_BSS];
void __sparse_cache *va_base = lib_manager_get_instance_bss_address(module_id,
instance_id, mod);

if (mod->type.load_type == SOF_MAN_MOD_TYPE_LLEXT)
bss_size = mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length * PAGE_SZ;
else
bss_size = (mod->segment[SOF_MAN_SEGMENT_BSS].flags.r.length /
mod->instance_max_count) * PAGE_SZ;

/* Unmap bss memory. */
return lib_manager_align_unmap(va_base, bss_size);
}
Expand All @@ -306,19 +328,26 @@ uint32_t lib_manager_allocate_module(const struct comp_driver *drv,
int ret;
uint32_t module_id = IPC4_MOD_ID(ipc_config->id);
uint32_t entry_index = LIB_MANAGER_GET_MODULE_INDEX(module_id);
struct lib_manager_mod_ctx *ctx = lib_manager_get_mod_ctx(module_id);

tr_dbg(&lib_manager_tr, "lib_manager_allocate_module(): mod_id: %#x",
ipc_config->id);
tr_dbg(&lib_manager_tr, "lib_manager_allocate_module(): mod_id: %#x", module_id);

desc = lib_manager_get_library_module_desc(module_id);
if (!desc) {
if (!ctx || !desc) {
tr_err(&lib_manager_tr,
"lib_manager_allocate_module(): failed to get module descriptor");
return 0;
}

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

for (unsigned int i = 0; i < ARRAY_SIZE(ctx->segment_size); i++) {
ctx->segment_size[i] = mod->segment[i].flags.r.length * PAGE_SZ;

if (i == SOF_MAN_SEGMENT_BSS && mod->type.load_type != SOF_MAN_MOD_TYPE_LLEXT)
ctx->segment_size[i] /= mod->instance_max_count;
}

ret = lib_manager_load_module(module_id, mod, desc);
if (ret < 0)
return 0;
Expand Down Expand Up @@ -391,25 +420,6 @@ void lib_manager_init(void)
sof->ext_library = &loader_ext_lib;
}

struct sof_man_fw_desc *lib_manager_get_library_module_desc(int module_id)
{
uint32_t lib_id = LIB_MANAGER_GET_LIB_ID(module_id);
struct ext_library *_ext_lib = ext_lib_get();
uint8_t *buffptr = (uint8_t *)_ext_lib->desc[lib_id];

if (!buffptr)
return NULL;
return (struct sof_man_fw_desc *)(buffptr + SOF_MAN_ELF_TEXT_OFFSET);
}

static void lib_manager_update_sof_ctx(struct sof_man_fw_desc *desc, uint32_t lib_id)
{
struct ext_library *_ext_lib = ext_lib_get();

_ext_lib->desc[lib_id] = desc;
/* TODO: maybe need to call here dcache_writeback here? */
}

#if CONFIG_INTEL_MODULES
int lib_manager_register_module(struct sof_man_fw_desc *desc, int module_id)
{
Expand Down

0 comments on commit bd9a877

Please sign in to comment.