-
Notifications
You must be signed in to change notification settings - Fork 325
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
llext: use the new inspection API #9831
Conversation
2606529
to
4c8d65c
Compare
21dcc83
to
e625dcb
Compare
c3108a6
to
23478ef
Compare
return ret; | ||
} | ||
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset, | ||
(const uint8_t *)region_addr + s_offset, shdr->sh_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we still need the .bss
check, don't we?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, that is not needed anymore. Only sections for the requested region will be considered by the check above, so BSS will always be skipped regardless of its placement in memory.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nnno, I think this is breaking SOF. Look at
sof/src/library_manager/llext_manager.c
Lines 150 to 158 in 09f4d94
if ((uintptr_t)bss_addr + bss_size == (uintptr_t)va_base_data && | |
!((uintptr_t)bss_addr & (PAGE_SZ - 1))) { | |
/* .bss directly in front of writable data and properly aligned, prepend */ | |
va_base_data = bss_addr; | |
data_size += bss_size; | |
} else if ((uintptr_t)bss_addr == (uintptr_t)va_base_data + | |
ALIGN_UP(data_size, bss_align)) { | |
/* .bss directly behind writable data, append */ | |
data_size += bss_size; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I do not understand how that is relevant. The changes did not impact the mapping with the vma
and size
parameters in any way, so while mapping writable data, the same "BSS-and-DATA" area is mapped in one go, as before.
Instead of having to rely only on the address, the copy code now checks the actual region LLEXT mapped each section to. So, yes, previously that check was needed, but now LLEXT will report .bss
in LLEXT_MEM_BSS
and that loop will definitely ignore it when looking for LLEXT_MEM_DATA
.
EDIT: CI is flaky, but the LNL + HDA test passed again. Can you describe a possible failing situation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pillo79 I think you're right. The thing is that even now calls to llext_manager_load_data_from_storage()
pass two (related but) different "memory descriptors:" (1) memory that has to be mapped and (2) memory, that has to be copied. Before your PR the call for .bss + .data was
sof/src/library_manager/llext_manager.c
Lines 183 to 184 in a895eb2
ret = llext_manager_load_data_from_storage(ext, va_base_data, ext->mem[LLEXT_MEM_DATA], | |
data_size, SYS_MM_MEM_PERM_RW); |
if (ret >= 0) { | ||
llext_get_section_info(ldr, *llext, ret, &hdr, NULL, NULL); | ||
*mod_manifest = llext_peek(ldr, hdr->sh_offset); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this now better than a single call to llext_find_section(llext_find_section()`?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention for LLEXT is to ask for deprecation of llext_find_section
, as it has a fundamental flaw - it does not provide the section length, so it's basically impossible to use it safely.
The new functions in the inspection API expose all details (when useful to the application) at the same runtime cost, and require the user to provide both ldr
and ext
parameters, allowing future freedom in Zephyr for internal LLEXT structure management.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lyakh I question the comments on "unneeded changes". Since the same areas are otherwise heavily modified, IMO those tiny clarity improvements will not have any additional impact on other outstanding work.
But that's just my point of view, will of course revert them if you feel they are blockers.
return ret; | ||
} | ||
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset, | ||
(const uint8_t *)region_addr + s_offset, shdr->sh_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, that is not needed anymore. Only sections for the requested region will be considered by the check above, so BSS will always be skipped regardless of its placement in memory.
if (ret >= 0) { | ||
llext_get_section_info(ldr, *llext, ret, &hdr, NULL, NULL); | ||
*mod_manifest = llext_peek(ldr, hdr->sh_offset); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My intention for LLEXT is to ask for deprecation of llext_find_section
, as it has a fundamental flaw - it does not provide the section length, so it's basically impossible to use it safely.
The new functions in the inspection API expose all details (when useful to the application) at the same runtime cost, and require the user to provide both ldr
and ext
parameters, allowing future freedom in Zephyr for internal LLEXT structure management.
llext_manager_link() is only interested in the 'llext_loader' part of the 'llext_buf_loader' structure. This patch refactors the code to pass a pointer to the llext_loader directly, making the code more readable. In preparation for the new inspection API, this patch also changes the checks for the buildinfo and mod_manifest pointers to be more explicit. No functional change is intended. Signed-off-by: Luca Burelli <[email protected]>
For inspection API to work, it is imperative to keep the LLEXT loader object available. This patch adds a pointer to the full loader object in the lib_manager_module structure. The loader object is allocated once and never freed. Signed-off-by: Luca Burelli <[email protected]>
23478ef
to
09f4d94
Compare
Applied initial notes from @lyakh after a Discord chat. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks correct, taking it for a short test before approving
return ret; | ||
} | ||
ret = memcpy_s((__sparse_force void *)shdr->sh_addr, size - s_offset, | ||
(const uint8_t *)region_addr + s_offset, shdr->sh_size); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pillo79 I think you're right. The thing is that even now calls to llext_manager_load_data_from_storage()
pass two (related but) different "memory descriptors:" (1) memory that has to be mapped and (2) memory, that has to be copied. Before your PR the call for .bss + .data was
sof/src/library_manager/llext_manager.c
Lines 183 to 184 in a895eb2
ret = llext_manager_load_data_from_storage(ext, va_base_data, ext->mem[LLEXT_MEM_DATA], | |
data_size, SYS_MM_MEM_PERM_RW); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some further testing turns out, that a bit more work is needed
This patch converts the llext_manager to use the new LLEXT inspection API. The new API allows to get information about sections and regions without the need to access the internal structures of the LLEXT loader, decoupling SOF and LLEXT code and making it easier to maintain. NOTE: Once loaded the first time, the extensions are never unloaded, so the inspection data is also never freed. If this behavior needs to be modified to allow extensions to be fully removed from memory, the inspection data in the loader must be freed as well by calling the llext_free_inspection_data() function before the final llext_unload(). Signed-off-by: Luca Burelli <[email protected]>
09f4d94
to
c449256
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
issue fixed, and thanks for documenting it
This PR tries to improve SOF by minimizing its dependency on LLEXT internals.
Instead of relying on direct field access, the code in
llext_manager.c
is refactored to use a set of new, stable LLEXT APIs that expose the same information. These code changes should have no measurable effects in the rest of SOF.LNL test passed as of commit 23478ef.