Skip to content

Commit 1754bb4

Browse files
committed
only block relevant functions during refill
1 parent 24f26bc commit 1754bb4

File tree

2 files changed

+23
-13
lines changed

2 files changed

+23
-13
lines changed

arch/x86/pagetables.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,13 +426,17 @@ void *vmap_frame_refill(void *va, mfn_t mfn, bool paging_lock) {
426426

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

429-
ASSERT(vmap_lock);
430-
431429
if (paging_lock)
432430
spin_lock(&vmap_lock);
431+
else
432+
ASSERT(vmap_lock);
433+
433434
va = _vmap_4k(&cr3, _ptr(_va), mfn, L1_PROT, false);
435+
434436
if (paging_lock)
435437
spin_unlock(&vmap_lock);
438+
else
439+
ASSERT(vmap_lock);
436440

437441
return va;
438442
}

mm/pmm.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,15 @@ static frames_array_t early_frames;
4141
static list_head_t free_frames[MAX_PAGE_ORDER + 1];
4242
static list_head_t busy_frames[MAX_PAGE_ORDER + 1];
4343

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

4848
static bool refilling;
4949
static spinlock_t lock = SPINLOCK_INIT;
5050

51+
static void try_create_4k_frames(void);
52+
5153
static void spin_lock_norefill() {
5254
spin_lock(&lock);
5355

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

113-
static frames_array_t *_new_frames_array(bool paging_lock) {
115+
static frames_array_t *_new_frames_array(bool from_paging) {
114116
frames_array_t *array;
115117
frame_t *frame;
116118

@@ -122,11 +124,13 @@ static frames_array_t *_new_frames_array(bool paging_lock) {
122124
array = (frames_array_t *) mfn_to_virt_kern(frame->mfn);
123125
else {
124126
/* switch to special refilling mode to avoid deadlock with paging */
127+
ASSERT(!refilling);
125128
refilling = true;
126129
/* only paging will be allowed to take the lock while refilling */
127130
spin_unlock(&lock);
128-
array = vmap_frame_refill(mfn_to_virt_map(frame->mfn), frame->mfn, paging_lock);
131+
array = vmap_frame_refill(mfn_to_virt_map(frame->mfn), frame->mfn, from_paging);
129132
spin_lock(&lock);
133+
ASSERT(refilling);
130134
refilling = false;
131135
if (!array)
132136
goto error;
@@ -136,6 +140,9 @@ static frames_array_t *_new_frames_array(bool paging_lock) {
136140

137141
init_frames_array(array);
138142

143+
/* since paging will back off from refilling we are responsible to do it here */
144+
try_create_4k_frames();
145+
139146
return array;
140147
error:
141148
panic("PMM: Unable to allocate new page for frame array");
@@ -449,7 +456,7 @@ static frame_t *_find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order
449456
frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order) {
450457
frame_t *frame;
451458

452-
spin_lock_norefill();
459+
spin_lock(&lock);
453460
frame = _find_mfn_frame(free_frames, mfn, order);
454461
spin_unlock(&lock);
455462

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

462-
spin_lock_norefill();
469+
spin_lock(&lock);
463470
frame = _find_mfn_frame(busy_frames, mfn, order);
464471
spin_unlock(&lock);
465472

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

472-
spin_lock_norefill();
479+
spin_lock(&lock);
473480
frame = _find_mfn_frame(busy_frames, mfn, order);
474481
if (!frame)
475482
frame = _find_mfn_frame(free_frames, mfn, order);
@@ -494,7 +501,7 @@ static frame_t *_find_paddr_frame(list_head_t *list, paddr_t paddr) {
494501
frame_t *find_free_paddr_frame(paddr_t paddr) {
495502
frame_t *frame;
496503

497-
spin_lock_norefill();
504+
spin_lock(&lock);
498505
frame = _find_paddr_frame(free_frames, paddr);
499506
spin_unlock(&lock);
500507

@@ -504,7 +511,7 @@ frame_t *find_free_paddr_frame(paddr_t paddr) {
504511
frame_t *find_busy_paddr_frame(paddr_t paddr) {
505512
frame_t *frame;
506513

507-
spin_lock_norefill();
514+
spin_lock(&lock);
508515
frame = _find_paddr_frame(busy_frames, paddr);
509516
spin_unlock(&lock);
510517

@@ -514,7 +521,7 @@ frame_t *find_busy_paddr_frame(paddr_t paddr) {
514521
frame_t *find_paddr_frame(paddr_t paddr) {
515522
frame_t *frame;
516523

517-
spin_lock_norefill();
524+
spin_lock(&lock);
518525
frame = _find_paddr_frame(busy_frames, paddr);
519526
if (!frame)
520527
frame = _find_paddr_frame(free_frames, paddr);
@@ -687,7 +694,7 @@ void put_free_frames(mfn_t mfn, unsigned int order) {
687694

688695
ASSERT(order <= MAX_PAGE_ORDER);
689696

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

730737
void refill_from_paging(void) {
731738

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

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

0 commit comments

Comments
 (0)