Free paging slab space used in spawning a child process

This commit is contained in:
Sparchatus 2022-05-05 09:21:30 +00:00
parent 80313640f4
commit f59c3b52c5
3 changed files with 40 additions and 0 deletions

View File

@ -135,4 +135,12 @@ static inline lvaddr_t paging_genvaddr_to_lvaddr(genvaddr_t genvaddr) {
// NOTE rueegges: added debug helper // NOTE rueegges: added debug helper
void pt_print_state(struct paging_state *st); void pt_print_state(struct paging_state *st);
/**
* @brief Destructive action! NOT THREAD SAFE
* This frees all the slab space occupied by the given paging state without performing any unmapping operations
*
* @param st paging state to perform destructive action on
*/
void paging_free_slabs(struct paging_state *st);
#endif // LIBBARRELFISH_PAGING_H #endif // LIBBARRELFISH_PAGING_H

View File

@ -1049,3 +1049,31 @@ errval_t paging_unmap(struct paging_state *st, const void *region)
return err; return err;
} }
/**
* @brief Function to recursively free all the slab space. NOT THREAD SAFE
*
* @param pt page table to recursively free the slab space for
* @return errval_t
*/
static void paging_free_page_table_tree(struct paging_state *st, struct pt_t *pt) {
if(pt == NULL) return;
if(pt->children != NULL) {
for(size_t i = 0; i < PTABLE_ENTRIES; ++i) {
paging_free_page_table_tree(st, pt->children[i]);
}
slab_free(&st->pt_children_slabs, pt->children);
}
slab_free(&st->pt_slabs, pt);
}
void paging_free_slabs(struct paging_state *st) {
// free the slab space used by the child paging state so it can be reused by the parent
for(size_t i = 0; i < PTABLE_ENTRIES; ++i){
paging_free_page_table_tree(st, st->l0_pt.children[i]);
}
for(struct pt_vaddr_reg_t *reg = st->vaddr_head.next; reg != NULL; reg = reg->next){
slab_free(&st->pt_slabs, reg);
}
}

View File

@ -511,6 +511,9 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
struct paging_state *child_paging_state = &_child_paging_state; struct paging_state *child_paging_state = &_child_paging_state;
// 64 * 1024 is enough to catch null pointers and also enough to not conflict with child starting paging_alloc at VADDR_OFFSET // 64 * 1024 is enough to catch null pointers and also enough to not conflict with child starting paging_alloc at VADDR_OFFSET
err = paging_init_state_foreign(child_paging_state, VADDR_LOWEST_NON_NULL, si->vspace_cap_l0_pagetable, get_default_slot_allocator()); err = paging_init_state_foreign(child_paging_state, VADDR_LOWEST_NON_NULL, si->vspace_cap_l0_pagetable, get_default_slot_allocator());
// we use the parent's slab allocators because we want to later free the child paging state's memory
child_paging_state->pt_slabs = get_current_paging_state()->pt_slabs;
child_paging_state->pt_children_slabs = get_current_paging_state()->pt_children_slabs;
if (err_is_fail(err)) return err_push(err, SPAWN_ERR_PAGING_INIT); if (err_is_fail(err)) return err_push(err, SPAWN_ERR_PAGING_INIT);
// - Load the ELF binary // - Load the ELF binary
@ -641,6 +644,7 @@ errval_t spawn_load_argv(int argc, char *argv[], struct spawninfo *si,
if (err_is_fail(err)) { if (err_is_fail(err)) {
return err_push(err, SPAWN_ERR_SERIALISE_VSPACE); return err_push(err, SPAWN_ERR_SERIALISE_VSPACE);
} }
paging_free_slabs(child_paging_state);
// so we don't use it after serializing // so we don't use it after serializing
child_paging_state = NULL; child_paging_state = NULL;