sandbox: vm: implement page freeing; merge/split bugfix
This commit is contained in:
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user