Skip to content

Commit

Permalink
mm/pmm: add frame finder functions for MFN and paddr
Browse files Browse the repository at this point in the history
Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Nov 17, 2023
1 parent 4882428 commit 7cbcafe
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 4 deletions.
17 changes: 17 additions & 0 deletions include/mm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ extern frame_t *get_free_frames(unsigned int order);
extern void put_free_frames(mfn_t mfn, unsigned int order);
extern void reclaim_frame(mfn_t mfn, unsigned int order);

extern frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order);
extern frame_t *find_busy_mfn_frame(mfn_t mfn, unsigned int order);
extern frame_t *find_mfn_frame(mfn_t mfn, unsigned int order);
extern frame_t *find_free_paddr_frame(paddr_t paddr);
extern frame_t *find_busy_paddr_frame(paddr_t paddr);
extern frame_t *find_paddr_frame(paddr_t paddr);

extern void map_used_memory(void);
extern void map_frames_array(void);

Expand All @@ -100,6 +107,16 @@ static inline frame_t *get_first_frame(list_head_t *frames, unsigned int order)
return list_first_entry(&frames[order], frame_t, list);
}

static inline bool frame_has_paddr(const frame_t *frame, paddr_t pa) {
if (!frame)
return false;

paddr_t start_pa = mfn_to_paddr(frame->mfn);
paddr_t end_pa = start_pa + ORDER_TO_SIZE(frame->order) - 1;

return pa >= start_pa && pa <= end_pa;
}

static inline frame_t *get_free_frame(void) {
return get_free_frames(PAGE_ORDER_4K);
}
Expand Down
85 changes: 81 additions & 4 deletions mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ static inline bool return_frame(frame_t *frame) {
return false;
}

static frame_t *find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order) {
static frame_t *_find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order) {
frame_t *frame;

if (!has_frames(list, order))
Expand All @@ -421,6 +421,83 @@ static frame_t *find_mfn_frame(list_head_t *list, mfn_t mfn, unsigned int order)
return NULL;
}

frame_t *find_free_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

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

return frame;
}

frame_t *find_busy_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

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

return frame;
}

frame_t *find_mfn_frame(mfn_t mfn, unsigned int order) {
frame_t *frame;

spin_lock(&lock);
frame = _find_mfn_frame(busy_frames, mfn, order);
if (!frame)
frame = _find_mfn_frame(free_frames, mfn, order);
spin_unlock(&lock);

return frame;
}

static frame_t *_find_paddr_frame(list_head_t *list, paddr_t paddr) {
frame_t *frame;

for_each_order (order) {
list_for_each_entry (frame, &list[order], list) {
if (frame_has_paddr(frame, paddr))
return frame;
}
}

return NULL;
}

frame_t *find_free_paddr_frame(paddr_t paddr) {
frame_t *frame;

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

return frame;
}

frame_t *find_busy_paddr_frame(paddr_t paddr) {
frame_t *frame;

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

return frame;
}

frame_t *find_paddr_frame(paddr_t paddr) {
frame_t *frame;

spin_lock(&lock);
frame = _find_paddr_frame(busy_frames, paddr);
if (!frame)
frame = _find_paddr_frame(free_frames, paddr);
spin_unlock(&lock);

return frame;
}

static frame_t *find_larger_frame(list_head_t *list, unsigned int order) {
while (++order <= MAX_PAGE_ORDER) {
frame_t *frame = get_first_frame(list, order);
Expand Down Expand Up @@ -491,13 +568,13 @@ static void merge_frames(frame_t *first) {

if (FIRST_FRAME_SIBLING(first->mfn, first->order + 1)) {
mfn_t next_mfn = NEXT_MFN(first->mfn, first->order);
second = find_mfn_frame(free_frames, next_mfn, first->order);
second = _find_mfn_frame(free_frames, next_mfn, first->order);
}
else {
/* Second frame sibling */
mfn_t prev_mfn = PREV_MFN(first->mfn, first->order);
second = first;
first = find_mfn_frame(free_frames, prev_mfn, first->order);
first = _find_mfn_frame(free_frames, prev_mfn, first->order);
}

if (!first || !second)
Expand Down Expand Up @@ -547,7 +624,7 @@ void put_free_frames(mfn_t mfn, unsigned int order) {
ASSERT(order <= MAX_PAGE_ORDER);

spin_lock(&lock);
frame = find_mfn_frame(busy_frames, mfn, order);
frame = _find_mfn_frame(busy_frames, mfn, order);
if (!frame) {
warning("PMM: unable to find frame: %lx, order: %u among busy frames", mfn,
order);
Expand Down

0 comments on commit 7cbcafe

Please sign in to comment.