Skip to content

Commit 436c7bb

Browse files
committed
demand_paging: eviction: add kconfig CONFIG_EVICTION_TRACKING
This adds a new kconfig for eviction algorithm which needs page tracking. When enabled, k_mem_paging_eviction_add()/_remove() and k_mem_paging_eviction_accessed() must be implemented. If an algorithm does not do page tracking, there is no need to implement these functions, and no need for the kernel MMU code to call into empty functions. This should save a few function calls and some CPU cycles. Note that arm64 unconditionally calls those functions so forces CONFIG_EVICTION_TRACKING to be enabled there. Signed-off-by: Daniel Leung <[email protected]>
1 parent 40cd35e commit 436c7bb

File tree

6 files changed

+75
-14
lines changed

6 files changed

+75
-14
lines changed

arch/Kconfig

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ config ARM64
5555
select ARCH_HAS_DIRECTED_IPIS
5656
select ARCH_HAS_DEMAND_PAGING
5757
select ARCH_HAS_DEMAND_MAPPING
58+
select ARCH_SUPPORTS_EVICTION_TRACKING
59+
select EVICTION_TRACKING if DEMAND_PAGING
5860
help
5961
ARM64 (AArch64) architecture
6062

@@ -694,6 +696,12 @@ config ARCH_SUPPORTS_ROM_START
694696
config ARCH_SUPPORTS_EMPTY_IRQ_SPURIOUS
695697
bool
696698

699+
config ARCH_SUPPORTS_EVICTION_TRACKING
700+
bool
701+
help
702+
Architecture code supports page tracking for eviction algorithms
703+
when demand paging is enabled.
704+
697705
config ARCH_HAS_EXTRA_EXCEPTION_INFO
698706
bool
699707

doc/kernel/memory_management/demand_paging.rst

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,8 +156,12 @@ Two eviction algorithms are currently available:
156156
to the NRU code but also considerably more efficient. This is recommended for
157157
production use.
158158

159-
To implement a new eviction algorithm, the five functions mentioned
160-
above must be implemented.
159+
To implement a new eviction algorithm, :c:func:`k_mem_paging_eviction_init()`
160+
and :c:func:`k_mem_paging_eviction_select()` must be implemented.
161+
If :kconfig:option:`CONFIG_EVICTION_TRACKING` is enabled for an algorithm,
162+
these additional functions must also be implemented,
163+
:c:func:`k_mem_paging_eviction_add()`, :c:func:`k_mem_paging_eviction_remove()`,
164+
:c:func:`k_mem_paging_eviction_accessed()`.
161165

162166
Backing Store
163167
*************

include/zephyr/kernel/mm/demand_paging.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ __syscall void k_mem_paging_histogram_backing_store_page_out_get(
217217
* @{
218218
*/
219219

220+
#if defined(CONFIG_EVICTION_TRACKING) || defined(__DOXYGEN__)
221+
220222
/**
221223
* Submit a page frame for eviction candidate tracking
222224
*
@@ -261,6 +263,25 @@ void k_mem_paging_eviction_remove(struct k_mem_page_frame *pf);
261263
*/
262264
void k_mem_paging_eviction_accessed(uintptr_t phys);
263265

266+
#else /* CONFIG_EVICTION_TRACKING || __DOXYGEN__ */
267+
268+
static inline void k_mem_paging_eviction_add(struct k_mem_page_frame *pf)
269+
{
270+
ARG_UNUSED(pf);
271+
}
272+
273+
static inline void k_mem_paging_eviction_remove(struct k_mem_page_frame *pf)
274+
{
275+
ARG_UNUSED(pf);
276+
}
277+
278+
static inline void k_mem_paging_eviction_accessed(uintptr_t phys)
279+
{
280+
ARG_UNUSED(phys);
281+
}
282+
283+
#endif /* CONFIG_EVICTION_TRACKING || __DOXYGEN__ */
284+
264285
/**
265286
* Select a page frame for eviction
266287
*

kernel/mmu.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,7 @@ static int map_anon_page(void *addr, uint32_t flags)
556556
}
557557
frame_mapped_set(pf, addr);
558558
#ifdef CONFIG_DEMAND_PAGING
559-
if (!lock) {
559+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING) && (!lock)) {
560560
k_mem_paging_eviction_add(pf);
561561
}
562562
#endif
@@ -784,7 +784,8 @@ void k_mem_unmap_phys_guard(void *addr, size_t size, bool is_anon)
784784

785785
arch_mem_unmap(pos, CONFIG_MMU_PAGE_SIZE);
786786
#ifdef CONFIG_DEMAND_PAGING
787-
if (!k_mem_page_frame_is_pinned(pf)) {
787+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING) &&
788+
(!k_mem_page_frame_is_pinned(pf))) {
788789
k_mem_paging_eviction_remove(pf);
789790
}
790791
#endif
@@ -1041,7 +1042,8 @@ static void mark_linker_section_pinned(void *start_addr, void *end_addr,
10411042
} else {
10421043
k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_PINNED);
10431044
#ifdef CONFIG_DEMAND_PAGING
1044-
if (k_mem_page_frame_is_evictable(pf)) {
1045+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING) &&
1046+
k_mem_page_frame_is_evictable(pf)) {
10451047
k_mem_paging_eviction_add(pf);
10461048
}
10471049
#endif
@@ -1147,10 +1149,13 @@ void z_mem_manage_init(void)
11471149
#endif /* CONFIG_DEMAND_PAGING_TIMING_HISTOGRAM */
11481150
k_mem_paging_backing_store_init();
11491151
k_mem_paging_eviction_init();
1150-
/* start tracking evictable page installed above if any */
1151-
K_MEM_PAGE_FRAME_FOREACH(phys, pf) {
1152-
if (k_mem_page_frame_is_evictable(pf)) {
1153-
k_mem_paging_eviction_add(pf);
1152+
1153+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING)) {
1154+
/* start tracking evictable page installed above if any */
1155+
K_MEM_PAGE_FRAME_FOREACH(phys, pf) {
1156+
if (k_mem_page_frame_is_evictable(pf)) {
1157+
k_mem_paging_eviction_add(pf);
1158+
}
11541159
}
11551160
}
11561161
#endif /* CONFIG_DEMAND_PAGING */
@@ -1347,7 +1352,10 @@ static int page_frame_prepare_locked(struct k_mem_page_frame *pf, bool *dirty_pt
13471352
return -ENOMEM;
13481353
}
13491354
arch_mem_page_out(k_mem_page_frame_to_virt(pf), *location_ptr);
1350-
k_mem_paging_eviction_remove(pf);
1355+
1356+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING)) {
1357+
k_mem_paging_eviction_remove(pf);
1358+
}
13511359
} else {
13521360
/* Shouldn't happen unless this function is mis-used */
13531361
__ASSERT(!dirty, "un-mapped page determined to be dirty");
@@ -1683,7 +1691,9 @@ static bool do_page_fault(void *addr, bool pin)
16831691

16841692
pf = k_mem_phys_to_page_frame(phys);
16851693
if (!k_mem_page_frame_is_pinned(pf)) {
1686-
k_mem_paging_eviction_remove(pf);
1694+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING)) {
1695+
k_mem_paging_eviction_remove(pf);
1696+
}
16871697
k_mem_page_frame_set(pf, K_MEM_PAGE_FRAME_PINNED);
16881698
}
16891699
}
@@ -1738,7 +1748,7 @@ static bool do_page_fault(void *addr, bool pin)
17381748

