Skip to content

Conversation

@lyakh
Copy link
Collaborator

@lyakh lyakh commented May 23, 2025

Resuming after D3 currently reloads all LLEXT modules / libraries, which wastes time and can be avoided by re-using data stored in DRAM. This PR adds that functionality. It depends on zephyrproject-rtos/zephyr#90400 and also needs the Linux driver to avoid re-sending modules. @ujfalusi I used a simple diff for testing:

diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 49085ca7b46b..4dbf41b73e4d 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -573,14 +573,13 @@ int hda_dsp_ipc4_load_library(struct snd_sof_dev *sdev,
 			      struct sof_ipc4_fw_library *fw_lib, bool reload)
 {
 	struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
-	struct sof_ipc4_fw_data *ipc4_data = sdev->private;
 	struct hdac_ext_stream *hext_stream;
 	struct firmware stripped_firmware;
 	struct sof_ipc4_msg msg = {};
 	int ret, ret1;
 
 	/* if IMR booting is enabled and fw context is saved for D3 state, skip the loading */
-	if (reload && hda->booted_from_imr && ipc4_data->fw_context_save)
+	if (reload && hda->booted_from_imr)
 		return 0;
 
 	/* the fw_lib has been verified during loading, we can trust the validity here */

@ujfalusi
Copy link
Contributor

@lyakh, how does the kernel knows that the booted firmware saves the library context thus no need to re-load the libraries?
What shall the kernel do (and how it might know it) if the lib manager context restore fails and it needs to re-load the libraries?

Can we send flag(s) via FW_READY for example? Or the context restore happens after the firmware has sent the FW_READY?

Copy link
Collaborator

@kv2019i kv2019i left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No blockers, some questions in line.

return IPC4_BUSY;
}

ret = llext_manager_store_to_dram();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this play with full CONTEXT_SAVE feature? If full SRAM is saved, then this is redundant, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, need to add that

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any update here ?

@@ -0,0 +1,308 @@
// SPDX-License-Identifier: BSD-3-Clause
//
// Copyright(c) 2025 Intel Corporation. All rights reserved.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We omit the "all rights reserved" nowadays

@lyakh
Copy link
Collaborator Author

lyakh commented May 26, 2025

Can we send flag(s) via FW_READY for example? Or the context restore happens after the firmware has sent the FW_READY?

@ujfalusi if this comment is correct 5e6ae48#diff-4287fd67d00ed77ae6296c02fa3a29e7f113fe39a7c488846b9e38cdb46447ffR194 then yes, in the present form restoring module context takes place before sending "ready" to the host, so it should be possible to adjust that message if needed

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good stuff, in general could do with more inline comments.

lib_manager_dram.ext_lib = *_ext_lib;
for (i = 0, n_lib = 0, n_mod = 0, n_llext = 0, n_sect = 0, n_sym = 0;
i < ARRAY_SIZE(_ext_lib->desc); i++)
if (_ext_lib->desc[i]) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (!) continue ? reduces the indentation.

n_lib++;
n_mod += _ext_lib->desc[i]->n_mod;
for (k = 0; k < _ext_lib->desc[i]->n_mod; k++)
if (_ext_lib->desc[i]->mod[k].ebl) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto if(!) continue


/* Also flatten dependency lists */
int ret = llext_relink_dependency(lib_manager_dram.llext, n_llext);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

newline needed ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood unfortunately yes, otherwise something (checkpatch?) will complain, that it wants to have a blank line between declarations and code

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ignore it now - it can be removed, this stuff is caught in review now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ignore it now - it can be removed, this stuff is caught in review now.

@lgirdwood sorry, which review? Some tool is now complaining about these blank lines?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no I mean us human reviewers. I pattern match the if() {block} together without the new line. new line here makes it look like another unrelated block to the if condition.

@lyakh
Copy link
Collaborator Author

lyakh commented Jun 2, 2025

thesofproject/linux#5430 is merged, this can now be tested, now waiting for zephyrproject-rtos/zephyr#90400

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, some opens but lets get the Zephyr part merged 1st.

return IPC4_BUSY;
}

ret = llext_manager_store_to_dram();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any update here ?

@lyakh
Copy link
Collaborator Author

lyakh commented Jun 11, 2025

zephyrproject-rtos/zephyr#90400 got merged, now this becomes mergeable too

lyakh added 6 commits June 11, 2025 11:55
The authentication context, used by the library manager to check
module signature, is fully reinitialised and released for each
loaded module, no need to store it permanently.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
L3 heap allocates memory in DRAM. Usually this is done to preserve
contents over DSP reset. This patch adds a method to do that.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
lib_manager.h uses some types without including respective headers or
declaring them. Fix two such omissions.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
If module registration fails, lib_manager_load_library() will jump to
"cleanup" where it will attempt to check whether a module is an LLEXT
but in such cases the "mod" pointer can be NULL, which will cause an
exception. Check the error code before checking the module type.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
llext_get_section_info() shouldn't fail when called with a valid
section number, but it's still cleaner to check its success and
skip the section in case of an error.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
When failing llext_manager_link_single() should return a negative
error code, not 0.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
Updpate Zephyr to include

