Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PMM: add simple buddy allocator (splitting and merging frames) #244

Merged
merged 6 commits into from
Jan 23, 2022

Conversation

wipawel
Copy link
Contributor

@wipawel wipawel commented Jan 22, 2022

The split_frame() breaks given frame into two smaller frames.
Original frame's frame_t struct is reused, frame order is decremented
and the struct is re-assigned to lower order free frame list.
Another, new frame is created for the second half of the original frame.

The get_free_frame(), when cannot find free frame of requested order,
keeps finding first free higher-order frame and split it, until desired
order frame becomes available.

The merge_frames() attempts to merge two consecutive frames into a higher
order frame. It only merges higher-order aligned frame with its following
frame. To do so, it checks if the frame being returned is higher-order
aligned frame and attempts to find its following frame. If the frame
being returned is not higher-order aligned, it tries to find its preceding
frame, which will be properly aligned.
When the two frames are found, the first frame's struct is reused, order
is incremented and the struct is relinked to higher order free frames list.
The second frame struct is destroyed.

The merge_frames() calls itself recursively in attempt to merge all merge-
able higher-order frames for all orders.

The put_free_frames() find corresponding frame struct for given MFN and
order. If the frame is fully returned (there is no more references) and
relinked from busy_frames to free_frames, it attempts to merge the frame.

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.

Implements #7.

The destroy_frame() makes sure to unlink a frame from its list and
update frames_count. Then it clears up frame's frame_array entry.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
It allows to find a frame_t struct pointer for specified MFN and order.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
The split_frame() breaks given frame into two smaller frames.
Original frame's frame_t struct is reused, frame order is decremented
and the struct is re-assigned to lower order free frame list.
Another, new frame is created for the second half of the original frame.

The get_free_frame(), when cannot find free frame of requested order,
keeps finding first free higher-order frame and split it, until desired
order frame becomes available.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
The merge_frames() attempts to merge two consecutive frames into a higher
order frame. It only merges higher-order aligned frame with its following
frame. To do so, it checks if the frame being returned is higher-order
aligned frame and attempts to find its following frame. If the frame
being returned is not higher-order aligned, it tries to find its preceding
frame, which will be properly aligned.
When the two frames are found, the first frame's struct is reused, order
is incremented and the struct is relinked to higher order free frames list.
The second frame struct is destroyed.

The merge_frames() calls itself recursively in attempt to merge all merge-
able higher-order frames for all orders.

The put_free_frames() find corresponding frame struct for given MFN and
order. If the frame is fully returned (there is no more references) and
relinked from busy_frames to free_frames, it attempts to merge the frame.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
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]>
@wipawel wipawel added feature New feature or request Priority: 2 Very important feature labels Jan 22, 2022
@wipawel wipawel added this to the v0.5.0 milestone Jan 22, 2022
@wipawel wipawel linked an issue Jan 22, 2022 that may be closed by this pull request
Copy link
Contributor

@bjoernd bjoernd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing obviously stands out. Test cases would make me even more confident.

mm/pmm.c Show resolved Hide resolved
@wipawel wipawel merged commit e55bb28 into KernelTestFramework:mainline Jan 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New feature or request Priority: 2 Very important feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement buddy allocator (Physical Memory Manager)
2 participants