From 4dd6b6e928e8b8b62ec38646f2589d678c4ace15 Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Thu, 5 Dec 2024 19:38:27 +0000 Subject: [PATCH] fix: do not leak when inserting the same page twice, just update --- src/userprog/exception.c | 2 +- src/vm/page.c | 10 ++++++++++ src/vm/page.h | 6 ++---- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/userprog/exception.c b/src/userprog/exception.c index c4bfa97..dc1d48a 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -292,7 +292,7 @@ fetch_page (void *upage, bool write) switch (page->type) { case PAGE_MMAP: case PAGE_FILE: - success = page_load_file (page, page->writable); + success = page_load_file (page); if (success && page->type == PAGE_FILE) { hash_delete (&thread_current ()->pages, &page->elem); diff --git a/src/vm/page.c b/src/vm/page.c index e4efb2f..a21b9e8 100644 --- a/src/vm/page.c +++ b/src/vm/page.c @@ -95,6 +95,16 @@ page_insert_file (struct file *file, off_t ofs, void *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable, enum page_type type) { + /* If page exists, just update it. */ + struct page_entry *existing = page_get (upage); + if (existing != NULL) + { + ASSERT (existing->read_bytes == read_bytes); + ASSERT (existing->zero_bytes == zero_bytes); + existing->writable = existing->writable || writable; + return existing; + } + struct page_entry *page = malloc(sizeof (struct page_entry)); if (page == NULL) return NULL; diff --git a/src/vm/page.h b/src/vm/page.h index 893317d..a96f89a 100644 --- a/src/vm/page.h +++ b/src/vm/page.h @@ -30,16 +30,14 @@ struct page_entry { struct hash_elem elem; /* An elem for the hash table. */ }; -unsigned page_hash (const struct hash_elem *e, void *aux); -bool page_less (const struct hash_elem *a_, const struct hash_elem *b_, - void *aux); +bool init_pages (struct hash *pages); struct page_entry *page_insert_swapped (void *upage, void* kpage, struct thread *owner); struct page_entry *page_insert_file (struct file *file, off_t ofs, void *upage, uint32_t read_bytes, uint32_t zero_bytes, bool writable, enum page_type); struct page_entry *page_get (void *upage); -bool page_load_file (struct page_entry *page, bool writable); +bool page_load_file (struct page_entry *page); void page_cleanup (struct hash_elem *e, void *aux); bool page_in_swap (struct thread *, void *);