4de0c9abc0e SoC: Intel: ADSP: ACE30: add .imrdata to MMU definitions
5f4177b47c9 llext: add context save and restore
d8195c05c78 llext: rename _llext_list to llext_list

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
@lyakh lyakh force-pushed the llext branch 2 times, most recently from b17e512 to 46afc5a Compare June 12, 2025 06:59
@lyakh
Copy link
Collaborator Author

lyakh commented Jun 12, 2025

for the record. Having enabled partial restore shortens resume time as follows: before enabling

[  392.474926] kernel: snd_sof:snd_sof_boot_dsp_firmware: sof-audio-pci-intel-ptl 0000:00:1f.3: Booting DSP firmware
...
[  392.639208] kernel: snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-ptl 0000:00:1f.3: ipc rx      : 0x1b080000|0x0: GLB_NOTIFICATION|FW_READY

i.e. 164ms, after:

[ 2519.523002] kernel: snd_sof:snd_sof_boot_dsp_firmware: sof-audio-pci-intel-ptl 0000:00:1f.3: Booting DSP firmware
...
[ 2519.598833] kernel: snd_sof:sof_ipc4_log_header: sof-audio-pci-intel-ptl 0000:00:1f.3: ipc rx      : 0x1b088000|0x0: GLB_NOTIFICATION|FW_READY

i.e. 76ms

Copy link
Member

@lgirdwood lgirdwood left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One open.

CONFIG_SYS_CLOCK_TICKS_PER_SEC=12000

# Zephyr / power settings
CONFIG_ADSP_IMR_CONTEXT_SAVE=y
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a Kconfig to select partial context save ?

Copy link
Collaborator Author

@lyakh lyakh Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need a Kconfig to select partial context save ?

@lgirdwood currently we have the following configuration possibilities:

  1. no LLEXT - obviously LLEXT selective context saving isn't used
  2. LLEXT and full context saving - LLEXT selective context saving isn't used
  3. otherwise - if LLEXT is enabled and full context saving isn't enabled, then LLEXT selective context saving is used.

So you'd like to also be able to select
4. LLEXT but no context saving - LLEXT reloading when booting

I didn't add a Kconfig option for this because why would anyone want to disable this? It almost looks like a fix instead of a new feature - we have LLEXT modules in DRAM, reloading them instead of reusing sounds more like a bug than a viable option to me. But if needed, sure, we can make this configurable. Also, there's a Zephyr option that this depends on: CONFIG_LLEXT_EXPERIMENTAL - without it this will fail, but it might to fail completely, haven't checked that

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lgirdwood with the new version one can disable CONFIG_LLEXT_EXPERIMENTAL and return to the old behaviour - reloading libraries on each resume

Currently when resuming from D3 we lose the complete LLEXT context,
which forces SOF to reload all the libraries, which costs time. This
isn't necessary, because the libraries are stored in DRAM, which
preserves its contents across DSP reset. Instead of reloading save
LLEXT context before power down and reload it when resuming.

Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
CONFIG_HEAP_MEM_POOL_SIZE=8192
CONFIG_LLEXT=y
CONFIG_LLEXT_STORAGE_WRITABLE=y
CONFIG_LLEXT_EXPERIMENTAL=y
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why call it experimental? Perhaps LLEXT_SAVE_RESTORE makes better sense?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ranj063 we don't, Zephyr does. This option has recently been added to Zephyr to support our partial LLEXT restore, but the way how we added it there isn't perfectly clean. It's hardly usable by other LLEXT users, it's almost SOF-specific, therefore it's been decided to mark it "experimental" until a proper universal solution replaces it.

@kv2019i
Copy link
Collaborator

kv2019i commented Jul 2, 2025

@lyakh Have you checked the PM-with-audio fail in https://sof-ci.01.org/sofpr/PR10028/build13381/devicetest/index.html ? Other tests (that we have available now) seem good.

@kv2019i
Copy link
Collaborator

kv2019i commented Jul 2, 2025

The check-suspend-resume-with-playback-5.sh fail is suspicious, let's rerun the test. This PR should not have any impact, but the Zephyr update could bring in some new problem. https://sof-ci.01.org/sofpr/PR10028/build13381/devicetest/index.html?model=PTLH_RVP_NOCODEC&testcase=check-suspend-resume-with-playback-5

@kv2019i
Copy link
Collaborator

kv2019i commented Jul 2, 2025

SOFCI TEST

@kv2019i
Copy link
Collaborator

kv2019i commented Jul 2, 2025

check-suspend-resume-with-playback-5.sh fail not related to this PR. It has been seen with baseline (albeit with low repro rate) and the rerun of tests today with this PR didn't hit the failure. Proceeding with merge.

@kv2019i kv2019i merged commit 60e7a0a into thesofproject:main Jul 2, 2025
23 of 48 checks passed
@lyakh lyakh deleted the llext branch July 2, 2025 12:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants