Skip to content

Commit

Permalink
only block relevant functions during refill
Browse files Browse the repository at this point in the history
  • Loading branch information
sparchatus committed Dec 3, 2024
1 parent 24f26bc commit 1754bb4
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
8 changes: 6 additions & 2 deletions arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,13 +426,17 @@ void *vmap_frame_refill(void *va, mfn_t mfn, bool paging_lock) {

dprintk("%s: va: 0x%p mfn: 0x%lx\n", __func__, va, mfn);

ASSERT(vmap_lock);

if (paging_lock)
spin_lock(&vmap_lock);
else
ASSERT(vmap_lock);

va = _vmap_4k(&cr3, _ptr(_va), mfn, L1_PROT, false);

if (paging_lock)
spin_unlock(&vmap_lock);
else
ASSERT(vmap_lock);

return va;
}
Expand Down
28 changes: 17 additions & 11 deletions mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ static frames_array_t early_frames;
static list_head_t free_frames[MAX_PAGE_ORDER + 1];
static list_head_t busy_frames[MAX_PAGE_ORDER + 1];

/* 1 frame for array frame, 3 for mapping it, times to for paging/pmm collisions */
/* 1 frame for array frame, 3 for mapping it, times two for paging/pmm collisions */
#define MIN_NUM_4K_FRAMES 2 * (1 + 3)
static size_t frames_count[MAX_PAGE_ORDER + 1];

static bool refilling;
static spinlock_t lock = SPINLOCK_INIT;

static void try_create_4k_frames(void);

static void spin_lock_norefill() {
spin_lock(&lock);

Expand Down Expand Up @@ -110,7 +112,7 @@ static inline void init_frames_array(frames_array_t *array) {
total_free_frames += array->meta.free_count;
}

static frames_array_t *_new_frames_array(bool paging_lock) {
static frames_array_t *_new_frames_array(bool from_paging) {
frames_array_t *array;
frame_t *frame;

Expand All @@ -122,11 +124,13 @@ static frames_array_t *_new_frames_array(bool paging_lock) {
array = (frames_array_t *) mfn_to_virt_kern(frame->mfn);
else {
/* switch to special refilling mode to avoid deadlock with paging */
ASSERT(!refilling);
refilling = true;
/* only paging will be allowed to take the lock while refilling */
spin_unlock(&lock);
array = vmap_frame_refill(mfn_to_virt_map(frame->mfn), frame->mfn, paging_lock);
array = vmap_frame_refill(mfn_to_virt_map(frame->mfn), frame->mfn, from_paging);
spin_lock(&lock);
ASSERT(refilling);
refilling = false;
if (!array)
goto error;
Expand All @@ -136,6 +140,9 @@ static frames_array_t *_new_frames_array(bool paging_lock) {

init_frames_array(array);

/* since paging will back off from refilling we are responsible to do it here */
try_create_4k_frames();

return array;
error:
panic("PMM: Unable to allocate new page for frame array");
Expand Down Expand Up @@ -449,7 +456,7 @@ static frame_t *_find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order
frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_mfn_frame(free_frames, mfn, order);
spin_unlock(&lock);

Expand All @@ -459,7 +466,7 @@ frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *find_busy_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_mfn_frame(busy_frames, mfn, order);
spin_unlock(&lock);

Expand All @@ -469,7 +476,7 @@ frame_t *find_busy_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *find_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_mfn_frame(busy_frames, mfn, order);
if (!frame)
frame = _find_mfn_frame(free_frames, mfn, order);
Expand All @@ -494,7 +501,7 @@ static frame_t *_find_paddr_frame(list_head_t *list, paddr_t paddr) {
frame_t *find_free_paddr_frame(paddr_t paddr) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_paddr_frame(free_frames, paddr);
spin_unlock(&lock);

Expand All @@ -504,7 +511,7 @@ frame_t *find_free_paddr_frame(paddr_t paddr) {
frame_t *find_busy_paddr_frame(paddr_t paddr) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_paddr_frame(busy_frames, paddr);
spin_unlock(&lock);

Expand All @@ -514,7 +521,7 @@ frame_t *find_busy_paddr_frame(paddr_t paddr) {
frame_t *find_paddr_frame(paddr_t paddr) {
frame_t *frame;

spin_lock_norefill();
spin_lock(&lock);
frame = _find_paddr_frame(busy_frames, paddr);
if (!frame)
frame = _find_paddr_frame(free_frames, paddr);
Expand Down Expand Up @@ -687,7 +694,7 @@ void put_free_frames(mfn_t mfn, unsigned int order) {

ASSERT(order <= MAX_PAGE_ORDER);

spin_lock_norefill();
spin_lock(&lock);
frame = _find_mfn_frame(busy_frames, mfn, order);
if (!frame) {
warning("PMM: unable to find frame: %lx, order: %u among busy frames", mfn,
Expand Down Expand Up @@ -729,7 +736,6 @@ void map_frames_array(void) {

void refill_from_paging(void) {

printk("%s: start\n", __func__);
spin_lock(&lock);

/* if a refill is already active then they are responsible */
Expand Down

0 comments on commit 1754bb4

Please sign in to comment.