Free paging slab space used in spawning a child process
This commit is contained in:
parent
80313640f4
commit
f59c3b52c5
@ -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
|
||||||
|
|||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -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;
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user