From daffc1d08407146069047d11fe2934c50a6a99c0 Mon Sep 17 00:00:00 2001 From: Bahadir Balban Date: Fri, 7 Nov 2008 20:39:11 +0200 Subject: [PATCH] Split vmas had no objects. Now fixed. When sys_munmap() splits a vma, the new vma had no copy of the objects in the original vma. Now we fixed that using a vma_copy_links() function which can also be used as part of fork(). --- tasks/mm0/include/vm_area.h | 1 + tasks/mm0/src/fault.c | 26 ++++++++++++++++++++++++++ tasks/mm0/src/munmap.c | 9 ++++++++- tasks/mm0/src/task.c | 20 ++------------------ 4 files changed, 37 insertions(+), 19 deletions(-) diff --git a/tasks/mm0/include/vm_area.h b/tasks/mm0/include/vm_area.h index afdb753..d6192b1 100644 --- a/tasks/mm0/include/vm_area.h +++ b/tasks/mm0/include/vm_area.h @@ -252,6 +252,7 @@ static inline void task_add_vma(struct tcb *task, struct vm_area *vma) /* Main page fault entry point */ int page_fault_handler(struct tcb *faulty_task, fault_kdata_t *fkdata); +int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma); int vma_drop_merge_delete(struct vm_area *vma, struct vm_obj_link *link); int vma_drop_merge_delete_all(struct vm_area *vma); diff --git a/tasks/mm0/src/fault.c b/tasks/mm0/src/fault.c index defb36a..99cc9a1 100644 --- a/tasks/mm0/src/fault.c +++ b/tasks/mm0/src/fault.c @@ -262,6 +262,32 @@ struct page *copy_to_new_page(struct page *orig) } +/* Copy all mapped object link stack from vma to new vma */ +int vma_copy_links(struct vm_area *new_vma, struct vm_area *vma) +{ + struct vm_obj_link *vmo_link, *new_link; + + /* Get the first object on the vma */ + BUG_ON(list_empty(&vma->vm_obj_list)); + vmo_link = list_entry(vma->vm_obj_list.next, + struct vm_obj_link, list); + do { + /* Create a new link */ + new_link = vm_objlink_create(); + + /* Link object with new link */ + vm_link_object(new_link, vmo_link->obj); + + /* Add the new link to vma in object order */ + list_add_tail(&new_link->list, &new_vma->vm_obj_list); + + /* Continue traversing links, doing the same copying */ + } while((vmo_link = vma_next_link(&vmo_link->list, + &vma->vm_obj_list))); + + return 0; +} + /* * Determine if an object is deletable. * diff --git a/tasks/mm0/src/munmap.c b/tasks/mm0/src/munmap.c index da2dfdd..7ce5914 100644 --- a/tasks/mm0/src/munmap.c +++ b/tasks/mm0/src/munmap.c @@ -8,7 +8,7 @@ #include #include #include - +#include /* This splits a vma, splitter region must be in the *middle* of original vma */ int vma_split(struct vm_area *vma, struct tcb *task, @@ -33,6 +33,13 @@ int vma_split(struct vm_area *vma, struct tcb *task, vma->pfn_end = pfn_start; new->flags = vma->flags; + /* + * Copy the object links of original vma to new vma. A split like this + * increases the map count of mapped object(s) since now 2 vmas on the + * same task maps the same object(s). + */ + vma_copy_links(new, vma); + /* Add new one next to original vma */ list_add_tail(&new->list, &vma->list); diff --git a/tasks/mm0/src/task.c b/tasks/mm0/src/task.c index d9bf9ae..b0dc262 100644 --- a/tasks/mm0/src/task.c +++ b/tasks/mm0/src/task.c @@ -129,7 +129,6 @@ int tcb_destroy(struct tcb *task) int copy_vmas(struct tcb *to, struct tcb *from) { struct vm_area *vma, *new_vma; - struct vm_obj_link *vmo_link, *new_link; list_for_each_entry(vma, &from->vm_area_head->list, list) { @@ -137,23 +136,8 @@ int copy_vmas(struct tcb *to, struct tcb *from) new_vma = vma_new(vma->pfn_start, vma->pfn_end - vma->pfn_start, vma->flags, vma->file_offset); - /* Get the first object on the vma */ - BUG_ON(list_empty(&vma->vm_obj_list)); - vmo_link = list_entry(vma->vm_obj_list.next, - struct vm_obj_link, list); - do { - /* Create a new link */ - new_link = vm_objlink_create(); - - /* Link object with new link */ - vm_link_object(new_link, vmo_link->obj); - - /* Add the new link to vma in object order */ - list_add_tail(&new_link->list, &new_vma->vm_obj_list); - - /* Continue traversing links, doing the same copying */ - } while((vmo_link = vma_next_link(&vmo_link->list, - &vma->vm_obj_list))); + /* Copy all object links */ + vma_copy_links(new_vma, vma); /* All link copying is finished, now add the new vma to task */ task_add_vma(to, new_vma);