kernel: bypass k_heap_free() in k_free() to avoid scheduler locking#107146
kernel: bypass k_heap_free() in k_free() to avoid scheduler locking#107146npitre wants to merge 3 commits intozephyrproject-rtos:mainfrom
Conversation
d924960 to
99dcc5b
Compare
|
This PR has been significantly reworked. The previous approach introduced The new approach is much simpler: The one subtlety: since The |
This partially reverts commit 9cef0da ("kernel: avoid recursive scheduler lock in k_heap_free path"), keeping only the sched.c changes (z_unpend_all_locked / z_unpend_all refactoring). The _sched_locked variants of k_free, k_heap_free, k_msgq_cleanup, k_stack_cleanup and the sched_locked parameter plumbing through unref_check were an overcomplicated approach. A simpler fix follows. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
k_free() now goes directly to sys_heap_free() under heap->lock, bypassing k_heap_free() and its z_unpend_all() call. This is symmetric with z_alloc_helper() which already bypasses k_heap_alloc() to go directly to sys_heap_*(). This avoids any scheduler lock involvement in the k_free() path, eliminating the recursive _sched_spinlock issue when k_free() is called from halt_thread() during thread abort with CONFIG_USERSPACE and CONFIG_DYNAMIC_OBJECTS. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
k_free() bypasses k_heap_free() to avoid scheduler lock involvement, going directly to sys_heap_free() instead. This means nothing in kheap.c may have any callers, and since it is in a library linked without --whole-archive, the linker may discard it entirely. However, kheap.c contains a SYS_INIT handler that initializes all statically defined k_heap objects (those created with K_HEAP_DEFINE). Without it, heaps such as the system heap or those used as thread resource pools via k_thread_heap_assign() are never initialized: their internal sys_heap pointer remains NULL, causing a crash on the first allocation. This can be reproduced without this commit with e.g.: west build -b qemu_cortex_a53 tests/kernel/poll Force kheap.o into the link by adding a __used reference to k_heap_init in mempool.c. This is enough to pull in kheap.o and its SYS_INIT registration. Unused functions from kheap.o are still garbage collected. Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
99dcc5b to
efefad5
Compare
|



Simpler alternative to the approach taken in #106792.
k_free()now bypassesk_heap_free()entirely, going directly tosys_heap_free()underheap->lock. This is symmetric withz_alloc_helper()which already bypassesk_heap_alloc()to godirectly to
sys_heap_*().This eliminates scheduler lock involvement in the
k_free()path,avoiding the recursive
_sched_spinlockissue whenk_free()iscalled from
halt_thread()during thread abort withCONFIG_USERSPACEandCONFIG_DYNAMIC_OBJECTS, without requiringany
_sched_lockedfunction variants or extra parameters.Fixes #106659