From d389c1582855a334b28be4417b57f97f5dec1aca Mon Sep 17 00:00:00 2001 From: EDiasAlberto Date: Fri, 6 Dec 2024 13:20:43 +0000 Subject: [PATCH] fix: acquire lru_lock before pinning frames to avoid race condition with eviction --- src/vm/frame.c | 12 +++++++----- src/vm/frame.h | 4 ++++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/vm/frame.c b/src/vm/frame.c index 4730558..c1d5ae3 100644 --- a/src/vm/frame.c +++ b/src/vm/frame.c @@ -28,9 +28,6 @@ struct list lru_list; victim. Otherwise, the next element in the queue is similarly considered. */ struct list_elem *next_victim = NULL; -/* Synchronisation variables. */ -/* Protects access to 'lru_list'. */ -struct lock lru_lock; struct frame_metadata { @@ -175,23 +172,29 @@ frame_alloc (enum palloc_flags flags, void *upage, struct thread *owner) void frame_pin (void *frame) { + ASSERT (frame != NULL); + lock_acquire (&lru_lock); struct frame_metadata *frame_metadata = frame_metadata_get (frame); if (frame_metadata == NULL) PANIC ("Attempted to pin a frame at an unallocated kernel address '%p'\n", frame); frame_metadata->pinned = true; + lock_release (&lru_lock); } - + void frame_unpin (void *frame) { + ASSERT (frame != NULL); + lock_acquire (&lru_lock); struct frame_metadata *frame_metadata = frame_metadata_get (frame); if (frame_metadata == NULL) PANIC ("Attempted to unpin a frame at an unallocated kernel address '%p'\n", frame); frame_metadata->pinned = false; + lock_release (&lru_lock); } /* Attempt to deallocate a frame for a user process by removing it from the @@ -372,7 +375,6 @@ frame_metadata_get (void *frame) struct hash_elem *e = hash_find (&frame_table, &key_metadata.hash_elem); if (e == NULL) return NULL; - return hash_entry (e, struct frame_metadata, hash_elem); } diff --git a/src/vm/frame.h b/src/vm/frame.h index 76a801a..cb5916e 100644 --- a/src/vm/frame.h +++ b/src/vm/frame.h @@ -10,7 +10,11 @@ struct frame_owner struct list_elem elem; /* List element for the list of owners. */ }; +/* Synchronisation variables. */ +/* Protects access to 'lru_list'. */ +struct lock lru_lock; void frame_init (void); + void *frame_alloc (enum palloc_flags, void *, struct thread *); void frame_pin (void *frame); void frame_unpin (void *frame);