fix: properly assign frame owners and deallocate in all required places

This commit is contained in:
2024-12-06 00:29:57 +00:00
parent 833c1b0520
commit 1da0c7d48c
5 changed files with 112 additions and 36 deletions

View File

@@ -191,11 +191,18 @@ page_load_file (struct page_entry *page)
{
/* Frame exists, just install it. */
if (sfp->frame != NULL)
if (!install_page (page->upage, sfp->frame, page->writable))
{
lock_release (&shared_file_pages_lock);
return false;
}
{
if (!install_page (page->upage, sfp->frame, page->writable))
{
lock_release (&shared_file_pages_lock);
return false;
}
/* First time adding the shared page, so add thread as owner. */
if (page->type != PAGE_SHARED)
{
frame_owner_insert (sfp->frame, t);
}
}
/* Shared page is in swap. Load it. */
else
{
@@ -211,12 +218,15 @@ page_load_file (struct page_entry *page)
lock_release (&shared_file_pages_lock);
return false;
}
page_flag_shared (t, page->upage, true);
}
sfp->ref_count++;
page->type = PAGE_SHARED;
lock_release (&shared_file_pages_lock);
return true;
page_flag_shared (t, page->upage, true);
if (page->type != PAGE_SHARED)
{
sfp->ref_count++;
page->type = PAGE_SHARED;
}
lock_release (&shared_file_pages_lock);
return true;
}
}
@@ -286,6 +296,8 @@ page_cleanup (struct hash_elem *e, void *aux UNUSED)
struct shared_file_page *sfp
= shared_file_page_get (page->file, page->upage);
ASSERT (sfp != NULL);
if (sfp->frame != NULL)
frame_owner_remove (sfp->frame, thread_current ());
sfp->ref_count--;
if (sfp->ref_count == 0)
{
@@ -379,8 +391,7 @@ page_flag_shared (struct thread *owner, void *upage, bool shared)
*pte &= ~(1 << SHARED_FLAG_BIT);
}
/* Returns true iff the page with user address 'upage' owned by 'owner'
is flagged to be shared via the owner's page table. */
/* Returns true iff the page table entry is marked to be shared. */
bool
page_is_shared_pte (uint32_t *pte)
{
@@ -403,7 +414,9 @@ static unsigned
shared_file_page_hash (const struct hash_elem *e, void *aux UNUSED)
{
struct shared_file_page *sfp = hash_entry (e, struct shared_file_page, elem);
void *bytes[2] = { sfp->upage, sfp->file };
void *inode = file_get_inode (sfp->file);
void *upage = sfp->upage;
void *bytes[2] = { inode, upage };
return hash_bytes (bytes, sizeof (bytes));
}