sandbox: vm: implement page freeing; merge/split bugfix

This commit is contained in:
2023-02-01 17:05:14 +00:00
parent ca92093c10
commit 9409ebbb19
4 changed files with 91 additions and 21 deletions

View File

@@ -47,7 +47,7 @@ static void *system_memory = NULL;
static void print_free_pages(vm_zone_t *z)
{
printf(" * %s:\n", z->z_info.zd_name);
for (int i = VM_PAGE_MIN_ORDER; i <= VM_PAGE_MAX_ORDER; i++) {
if (queue_length(&z->z_free_pages[i]) == 0) {
continue;
@@ -55,8 +55,8 @@ static void print_free_pages(vm_zone_t *z)
char size_str[64];
data_size_to_string(vm_page_order_to_bytes(i), size_str, sizeof size_str);
printf(" - %u pages with size %s (order-%u)\n", queue_length(&z->z_free_pages[i]), size_str, i);
printf(" - %u pages with size %s (order-%u)\n", queue_length(&z->z_free_pages[i]), size_str, i);
}
}
@@ -184,11 +184,58 @@ int memory_test(void)
assert(a->p_flags & VM_PAGE_HEAD);
assert(b->p_flags & VM_PAGE_HEAD);
size_t nr_frames = vm_page_order_to_pages(VM_PAGE_128K);
for (size_t i = 0; i < nr_frames; i++) {
printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(a + i), a[i].p_order, a[i].p_flags);
assert(a[i].p_flags & VM_PAGE_HUGE);
assert((a[i].p_flags & VM_PAGE_RESERVED) == 0);
printf("first page block:\n");
vm_page_foreach (a, i) {
printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags);
assert(i->p_flags & VM_PAGE_HUGE);
assert((i->p_flags & VM_PAGE_RESERVED) == 0);
}
printf("second page block:\n");
vm_page_foreach (b, i) {
printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags);
assert(i->p_flags & VM_PAGE_HUGE);
assert((i->p_flags & VM_PAGE_RESERVED) == 0);
}
pg = vm_page_merge(a, b);
if (pg) {
char size_str[64];
data_size_to_string(vm_page_order_to_bytes(pg->p_order), size_str, sizeof size_str);
printf("merged pages 0x%lx and 0x%lx to single page of size %s:\n", vm_page_get_paddr(a), vm_page_get_paddr(b), size_str);
size_t block_sz = 0;
vm_page_foreach (pg, i) {
printf(" 0x%lx: order:%u, flags:0x%x\n", vm_page_get_paddr(i), i->p_order, i->p_flags);
assert(i->p_flags & VM_PAGE_HUGE);
assert((i->p_flags & VM_PAGE_RESERVED) == 0);
block_sz += VM_PAGE_SIZE;
}
assert(block_sz == vm_page_order_to_bytes(pg->p_order));
vm_page_free(pg);
} else {
printf("cannot merge pages 0x%lx and 0x%lx\n", vm_page_get_paddr(a), vm_page_get_paddr(b));
}
}
pg = vm_page_alloc(VM_PAGE_128K, 0);
printf("allocated 128K at 0x%lx\n", vm_page_get_paddr(pg));
if (vm_page_split(pg, &a, &b) == 0) {
assert(a->p_order == VM_PAGE_64K);
assert(b->p_order == VM_PAGE_64K);
printf("split 128K block into two 64K blocks\n");
vm_page_free(a);
vm_page_free(b);
/* if these conditions are true, the two blocks were successfully
merged after being freed. */
if (a->p_order == VM_PAGE_128K && b->p_order == VM_PAGE_128K) {
printf("two 64K blocks were merged into one 128K block after free\n");
} else {
printf("two 64K blocks were NOT merged into one 128K block after free!\n");
}
}