feat: implement page swapping

This commit is contained in:
Themis Demetriades
2024-12-03 16:53:47 +00:00
parent df7d847978
commit 08eafcf7ef
3 changed files with 39 additions and 3 deletions

View File

@@ -1,10 +1,18 @@
#include "userprog/exception.h"
#include <inttypes.h>
#include <stdio.h>
#include "stdbool.h"
#include "userprog/gdt.h"
#include "threads/interrupt.h"
#include "threads/thread.h"
#include "userprog/pagedir.h"
#ifdef VM
#include "vm/stackgrowth.h"
#include "vm/frame.h"
#include "vm/page.h"
#include "devices/swap.h"
#include "threads/vaddr.h"
#endif
/* Number of page faults processed. */
static long long page_fault_cnt;
@@ -147,10 +155,27 @@ page_fault (struct intr_frame *f)
user = (f->error_code & PF_U) != 0;
#ifdef VM
if (user && not_present)
if (user)
{
if (not_present)
{
struct thread *t = thread_current ();
if (page_in_swap (t, fault_addr))
{
size_t swap_slot = page_get_swap (t, fault_addr);
void *upage = pg_round_down (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;
}
/* Handle page faults that need to be resolved by dynamic stack growth
by checking if this is such a fault and resolving it appropriately. */
if (handle_stack_fault (fault_addr, f->esp)) return;
}
}
else
{
f->eip = (void *)f->eax;

View File

@@ -24,6 +24,16 @@ page_set_swap (struct thread *owner, void *upage, size_t swap_slot)
pagedir_clear_page (owner->pagedir, upage);
}
/* Returns true iff the page with user address 'upage' owned by 'owner'
is flagged to be in the swap disk via the owner's page table. */
bool
page_in_swap (struct thread *owner, void *upage)
{
uint32_t *pte = lookup_page (owner->pagedir, upage, false);
return pte != NULL &&
(*pte & (1 << SWAP_FLAG_BIT)) != 0;
}
/* Given that the page with user address 'upage' owned by 'owner' is flagged
to be in the swap disk via the owner's page table, returns its stored
swap slot. Otherwise panics the kernel. */
@@ -32,8 +42,8 @@ page_get_swap (struct thread *owner, void *upage)
{
uint32_t *pte = lookup_page (owner->pagedir, upage, false);
ASSERT (pte != NULL);
ASSERT ((*pte & PTE_P) == 0);
ASSERT ((*pte & (1 << SWAP_FLAG_BIT)) != 0);
/* Masks the address bits and returns truncated value. */
return ((*pte & PTE_ADDR) >> ADDR_START_BIT);

View File

@@ -4,6 +4,7 @@
#include "threads/thread.h"
void page_set_swap (struct thread *, void *, size_t);
bool page_in_swap (struct thread *, void *);
size_t page_get_swap (struct thread *, void *);
#endif /* vm/frame.h */