Keep VM areas sorted, and add function to destroy VM areas.

This commit is contained in:
Enrico Fraccaroli (Galfurian)
2023-06-14 12:54:16 -04:00
parent e23c434cc6
commit af77072301
2 changed files with 60 additions and 4 deletions
+17 -4
View File
@@ -136,6 +136,13 @@ typedef struct mm_struct_t {
/// @brief Cache used to store page tables.
extern kmem_cache_t *pgtbl_cache;
static inline int vm_area_compare(const list_head *a, const list_head *b)
{
vm_area_struct_t *_a = list_entry(a, vm_area_struct_t, vm_list);
vm_area_struct_t *_b = list_entry(b, vm_area_struct_t, vm_list);
return _a->vm_start > _b->vm_end;
}
/// @brief Initializes paging
/// @param info Information coming from bootloader.
void paging_init(boot_info_t *info);
@@ -229,16 +236,22 @@ uint32_t create_vm_area(mm_struct_t *mm,
uint32_t gfpflags);
/// @brief Clone a virtual memory area, using copy on write if specified
/// @param mm The memory descriptor which will contain the new segment.
/// @param area The area to clone
/// @param cow Whether to use copy-on-write or just copy everything.
/// @param gfpflags The Get Free Pages flags.
/// @param mm the memory descriptor which will contain the new segment.
/// @param area the area to clone
/// @param cow whether to use copy-on-write or just copy everything.
/// @param gfpflags the Get Free Pages flags.
/// @return Zero on success.
uint32_t clone_vm_area(mm_struct_t *mm,
vm_area_struct_t *area,
int cow,
uint32_t gfpflags);
/// @brief Destroys a virtual memory area.
/// @param mm the memory descriptor from which we will destroy the area.
/// @param area the are we want to destroy.
/// @return 0 if the area was destroyed, or 1 if the operation failed.
int destroy_vm_area(mm_struct_t *mm, vm_area_struct_t *area);
/// @brief Creates the main memory descriptor.
/// @param stack_size The size of the stack in byte.
/// @return The Memory Descriptor created.
+43
View File
@@ -15,6 +15,11 @@
#include "mem/kheap.h"
#include "descriptor_tables/isr.h"
#include "system/panic.h"
#include "sys/list_head_algorithm.h"
#include "stddef.h"
#include "stdint.h"
#include "sys/list_head.h"
#include "sys/mman.h"
#include "assert.h"
#include "string.h"
@@ -178,6 +183,9 @@ uint32_t create_vm_area(mm_struct_t *mm,
list_head_insert_after(&new_segment->vm_list, &mm->mmap_list);
mm->mmap_cache = new_segment;
// Sort the mmap_list.
list_head_sort(&mm->mmap_list, vm_area_compare);
// Update memory descriptor info.
mm->map_count++;
@@ -234,6 +242,41 @@ uint32_t clone_vm_area(mm_struct_t *mm, vm_area_struct_t *area, int cow, uint32_
return 0;
}
int destroy_vm_area(mm_struct_t *mm, vm_area_struct_t *area)
{
size_t area_total_size, area_size, area_start;
uint32_t order, block_size;
page_t *phy_page;
// Get the total area size.
area_total_size = area->vm_end - area->vm_start;
// Get the starting location.
area_start = area->vm_start;
// Free all the memory.
while (area_total_size > 0) {
area_size = area_total_size;
phy_page = mem_virtual_to_page(mm->pgd, area_start, &area_size);
// If the pages are marked as copy-on-write, do not deallocate them!
if (page_count(phy_page) > 1) {
order = phy_page->bbpage.order;
block_size = 1UL << order;
for (int i = 0; i < block_size; i++) {
page_dec(phy_page + i);
}
} else {
__free_pages(phy_page);
}
area_total_size -= area_size;
area_start += area_size;
}
// Delete segment from the mmap.
list_head_remove(&area->vm_list);
// Free the memory.
kmem_cache_free(area);
// Reduce the counter for memory mapped areas.
--mm->map_count;
return 0;
}
static void __init_pagedir(page_directory_t *pdir)
{
*pdir = (page_directory_t){ { 0 } };