diff --git a/arch/Kconfig b/arch/Kconfig index e1d84c1e9f6..de365d9a26f 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -701,6 +701,17 @@ config DEMAND_PAGING_ALLOW_IRQ runs with interrupts disabled for the entire operation. However, ISRs may also page fault. +config DEMAND_PAGING_PAGE_FRAMES_RESERVE + int "Number of page frames reserved for paging" + default 32 if !LINKER_GENERIC_SECTIONS_PRESENT_AT_BOOT + default 0 + help + This sets the number of page frames that will be reserved for + paging that do not count towards free memory. This is to + ensure that there are some page frames available for paging + code and data. Otherwise, it would be possible to exhaust + all page frames via anonymous memory mappings. + config DEMAND_PAGING_STATS bool "Gather Demand Paging Statistics" help diff --git a/kernel/mmu.c b/kernel/mmu.c index 4d235858a92..cfc75dae035 100644 --- a/kernel/mmu.c +++ b/kernel/mmu.c @@ -624,7 +624,15 @@ size_t k_mem_free_get(void) __ASSERT(page_frames_initialized, "%s called too early", __func__); key = k_spin_lock(&z_mm_lock); +#ifdef CONFIG_DEMAND_PAGING + if (z_free_page_count > CONFIG_DEMAND_PAGING_PAGE_FRAMES_RESERVE) { + ret = z_free_page_count - CONFIG_DEMAND_PAGING_PAGE_FRAMES_RESERVE; + } else { + ret = 0; + } +#else ret = z_free_page_count; +#endif k_spin_unlock(&z_mm_lock, key); return ret * (size_t)CONFIG_MMU_PAGE_SIZE;