casaroli opened a new pull request, #21328: URL: https://github.com/apache/nuttx/pull/21328
## Summary **mm: Do not report the growth of a process heap as a failure.** In the kernel build the heap of a process starts small. When `mm_malloc()` or `mm_memalign()` finds no free chunk that is large enough, the user allocator (`mm/umm_heap/umm_memalign.c`, `umm_realloc.c`; `malloc()`, `zalloc()` and `calloc()` go through `memalign()`) calls `sbrk()` and tries again. This is the normal way for the heap to grow. But `mm_malloc()` reported each of these first attempts as a failed allocation: - With `CONFIG_DEBUG_MM_WARN`, on qemu-armv8a:knsh a thread whose stack makes the heap grow gives two `mm_malloc: WARNING: Allocation failed, size 24584`: the 8 KiB stack must be aligned to 8 KiB (`CONFIG_TLS_ALIGNED`), so `mm_memalign()` asks `mm_malloc()` for the size plus two alignments. Each other growth of a process heap (`malloc()`, `realloc()`) gives one more warning. - With `CONFIG_MM_DUMP_ON_FAILURE`, each of them dumps the heap. - With `CONFIG_MM_PANIC_ON_FAILURE`, each of them causes a panic. `MM_INTERNAL_HEAP()` selects the heaps whose failures `mm_malloc()` reports. In the kernel build (`CONFIG_ARCH_ADDRENV` and `CONFIG_BUILD_KERNEL`) it now leaves out the heap of a process, in the kernel copy and in the user copy of the allocator. The user allocator gives the same warning, and the panic of `CONFIG_MM_PANIC_ON_FAILURE`, when `sbrk()` fails: then the allocation really fails. **Documentation/mm: Describe the growth of a process heap.** One paragraph in `memory_configurations.rst` (the page allocator section): the heap of a process grows with `sbrk()`, a failed search is a normal step, the warning and the panic come only when `sbrk()` fails, and the heap dump on failure applies only to the kernel heap. ## Impact - Flat and protected builds: no change (the new definitions apply only with `CONFIG_ARCH_ADDRENV` and `CONFIG_BUILD_KERNEL`). - Kernel build: no "Allocation failed" warning, heap dump or panic when the heap of a process grows. One warning, and the panic of `CONFIG_MM_PANIC_ON_FAILURE`, when `sbrk()` fails (no free pages or no address space left). - Kernel build: `CONFIG_MM_DUMP_ON_FAILURE` now applies only to the kernel heap. A failed allocation in the heap of a process gives the warning, but no heap dump. - Kernel build with `CONFIG_MM_TLSF_MANAGER`: `mm_tlsf.c` reports no failed allocation, so a failed `sbrk()` now gives the warning and the panic (before: nothing). - No change of an interface or of an allocation; no arch code. ## Testing Test program `heapgrow.c` (POSIX; it counts "Allocation failed" lines in the RAM log, `/dev/kmsg`, between two marker lines): - `grow`: `malloc()` of 256 KiB, `posix_memalign()` of 64 KiB at 64 KiB, `realloc()` to 512 KiB, a thread: no warning; - `spawn`: `posix_spawn()` of a program: no warning; - `fail` (last): `malloc()` of 4 GiB returns NULL and the log has a warning (a real failure is still reported). Base 5c441693fa8. qemu-armv8a:knsh (QEMU with HVF) with `DEBUG_FEATURES`, `DEBUG_WARN`, `DEBUG_MM`, `DEBUG_MM_WARN`, `RAMLOG`, `RAMLOG_SYSLOG` (`/dev/kmsg`), `SYSLOG_MAX_CHANNELS=2`, `SYSLOG_DEFAULT`; one boot runs `heapgrow`, then ostest: | | master | this PR | |---|---|---| | `grow` | FAIL (4 warnings; every allocation succeeds) | PASS | | `spawn` | PASS | PASS | | `fail` | PASS (`mm_malloc: ... size 4294967304`) | PASS (`memalign: ... size 4294967296`) | | "Allocation failed" lines in the whole boot | 20 (19 of them heap growth: 14 from thread stacks in ostest, 5 from `heapgrow`) | 1 (the 4 GiB request) | | ostest (knsh, qemu-armv8a:nsh) | 0, 0 | 0, 0 | The same with `MM_PANIC_ON_FAILURE`: on master `heapgrow` ends at the first growth of its heap (`mm_malloc: WARNING: Allocation failed, size 196616`, then `Assertion failed panic: at file: mm_heap/mm_malloc.c:406`), although every allocation succeeds after `sbrk()`. With this PR `grow` and `spawn` pass, the panic comes only at the real failure of `fail` (`umm_heap/umm_memalign.c:89`), and ostest after it exits with 0 (knsh and nsh). Build check (debug options: `DEBUG_MM_WARN`, `MM_DUMP_ON_FAILURE`, `MM_DUMP_DETAILS_ON_FAILURE`, `MM_PANIC_ON_FAILURE`), each OK: - kernel: rv-virt:knsh64 (defconfig; debug options; debug options + `MM_TLSF_MANAGER`), qemu-armv8a:knsh (defconfig; debug options). These compile `umm_memalign.c` and `umm_realloc.c` for the kernel and for the user library. - protected: mps2-an500:knsh (defconfig; debug options without `MM_DUMP_DETAILS_ON_FAILURE`). - flat: qemu-armv8a:nsh (defconfig; debug options; debug options + `MM_TLSF_MANAGER`), rv-virt:nsh64 (debug options). Failures that master has too: qemu-armv8a:knsh + `MM_TLSF_MANAGER` (`-Werror`: `mm_lock_irq` and `mm_unlock_irq` defined but not used in `mm_tlsf.c`); mps2-an500:knsh + `MM_DUMP_DETAILS_ON_FAILURE` (the user `libmm` calls `nxsched_get_tcb()` in `mm_memdump()`; with `MM_TLSF_MANAGER` the same call in `mm_tlsf.c`, a file this PR does not change). `tools/checkpatch.sh -c -u -m -g` passes. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
