Refactor: Check if page is in a swap in fetch_page instead of the page fault handler

This commit is contained in:
sBubshait
2024-12-05 03:17:18 +00:00
parent c12cd95093
commit 16db01d3d8

View File

@@ -24,7 +24,7 @@ static void page_fault (struct intr_frame *);
static bool is_valid_stack_access (const void *fault_addr, const void *esp); static bool is_valid_stack_access (const void *fault_addr, const void *esp);
static bool grow_stack (void *upage); static bool grow_stack (void *upage);
bool try_fetch_page (void *upage, bool write); bool fetch_page (void *upage, bool write);
/* Registers handlers for interrupts that can be caused by user /* Registers handlers for interrupts that can be caused by user
programs. programs.
@@ -167,29 +167,14 @@ page_fault (struct intr_frame *f)
be just that the stack needs to grow or that it needs to be lazily loaded. be just that the stack needs to grow or that it needs to be lazily loaded.
So we attempt to grow the stack. If this does not work, we check our SPT to So we attempt to grow the stack. If this does not work, we check our SPT to
see if the page is expected to have data loaded in memory. */ see if the page is expected to have data loaded in memory. */
struct thread *t = thread_current ();
void *upage = pg_round_down (fault_addr); void *upage = pg_round_down (fault_addr);
if (not_present && is_user_vaddr (upage) && upage != NULL) if (not_present && is_user_vaddr (upage) && upage != NULL)
{ {
/* Check if the non-present user page is in the swap partition.
If so, swap it back into main memory, updating the PTE for
the faulted virtual address to point to the newly allocated
frame. */
if (page_in_swap (t, fault_addr))
{
size_t swap_slot = page_get_swap (t, fault_addr);
void *kpage = frame_alloc (0, upage, t);
swap_in (kpage, swap_slot);
bool writeable = pagedir_is_writable (t->pagedir, upage);
if (pagedir_set_page (t->pagedir, upage, kpage, writeable)) return;
}
if (is_valid_stack_access (fault_addr, esp)) if (is_valid_stack_access (fault_addr, esp))
if (grow_stack (upage)) if (grow_stack (upage))
return; return;
if (try_fetch_page (upage, write)) if (fetch_page (upage, write))
return; return;
} }
@@ -262,8 +247,24 @@ grow_stack (void *upage)
} }
bool bool
try_fetch_page (void *upage, bool write) fetch_page (void *upage, bool write)
{ {
/* Check if the non-present user page is in the swap partition.
If so, swap it back into main memory, updating the PTE for
the faulted virtual address to point to the newly allocated
frame. */
struct thread *t = thread_current ();
if (page_in_swap (t, upage))
{
size_t swap_slot = page_get_swap (t, upage);
void *kpage = frame_alloc (0, upage, t);
swap_in (kpage, swap_slot);
bool writeable = pagedir_is_writable (t->pagedir, upage);
if (pagedir_set_page (t->pagedir, upage, kpage, writeable))
return true;
}
/* Check if the page is in the supplemental page table. That is, it is a page /* Check if the page is in the supplemental page table. That is, it is a page
that is expected to be in memory. */ that is expected to be in memory. */
struct page_entry *page = page_get (upage); struct page_entry *page = page_get (upage);