Skip to content

Commit 8bd037d

Browse files
committed
pmm: fix reserve_frame() and add return_frame()
The reserve_frame() should track frame usage by refcount value only. Re-assignment between free_frames and busy_frames lists should be based on refcount only and not frame's free flag. Add return_frame() to complement reserve_frame() and simplify put_free_frames(). Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
1 parent 6865f84 commit 8bd037d

2 files changed

Lines changed: 29 additions & 30 deletions

File tree

include/mm/pmm.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ static inline void display_frame(const frame_t *frame) {
8181
flags.pagetable);
8282
}
8383

84+
static inline bool is_frame_used(const frame_t *frame) {
85+
return frame && frame->refcount > 0;
86+
}
87+
8488
#endif /* __ASSEMBLY__ */
8589

8690
#endif /* KTF_PMM_H */

mm/pmm.c

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -150,16 +150,26 @@ void init_pmm(void) {
150150
display_frames();
151151
}
152152

153-
static frame_t *reserve_frame(frame_t *frame, unsigned int order) {
154-
BUG_ON(!frame);
155-
BUG_ON(!frame->flags.free);
156-
frame->flags.free = false;
153+
static inline frame_t *reserve_frame(frame_t *frame) {
154+
if (!frame)
155+
return NULL;
157156

158-
BUG_ON(frame->refcount > 0);
159-
frame->refcount++;
157+
if (frame->refcount++ == 0) {
158+
list_unlink(&frame->list);
159+
list_add(&frame->list, &busy_frames[frame->order]);
160+
}
160161

161-
list_unlink(&frame->list);
162-
list_add(&frame->list, &busy_frames[order]);
162+
return frame;
163+
}
164+
165+
static inline frame_t *return_frame(frame_t *frame) {
166+
if (!is_frame_used(frame))
167+
panic("PMM: trying to return unused frame: %p\n", frame);
168+
169+
if (--frame->refcount == 0) {
170+
list_unlink(&frame->list);
171+
list_add(&frame->list, &free_frames[frame->order]);
172+
}
163173

164174
return frame;
165175
}
@@ -177,7 +187,7 @@ frame_t *get_free_frames_cond(free_frames_cond_t cb) {
177187

178188
list_for_each_entry (frame, &free_frames[order], list) {
179189
if (cb(frame)) {
180-
return reserve_frame(frame, order);
190+
return reserve_frame(frame);
181191
}
182192
}
183193
}
@@ -195,16 +205,13 @@ frame_t *get_free_frames(unsigned int order) {
195205
return NULL;
196206
}
197207

198-
frame = list_first_entry(&free_frames[order], frame_t, list);
199-
200-
frame = reserve_frame(frame, order);
208+
frame = reserve_frame(list_first_entry(&free_frames[order], frame_t, list));
201209

202210
return frame;
203211
}
204212

205213
void put_free_frames(mfn_t mfn, unsigned int order) {
206214
frame_t *frame;
207-
frame_t *found = NULL;
208215

209216
BUG_ON(mfn_invalid(mfn));
210217

@@ -213,26 +220,14 @@ void put_free_frames(mfn_t mfn, unsigned int order) {
213220

214221
list_for_each_entry (frame, &busy_frames[order], list) {
215222
if (frame->mfn == mfn) {
216-
found = frame;
217-
break;
223+
/* FIXME: Maintain order wrt mfn value */
224+
/* FIXME: Add frame merge */
225+
return_frame(frame);
226+
return;
218227
}
219228
}
220229

221-
BUG_ON(!found);
222-
223-
BUG_ON(frame->refcount == 0);
224-
frame->refcount--;
225-
226-
if (found->refcount > 0)
227-
return;
228-
229-
BUG_ON(frame->flags.free);
230-
frame->flags.free = true;
231-
232-
list_unlink(&frame->list);
233-
/* FIXME: Maintain order wrt mfn value */
234-
list_add(&frame->list, &free_frames[order]);
235-
/* FIXME: Add frame merge */
230+
panic("PMM: unable to find frame: %x in busy frames list\n");
236231
}
237232

238233
void map_used_memory(void) {

0 commit comments

Comments
 (0)