Skip to content

Commit

Permalink
allow frame refill from paging
Browse files Browse the repository at this point in the history
  • Loading branch information
sparchatus committed Dec 2, 2024
1 parent 62c2167 commit ca5eb42
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
9 changes: 6 additions & 3 deletions arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,7 @@ void *__vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
invlpg(va);

done:
refill_from_paging();
return va;
}
static void *_vmap(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
Expand All @@ -337,11 +338,13 @@ void *__vmap_paging(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags, bool special_path) {
spin_lock(&vmap_lock);
unsigned long l1_flags, bool special_path, bool take_lock) {
if (take_lock)
spin_lock(&vmap_lock);
void *res = __vmap(cr3_ptr, va, mfn, order, l4_flags, l3_flags, l2_flags, l1_flags,
special_path);
spin_unlock(&vmap_lock);
if (take_lock)
spin_unlock(&vmap_lock);
return res;
}

Expand Down
6 changes: 3 additions & 3 deletions include/arch/x86/pagetable.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,11 +240,11 @@ static inline pte_t *l1_table_entry(pte_t *tab, const void *va) {
}

static inline pgentry_t pgentry_from_paddr(paddr_t pa, unsigned long flags) {
return (pgentry_t) ((pa & ~(PADDR_MASK & PAGE_MASK)) | (flags & _PAGE_ALL_FLAGS));
return (pgentry_t)((pa & ~(PADDR_MASK & PAGE_MASK)) | (flags & _PAGE_ALL_FLAGS));
}

static inline paddr_t paddr_from_pgentry(pgentry_t pgentry) {
return (paddr_t) (pgentry & ~PADDR_MASK) & PAGE_MASK;
return (paddr_t)(pgentry & ~PADDR_MASK) & PAGE_MASK;
}

static inline pgentry_t pgentry_from_mfn(mfn_t mfn, unsigned long flags) {
Expand Down Expand Up @@ -391,7 +391,7 @@ void *__vmap_paging(cr3_t *cr3_ptr, void *va, mfn_t mfn, unsigned int order,
unsigned long l4_flags,
#endif
unsigned long l3_flags, unsigned long l2_flags,
unsigned long l1_flags, bool special_path);
unsigned long l1_flags, bool special_path, bool paging_lock);

#endif /* __ASSEMBLY__ */

Expand Down
1 change: 1 addition & 0 deletions include/mm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ static inline bool is_frame_free(const frame_t *frame) {
return frame->flags.free;
}

void refill_from_paging(void);
frame_t *get_backup_frame(void);
frame_t *_get_backup_frame(void);

Expand Down
34 changes: 29 additions & 5 deletions mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ 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];

#define MIN_NUM_4K_FRAMES 2 + 4 + (MAX_PAGE_ORDER - PAGE_ORDER_4K)
/* 1 frame for array frame, 3 for mapping it and then one additional frame for each page
* order we might have to split */
#define MIN_NUM_4K_FRAMES 1 + 3 + (MAX_PAGE_ORDER - PAGE_ORDER_4K)
static size_t frames_count[MAX_PAGE_ORDER + 1];

static spinlock_t lock = SPINLOCK_INIT;
Expand Down Expand Up @@ -97,7 +99,7 @@ static inline void init_frames_array(frames_array_t *array) {
list_add(&array->list, &frames);
}

static frames_array_t *new_frames_array(void) {
static frames_array_t *new_frames_array(bool paging_lock) {
frames_array_t *array;
frame_t *frame;

Expand All @@ -111,7 +113,8 @@ static frames_array_t *new_frames_array(void) {
array = __vmap_paging(
&cr3,
_ptr(_ul(mfn_to_virt_map(frame->mfn)) & PAGE_ORDER_TO_MASK(PAGE_ORDER_4K)),
frame->mfn, PAGE_ORDER_4K, L4_PROT, L3_PROT, L2_PROT, L1_PROT, true);
frame->mfn, PAGE_ORDER_4K, L4_PROT, L3_PROT, L2_PROT, L1_PROT, true,
paging_lock);
if (!array)
goto error;
}
Expand Down Expand Up @@ -160,7 +163,18 @@ static inline frames_array_t *get_frames_array(void) {
return array;
}

return new_frames_array();
return new_frames_array(false);
}

static inline size_t get_frames_array_space(void) {
size_t space = 0;
frames_array_t *array;

list_for_each_entry (array, &frames, list) {
space += array->meta.free_count;
}

return space;
}

static inline bool put_frames_array(frames_array_t *array) {
Expand Down Expand Up @@ -195,7 +209,7 @@ static inline frame_t *take_frame(frame_t *frame, frames_array_t *array) {
array->meta.free_count--;

if (--total_free_frames <= MIN_FREE_FRAMES_THRESHOLD)
new_frames_array();
new_frames_array(false);

return frame;
}
Expand Down Expand Up @@ -693,3 +707,13 @@ void map_frames_array(void) {
BUG_ON(!vmap_kern_4k(va, mfn, L1_PROT));
}
}

void refill_from_paging(void) {
// make sure we have enough space to refill the 4K frames
// so we need space for one frame per
if (get_frames_array_space() < MIN_NUM_4K_FRAMES) {
new_frames_array(false);
}

try_create_4k_frames();
}

0 comments on commit ca5eb42

Please sign in to comment.