Skip to content

Commit

Permalink
pmm: detect and use highest available frame order
Browse files Browse the repository at this point in the history
After creating early frames, the process_memory_range() finds highest
available frame order (i.e. frame order whose size fits into available
physical memory size).
Instead of creating 2M frames by default, it creates frames of the
detected order and uses the rest of available space to create 2M frames
and 4K frames.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Jan 23, 2022
1 parent 1be371d commit e55bb28
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 12 deletions.
2 changes: 2 additions & 0 deletions include/mm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ typedef struct frames_array frames_array_t;

typedef bool (*free_frames_cond_t)(frame_t *free_frame);

#define ORDER_TO_SIZE(order) (PAGE_SIZE << (order))

#define FIRST_FRAME_SIBLING(mfn, order) ((mfn) % (1UL << (order)) == 0)
#define NEXT_MFN(mfn, order) ((mfn) + (1UL << (order)))
#define PREV_MFN(mfn, order) ((mfn) - (1UL << (order)))
Expand Down
30 changes: 18 additions & 12 deletions mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,8 +237,18 @@ static inline void add_frame(mfn_t mfn, unsigned int order) {
list_add_tail(&frame->list, &free_frames[order]);
}

static inline unsigned int find_max_avail_order(size_t size) {
for (unsigned int order = MAX_PAGE_ORDER; order > PAGE_ORDER_4K; order--) {
if (ORDER_TO_SIZE(order) <= size)
return order;
}

return PAGE_ORDER_4K;
}

static size_t process_memory_range(unsigned index) {
paddr_t start, end, cur;
unsigned int max_order;
addr_range_t range;
size_t size;

Expand All @@ -261,31 +271,27 @@ static size_t process_memory_range(unsigned index) {
add_early_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
else
add_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
cur += (PAGE_SIZE << PAGE_ORDER_4K);
cur += ORDER_TO_SIZE(PAGE_ORDER_4K);
}

/* Add initial 2M frames and align to 1G. */
while (cur % PAGE_SIZE_1G && cur + PAGE_SIZE_2M <= end) {
add_frame(paddr_to_mfn(cur), PAGE_ORDER_2M);
cur += (PAGE_SIZE << PAGE_ORDER_2M);
}
max_order = find_max_avail_order(end - cur);

/* Add all remaining 1G frames. */
while (cur + PAGE_SIZE_1G <= end) {
add_frame(paddr_to_mfn(cur), PAGE_ORDER_1G);
cur += (PAGE_SIZE << PAGE_ORDER_1G);
/* Add all available max_order frames. */
while (cur + ORDER_TO_SIZE(max_order) <= end) {
add_frame(paddr_to_mfn(cur), max_order);
cur += ORDER_TO_SIZE(max_order);
}

/* Add all remaining 2M frames. */
while (cur + PAGE_SIZE_2M <= end) {
add_frame(paddr_to_mfn(cur), PAGE_ORDER_2M);
cur += (PAGE_SIZE << PAGE_ORDER_2M);
cur += ORDER_TO_SIZE(PAGE_ORDER_2M);
}

/* Add all remaining 4K frames. */
while (cur < end) {
add_frame(paddr_to_mfn(cur), PAGE_ORDER_4K);
cur += (PAGE_SIZE << PAGE_ORDER_4K);
cur += ORDER_TO_SIZE(PAGE_ORDER_4K);
}

if (cur != end) {
Expand Down

0 comments on commit e55bb28

Please sign in to comment.