17391749
arch_mem_page_in(addr, k_mem_page_frame_to_phys(pf));
17401750
k_mem_paging_backing_store_page_finalize(pf, page_in_location);
1741-
if (!pin) {
1751+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING) && (!pin)) {
17421752
k_mem_paging_eviction_add(pf);
17431753
}
17441754
out:
@@ -1807,7 +1817,10 @@ static void do_mem_unpin(void *addr)
18071817
pf = k_mem_phys_to_page_frame(phys);
18081818
if (k_mem_page_frame_is_pinned(pf)) {
18091819
k_mem_page_frame_clear(pf, K_MEM_PAGE_FRAME_PINNED);
1810-
k_mem_paging_eviction_add(pf);
1820+
1821+
if (IS_ENABLED(CONFIG_EVICTION_TRACKING)) {
1822+
k_mem_paging_eviction_add(pf);
1823+
}
18111824
}
18121825
}
18131826
k_spin_unlock(&z_mm_lock, key);

subsys/demand_paging/eviction/Kconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ choice EVICTION_CHOICE
1111

1212
config EVICTION_CUSTOM
1313
bool "Custom eviction algorithm"
14+
imply EVICTION_TRACKING
1415
help
1516
This option is chosen when the eviction algorithm will be implemented
1617
by the application, instead of using one included in Zephyr.
@@ -30,6 +31,7 @@ config EVICTION_NRU
3031

3132
config EVICTION_LRU
3233
bool "Least Recently Used (LRU) page eviction algorithm"
34+
select EVICTION_TRACKING
3335
help
3436
This implements a Least Recently Used page eviction algorithm.
3537
Usage is tracked based on MMU protection making pages unaccessible
@@ -49,3 +51,11 @@ config EVICTION_NRU_PERIOD
4951
pages that are capable of being paged out. At eviction time, if a page
5052
still has the accessed property, it will be considered as recently used.
5153
endif # EVICTION_NRU
54+
55+
config EVICTION_TRACKING
56+
bool
57+
depends on ARCH_SUPPORTS_EVICTION_TRACKING
58+
help
59+
Selected by eviction algorithms which needs page tracking and need to
60+
implement the following functions: k_mem_paging_eviction_add(),
61+
k_mem_paging_eviction_remove() and k_mem_paging_eviction_accessed().

subsys/demand_paging/eviction/nru.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,11 @@ void k_mem_paging_eviction_init(void)
111111
K_MSEC(CONFIG_EVICTION_NRU_PERIOD));
112112
}
113113

114+
#ifdef CONFIG_EVICTION_TRACKING
114115
/*
115-
* unused interfaces
116+
* Empty functions defined here so that architectures unconditionally
117+
* implement eviction tracking can still use this algorithm for
118+
* testing.
116119
*/
117120

118121
void k_mem_paging_eviction_add(struct k_mem_page_frame *pf)
@@ -129,3 +132,5 @@ void k_mem_paging_eviction_accessed(uintptr_t phys)
129132
{
130133
ARG_UNUSED(phys);
131134
}
135+
136+
#endif /* CONFIG_EVICTION_TRACKING */

0 commit comments

Comments
 (0)