-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Is your enhancement proposal related to a problem? Please describe.
I recently put up a PR adding x86 support. On x86, if demand paging is on, which usually means CONFIG_LINKER_USE_PINNED_SECTION is on too, symbols that need to be pinned in memory (such as syscalls) will be put in .pinned_* sections during linking. During boot, these sections are marked "pinned" in memory i.e. they will never be paged.
Tom (@teburd) and I were wondering if we wanted to make that happen for extensions. Since we load the sections ourselves, they aren't actually "pinned". Do we want them to be? I think we'd have to call mark_linker_section_pinned...
To see what sorts of functions / data go in pinned sections, search "_pinned_func" / "_pinned_data". syscalls_ext.c / threads_kernel_objects_ext.c both produced .pinned_* sections.
$ west build -p -b qemu_x86/atom/virt tests/subsys/llext
$ readelf -r build/llext/threads_kernel_objects.llext
...
Relocation section '.rel.pinned_text' at offset 0xb1c contains 7 entries:
Offset Info Type Sym.Value Sym. Name
00000007 00000302 R_386_PC32 00000000 z_impl_device_get[...]
00000019 00000402 R_386_PC32 00000000 z_impl_device_is_ready
00000049 00000502 R_386_PC32 00000000 z_impl_k_thread_create
00000061 00000602 R_386_PC32 00000000 z_impl_k_thread_join
00000073 00000702 R_386_PC32 00000000 z_impl_k_wakeup
0000008c 00000802 R_386_PC32 00000000 z_impl_k_sem_take
0000009e 00000902 R_386_PC32 00000000 z_impl_k_sem_give
...
$ readelf -r build/llext/syscalls.llext
...
Relocation section '.rel.pinned_text' at offset 0x3b4 contains 1 entry:
Offset Info Type Sym.Value Sym. Name
00000007 00000302 R_386_PC32 00000000 z_impl_ext_syscall_ok
These sections are admittedly rather small, compared to the MMU page size e.g. CONFIG_MMU_PAGE_SIZE being 0x1000, but I guess for a real extension they could be a lot bigger.
$ readelf -S build/llext/threads_kernel_objects.llext
...
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 5] .pinned_text PROGBITS 00000000 000380 0000aa 00 AX 0 0 1
...
$ readelf -S build/llext/syscalls.llext
...
[ 5] .pinned_text PROGBITS 00000000 000128 000012 00 AX 0 0 1
...
Describe the solution you'd like
I don't have a particular solution I'd like, just raising the issue as an enhancement.
Describe alternatives you've considered
If people don't think extensions should have sections pinned in memory, we don't need to, I guess.
Additional Context
A related problem to keep in mind is the fact that the pinned sections - .pinned_text, .pinned_rodata, .pinned_data, .pinned_bss, and .pinned_noinit - will appear in the extension in the order that the first instance of data or code in that section appears in the extension.c.i (preprocessed) file. This can cause issues, for example when .pinned_text appears such that .rodata is in between it and .text - the LLEXT loader needs .text like sections to be grouped together, and fails with an "overlapping region" error (rodata region inside text region). I worked around this in my PR introducing x86 LLEXT support by just moving up the syscalls_ext.h header include.