Skip to content

Commit a05a6da

Browse files
committed
mem: get frames with a specific condition
Add an API to allow returning a frame with a user-defined condition, provided by a callback, instead of choosing the first available one. Signed-off-by: Daniele Ahmed <ahmeddan amazon c;0m >
1 parent 0575b4f commit a05a6da

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

include/mm/pmm.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ typedef struct frame frame_t;
8383

8484
#define for_each_order(order) for (int order = 0; order < MAX_PAGE_ORDER + 1; order++)
8585

86+
typedef bool (*free_frames_cond_t)(frame_t *free_frame);
87+
8688
/* External definitions */
8789

8890
extern void display_memory_map(void);
@@ -96,6 +98,7 @@ extern bool paddr_invalid(paddr_t pa);
9698

9799
extern void init_pmm(void);
98100

101+
extern frame_t *get_free_frames_cond(free_frames_cond_t cb);
99102
extern mfn_t get_free_frames(unsigned int order);
100103
extern void put_frame(mfn_t mfn, unsigned int order);
101104
extern void reclaim_frame(mfn_t mfn, unsigned int order);

mm/pmm.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,40 @@ void init_pmm(void) {
245245
}
246246
}
247247

248+
static frame_t *reserve_frame(frame_t *frame, unsigned int order) {
249+
BUG_ON(!frame);
250+
BUG_ON(!frame->free);
251+
frame->free = false;
252+
253+
BUG_ON(frame->refcount > 0);
254+
frame->refcount++;
255+
256+
list_unlink(&frame->list);
257+
list_add(&frame->list, &busy_frames[order]);
258+
259+
return frame;
260+
}
261+
262+
/* Reserves and returns the first free frame
263+
* fulfilling the condition specified by
264+
* the callback
265+
*/
266+
frame_t *get_free_frames_cond(free_frames_cond_t cb) {
267+
frame_t *frame;
268+
269+
for_each_order (order) {
270+
if (list_is_empty(&free_frames[order]))
271+
continue;
272+
273+
list_for_each_entry (frame, &free_frames[order], list) {
274+
if (cb(frame)) {
275+
return reserve_frame(frame, order);
276+
}
277+
}
278+
}
279+
return NULL;
280+
}
281+
248282
mfn_t get_free_frames(unsigned int order) {
249283
frame_t *frame;
250284

@@ -257,14 +291,8 @@ mfn_t get_free_frames(unsigned int order) {
257291
}
258292

259293
frame = list_first_entry(&free_frames[order], frame_t, list);
260-
BUG_ON(!frame->free);
261-
frame->free = false;
262294

263-
BUG_ON(frame->refcount > 0);
264-
frame->refcount++;
265-
266-
list_unlink(&frame->list);
267-
list_add(&frame->list, &busy_frames[order]);
295+
frame = reserve_frame(frame, order);
268296

269297
return frame->mfn;
270298
}

0 commit comments

Comments
 (0)