tests: demand_paging: add a test for on-demand sections

Exercises linker placement, the ondemand backing store, demand paging.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2024-07-31 01:09:36 -04:00 committed by Anas Nashif
parent 78cd836e2f
commit 7e847eca25
4 changed files with 93 additions and 0 deletions

View file

@ -0,0 +1,13 @@
# SPDX-License-Identifier: Apache-2.0
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(ondemand_section)
target_include_directories(app PRIVATE
${ZEPHYR_BASE}/kernel/include
${ZEPHYR_BASE}/arch/${ARCH}/include
)
FILE(GLOB app_sources src/*.c)
target_sources(app PRIVATE ${app_sources})

View file

@ -0,0 +1,6 @@
CONFIG_ZTEST=y
CONFIG_DEMAND_PAGING=y
CONFIG_DEMAND_PAGING_ALLOW_IRQ=y
CONFIG_DEMAND_PAGING_STATS=y
CONFIG_DEMAND_MAPPING=y
CONFIG_LINKER_USE_ONDEMAND_SECTION=y

View file

@ -0,0 +1,62 @@
/*
* Copyright (c) 2024 BayLibre SAS
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/kernel/mm.h>
#include <zephyr/kernel/mm/demand_paging.h>
#include <zephyr/linker/sections.h>
#include <mmu.h>
static const char __ondemand_rodata message[] = "was evicted";
static void __ondemand_func evictable_function(void)
{
static int count;
printk("This %s code, count=%d\n", message, ++count);
}
ZTEST(ondemand_section, test_ondemand_basic)
{
unsigned long faults_before, faults_after;
void *addr = (void *)ROUND_DOWN(&evictable_function, CONFIG_MMU_PAGE_SIZE);
printk("About to call unpaged code\n");
faults_before = k_mem_num_pagefaults_get();
evictable_function();
faults_after = k_mem_num_pagefaults_get();
zassert_not_equal(faults_before, faults_after, "should have faulted");
printk("Code should be resident on second call\n");
faults_before = k_mem_num_pagefaults_get();
evictable_function();
faults_after = k_mem_num_pagefaults_get();
zassert_equal(faults_before, faults_after, "should not have faulted");
printk("Forcefully evicting it from memory\n");
zassert_ok(k_mem_page_out(addr, CONFIG_MMU_PAGE_SIZE), "");
printk("Calling it again\n");
faults_before = k_mem_num_pagefaults_get();
evictable_function();
faults_after = k_mem_num_pagefaults_get();
zassert_not_equal(faults_before, faults_after, "should have faulted");
printk("Forcefully evicting it from memory again\n");
zassert_ok(k_mem_page_out(addr, CONFIG_MMU_PAGE_SIZE), "");
printk("Preemptively fetching it back in\n");
/* strangely, k_mem_page_in() returns void */
k_mem_page_in(addr, CONFIG_MMU_PAGE_SIZE);
printk("Code should be resident\n");
faults_before = k_mem_num_pagefaults_get();
evictable_function();
faults_after = k_mem_num_pagefaults_get();
zassert_equal(faults_before, faults_after, "should not have faulted");
}
ZTEST_SUITE(ondemand_section, NULL, NULL, NULL, NULL, NULL);

View file

@ -0,0 +1,12 @@
common:
tags:
- kernel
- mmu
- demand_paging
tests:
kernel.demand_paging.ondemand_section.arm64_semihost:
platform_allow:
- qemu_cortex_a53
extra_configs:
- CONFIG_SEMIHOST=y
- CONFIG_BACKING_STORE_ONDEMAND_SEMIHOST=y