Skip to content

Commit 5a14518

Browse files
lyakhkv2019i
authored andcommitted
llext: fix save-restore with no initialized modules
LLEXT save-restore to DRAM had a bug: if the DSP is powered off with loaded LLEXT modules, none of which was used, context restoration was performed incorrectly, leading to inability to use LLEXT after the next boot. This patch fixes that bug. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
1 parent 53df9fb commit 5a14518

File tree

1 file changed

+38
-26
lines changed

1 file changed

+38
-26
lines changed

src/library_manager/llext_manager_dram.c

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct lib_manager_dram_storage {
2323
struct llext_elf_sect_map *sect;
2424
struct llext_symbol *sym;
2525
unsigned int n_llext;
26+
unsigned int n_mod;
2627
};
2728

2829
/*
@@ -147,6 +148,8 @@ int llext_manager_store_to_dram(void)
147148
}
148149

149150
lib_manager_dram.n_llext = n_llext;
151+
lib_manager_dram.n_mod = n_mod;
152+
150153
/* Make sure, that the data is actually in the DRAM, not just in data cache */
151154
dcache_writeback_region((__sparse_force void __sparse_cache *)&lib_manager_dram,
152155
sizeof(lib_manager_dram));
@@ -162,26 +165,33 @@ int llext_manager_restore_from_dram(void)
162165

163166
struct ext_library *_ext_lib = ext_lib_get();
164167
unsigned int i, j, k, n_mod, n_llext, n_sect, n_sym;
168+
struct llext_loader **ldr;
169+
struct llext **llext;
165170

166-
if (!lib_manager_dram.n_llext || !lib_manager_dram.ctx) {
171+
if (!lib_manager_dram.n_mod || !lib_manager_dram.ctx) {
167172
tr_dbg(&lib_manager_tr, "No modules saved");
168173
dcache_writeback_region((__sparse_force void __sparse_cache *)&lib_manager_dram,
169174
sizeof(lib_manager_dram));
170175
return 0;
171176
}
172177

173-
/* arrays of pointers for llext_restore() */
174-
void **ptr_array = rmalloc(SOF_MEM_FLAG_KERNEL,
175-
sizeof(*ptr_array) * lib_manager_dram.n_llext * 2);
176-
177-
if (!ptr_array)
178-
return -ENOMEM;
179-
180-
struct llext_loader **ldr = (struct llext_loader **)ptr_array;
181-
struct llext **llext = (struct llext **)(ptr_array + lib_manager_dram.n_llext);
182-
183178
*_ext_lib = lib_manager_dram.ext_lib;
184179

180+
if (lib_manager_dram.n_llext) {
181+
/* arrays of pointers for llext_restore() */
182+
void **ptr_array = rmalloc(SOF_MEM_FLAG_KERNEL,
183+
sizeof(*ptr_array) * lib_manager_dram.n_llext * 2);
184+
185+
if (!ptr_array)
186+
return -ENOMEM;
187+
188+
ldr = (struct llext_loader **)ptr_array;
189+
llext = (struct llext **)(ptr_array + lib_manager_dram.n_llext);
190+
} else {
191+
ldr = NULL;
192+
llext = NULL;
193+
}
194+
185195
/* The external loop walks all the libraries */
186196
for (i = 0, j = 0, n_mod = 0, n_llext = 0, n_sect = 0, n_sym = 0;
187197
i < ARRAY_SIZE(_ext_lib->desc); i++) {
@@ -262,26 +272,28 @@ int llext_manager_restore_from_dram(void)
262272
_ext_lib->desc[i] = ctx;
263273
}
264274

265-
/* Let Zephyr restore extensions and its own internal bookkeeping */
266-
int ret = llext_restore(llext, ldr, lib_manager_dram.n_llext);
275+
if (lib_manager_dram.n_llext) {
276+
/* Let Zephyr restore extensions and its own internal bookkeeping */
277+
int ret = llext_restore(llext, ldr, lib_manager_dram.n_llext);
267278

268-
if (ret < 0) {
269-
tr_err(&lib_manager_tr, "Zephyr failed to restore: %d", ret);
270-
goto nomem;
271-
}
279+
if (ret < 0) {
280+
tr_err(&lib_manager_tr, "Zephyr failed to restore: %d", ret);
281+
goto nomem;
282+
}
272283

273-
/* Rewrite to correct LLEXT pointers, created by Zephyr */
274-
for (i = 0, n_llext = 0; i < ARRAY_SIZE(_ext_lib->desc); i++) {
275-
struct lib_manager_mod_ctx *ctx = _ext_lib->desc[i];
284+
/* Rewrite to correct LLEXT pointers, created by Zephyr */
285+
for (i = 0, n_llext = 0; i < ARRAY_SIZE(_ext_lib->desc); i++) {
286+
struct lib_manager_mod_ctx *ctx = _ext_lib->desc[i];
276287

277-
if (!ctx)
278-
continue;
288+
if (!ctx)
289+
continue;
279290

280-
struct lib_manager_module *mod = ctx->mod;
291+
struct lib_manager_module *mod = ctx->mod;
281292

282-
for (k = 0; k < ctx->n_mod; k++) {
283-
if (mod[k].llext)
284-
mod[k].llext = llext[n_llext++];
293+
for (k = 0; k < ctx->n_mod; k++) {
294+
if (mod[k].llext)
295+
mod[k].llext = llext[n_llext++];
296+
}
285297
}
286298
}
287299

0 commit comments

Comments
 (0)