From 5d5a0ee4bba8fdefc0d4d8589b75145a29e3387f Mon Sep 17 00:00:00 2001 From: jvbronzeado Date: Wed, 8 Jul 2026 19:59:48 -0300 Subject: [PATCH 1/3] mm: added page fault range caching for each mm_space_t --- kernel-src/include/kernel/mm.h | 2 ++ kernel-src/mm/mm.c | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/kernel-src/include/kernel/mm.h b/kernel-src/include/kernel/mm.h index d0ef47bf..4e96d3e5 100644 --- a/kernel-src/include/kernel/mm.h +++ b/kernel-src/include/kernel/mm.h @@ -46,6 +46,8 @@ typedef struct { rbtree_t *ranges; void *start; void *end; + + mm_range_t *last_pagefault; } mm_space_t; typedef struct { diff --git a/kernel-src/mm/mm.c b/kernel-src/mm/mm.c index 126e83c0..b2195171 100644 --- a/kernel-src/mm/mm.c +++ b/kernel-src/mm/mm.c @@ -273,7 +273,13 @@ bool mm_handle_page_fault(void *addr, bool user, int actions) { } MUTEX_ACQUIRE(&space->lock); - mm_range_t *range = mm_get_range(space, addr); + + // we look at the last page fault range and check if the address is in this range + // this avoids more expensive tree lookup + mm_range_t* range = space->last_pagefault; + if(range == NULL || range->start > addr || addr >= range->start + range->size) { + range = mm_get_range(space, addr); + } bool status = false; @@ -282,6 +288,8 @@ bool mm_handle_page_fault(void *addr, bool user, int actions) { goto cleanup; } + space->last_pagefault = range; + // check if valid int invalid_actions = 0; From 45bf3e1a367cde02dfbbe0a4d6535e821be4da31 Mon Sep 17 00:00:00 2001 From: jvbronzeado Date: Thu, 9 Jul 2026 19:34:40 -0300 Subject: [PATCH 2/3] mm: added last_pagefault handling when mm_space_t is unmapped --- kernel-src/mm/range.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/kernel-src/mm/range.c b/kernel-src/mm/range.c index 93414034..8f98a23e 100644 --- a/kernel-src/mm/range.c +++ b/kernel-src/mm/range.c @@ -288,6 +288,9 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in if (free) { // release page data + if (space->last_pagefault == range) + space->last_pagefault = NULL; + mm_destroy_range(range, (uintptr_t)address - (uintptr_t)range->start, size, 0); } @@ -340,6 +343,9 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in range->size -= difference; if (free) { + if (space->last_pagefault == range) + space->last_pagefault = NULL; + mm_destroy_range(range, range->size, difference, 0); rbtree = rbtree_successor(rbtree); } else { @@ -382,6 +388,9 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in // remove or change the flags of the range if (free) { + if (space->last_pagefault == range) + space->last_pagefault = NULL; + rbtree_remove(&space->ranges, &range->rbtree_node); mm_destroy_range(range, 0, range->size, 0); mm_free_range(range); @@ -410,8 +419,12 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in } size_t difference = (uintptr_t)top - (uintptr_t)range->start; - if (free) + if (free) { + if (space->last_pagefault == range) + space->last_pagefault = NULL; + mm_destroy_range(range, 0, difference, 0); + } range->start = (void *)((uintptr_t)range->start + difference); range->size -= difference; From c8c7776ebcd34a58ba02728eadbbd703ad40f1eb Mon Sep 17 00:00:00 2001 From: jvbronzeado Date: Fri, 10 Jul 2026 15:43:32 -0300 Subject: [PATCH 3/3] mm: fixed styling inconsistencies, fixed last pagefault range removal --- kernel-src/mm/mm.c | 12 ++++++++---- kernel-src/mm/range.c | 15 ++++++--------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/kernel-src/mm/mm.c b/kernel-src/mm/mm.c index b2195171..28f50d57 100644 --- a/kernel-src/mm/mm.c +++ b/kernel-src/mm/mm.c @@ -275,9 +275,9 @@ bool mm_handle_page_fault(void *addr, bool user, int actions) { MUTEX_ACQUIRE(&space->lock); // we look at the last page fault range and check if the address is in this range - // this avoids more expensive tree lookup - mm_range_t* range = space->last_pagefault; - if(range == NULL || range->start > addr || addr >= range->start + range->size) { + // this might avoid a more expensive tree lookup + mm_range_t *range = space->last_pagefault; + if (range == NULL || range->start > addr || addr >= range->start + range->size) { range = mm_get_range(space, addr); } @@ -494,8 +494,12 @@ void *mm_map(void *addr, volatile size_t size, int flags, mmuflags_t mmuflags, v mm_insert_range(space, range); cleanup: - if (ret_addr == NULL && range) + if (ret_addr == NULL && range) { + if (space->last_pagefault == range) + space->last_pagefault = NULL; + mm_free_range(range); + } MUTEX_RELEASE(&space->lock); return ret_addr; diff --git a/kernel-src/mm/range.c b/kernel-src/mm/range.c index 8f98a23e..99404fa9 100644 --- a/kernel-src/mm/range.c +++ b/kernel-src/mm/range.c @@ -122,6 +122,9 @@ void mm_insert_range(mm_space_t *space, mm_range_t *new_range) { if (next_range && ranges_compatible(new_range, next_range)) { new_range->size += next_range->size; + if (space->last_pagefault == next_range) + space->last_pagefault = NULL; + rbtree_remove(&space->ranges, &next_range->rbtree_node); mm_free_range(next_range); if (new_range->flags & MM_RANGE_FLAGS_FILE) { @@ -133,6 +136,9 @@ void mm_insert_range(mm_space_t *space, mm_range_t *new_range) { if (prev_range && ranges_compatible(prev_range, new_range)) { prev_range->size += new_range->size; + if (space->last_pagefault == new_range) + space->last_pagefault = NULL; + rbtree_remove(&space->ranges, &new_range->rbtree_node); mm_free_range(new_range); if (prev_range->flags & MM_RANGE_FLAGS_FILE) { @@ -288,9 +294,6 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in if (free) { // release page data - if (space->last_pagefault == range) - space->last_pagefault = NULL; - mm_destroy_range(range, (uintptr_t)address - (uintptr_t)range->start, size, 0); } @@ -343,9 +346,6 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in range->size -= difference; if (free) { - if (space->last_pagefault == range) - space->last_pagefault = NULL; - mm_destroy_range(range, range->size, difference, 0); rbtree = rbtree_successor(rbtree); } else { @@ -420,9 +420,6 @@ int mm_change_range(mm_space_t *space, void *address, size_t size, bool free, in size_t difference = (uintptr_t)top - (uintptr_t)range->start; if (free) { - if (space->last_pagefault == range) - space->last_pagefault = NULL; - mm_destroy_range(range, 0, difference, 0); }