diff options
Diffstat (limited to 'kernel/fork.c')
| -rw-r--r-- | kernel/fork.c | 31 | 
1 files changed, 14 insertions, 17 deletions
| diff --git a/kernel/fork.c b/kernel/fork.c index 280bd44ac441..8a069612eac3 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
| @@ -182,37 +182,37 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
| 182 | } | 182 | } | 
| 183 | 183 | ||
| 184 | #ifdef CONFIG_MMU | 184 | #ifdef CONFIG_MMU | 
| 185 | static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) | 185 | static inline int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) | 
| 186 | { | 186 | { | 
| 187 | struct vm_area_struct * mpnt, *tmp, **pprev; | 187 | struct vm_area_struct *mpnt, *tmp, **pprev; | 
| 188 | struct rb_node **rb_link, *rb_parent; | 188 | struct rb_node **rb_link, *rb_parent; | 
| 189 | int retval; | 189 | int retval; | 
| 190 | unsigned long charge; | 190 | unsigned long charge; | 
| 191 | struct mempolicy *pol; | 191 | struct mempolicy *pol; | 
| 192 | 192 | ||
| 193 | down_write(&oldmm->mmap_sem); | 193 | down_write(&oldmm->mmap_sem); | 
| 194 | flush_cache_mm(current->mm); | 194 | flush_cache_mm(oldmm); | 
| 195 | down_write(&mm->mmap_sem); | ||
| 196 | |||
| 195 | mm->locked_vm = 0; | 197 | mm->locked_vm = 0; | 
| 196 | mm->mmap = NULL; | 198 | mm->mmap = NULL; | 
| 197 | mm->mmap_cache = NULL; | 199 | mm->mmap_cache = NULL; | 
| 198 | mm->free_area_cache = oldmm->mmap_base; | 200 | mm->free_area_cache = oldmm->mmap_base; | 
| 199 | mm->cached_hole_size = ~0UL; | 201 | mm->cached_hole_size = ~0UL; | 
| 200 | mm->map_count = 0; | 202 | mm->map_count = 0; | 
| 201 | set_mm_counter(mm, rss, 0); | ||
| 202 | set_mm_counter(mm, anon_rss, 0); | ||
| 203 | cpus_clear(mm->cpu_vm_mask); | 203 | cpus_clear(mm->cpu_vm_mask); | 
| 204 | mm->mm_rb = RB_ROOT; | 204 | mm->mm_rb = RB_ROOT; | 
| 205 | rb_link = &mm->mm_rb.rb_node; | 205 | rb_link = &mm->mm_rb.rb_node; | 
| 206 | rb_parent = NULL; | 206 | rb_parent = NULL; | 
| 207 | pprev = &mm->mmap; | 207 | pprev = &mm->mmap; | 
| 208 | 208 | ||
| 209 | for (mpnt = current->mm->mmap ; mpnt ; mpnt = mpnt->vm_next) { | 209 | for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { | 
| 210 | struct file *file; | 210 | struct file *file; | 
| 211 | 211 | ||
| 212 | if (mpnt->vm_flags & VM_DONTCOPY) { | 212 | if (mpnt->vm_flags & VM_DONTCOPY) { | 
| 213 | long pages = vma_pages(mpnt); | 213 | long pages = vma_pages(mpnt); | 
| 214 | mm->total_vm -= pages; | 214 | mm->total_vm -= pages; | 
| 215 | __vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, | 215 | vm_stat_account(mm, mpnt->vm_flags, mpnt->vm_file, | 
| 216 | -pages); | 216 | -pages); | 
| 217 | continue; | 217 | continue; | 
| 218 | } | 218 | } | 
| @@ -253,12 +253,8 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) | |||
| 253 | } | 253 | } | 
| 254 | 254 | ||
| 255 | /* | 255 | /* | 
| 256 | * Link in the new vma and copy the page table entries: | 256 | * Link in the new vma and copy the page table entries. | 
| 257 | * link in first so that swapoff can see swap entries. | ||
| 258 | * Note that, exceptionally, here the vma is inserted | ||
| 259 | * without holding mm->mmap_sem. | ||
| 260 | */ | 257 | */ | 
| 261 | spin_lock(&mm->page_table_lock); | ||
| 262 | *pprev = tmp; | 258 | *pprev = tmp; | 
| 263 | pprev = &tmp->vm_next; | 259 | pprev = &tmp->vm_next; | 
| 264 | 260 | ||
| @@ -267,8 +263,7 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) | |||
| 267 | rb_parent = &tmp->vm_rb; | 263 | rb_parent = &tmp->vm_rb; | 
| 268 | 264 | ||
| 269 | mm->map_count++; | 265 | mm->map_count++; | 
| 270 | retval = copy_page_range(mm, current->mm, tmp); | 266 | retval = copy_page_range(mm, oldmm, tmp); | 
| 271 | spin_unlock(&mm->page_table_lock); | ||
| 272 | 267 | ||
| 273 | if (tmp->vm_ops && tmp->vm_ops->open) | 268 | if (tmp->vm_ops && tmp->vm_ops->open) | 
| 274 | tmp->vm_ops->open(tmp); | 269 | tmp->vm_ops->open(tmp); | 
| @@ -277,9 +272,9 @@ static inline int dup_mmap(struct mm_struct * mm, struct mm_struct * oldmm) | |||
| 277 | goto out; | 272 | goto out; | 
| 278 | } | 273 | } | 
| 279 | retval = 0; | 274 | retval = 0; | 
| 280 | |||
| 281 | out: | 275 | out: | 
| 282 | flush_tlb_mm(current->mm); | 276 | up_write(&mm->mmap_sem); | 
| 277 | flush_tlb_mm(oldmm); | ||
| 283 | up_write(&oldmm->mmap_sem); | 278 | up_write(&oldmm->mmap_sem); | 
| 284 | return retval; | 279 | return retval; | 
| 285 | fail_nomem_policy: | 280 | fail_nomem_policy: | 
| @@ -323,6 +318,8 @@ static struct mm_struct * mm_init(struct mm_struct * mm) | |||
| 323 | INIT_LIST_HEAD(&mm->mmlist); | 318 | INIT_LIST_HEAD(&mm->mmlist); | 
| 324 | mm->core_waiters = 0; | 319 | mm->core_waiters = 0; | 
| 325 | mm->nr_ptes = 0; | 320 | mm->nr_ptes = 0; | 
| 321 | set_mm_counter(mm, file_rss, 0); | ||
| 322 | set_mm_counter(mm, anon_rss, 0); | ||
| 326 | spin_lock_init(&mm->page_table_lock); | 323 | spin_lock_init(&mm->page_table_lock); | 
| 327 | rwlock_init(&mm->ioctx_list_lock); | 324 | rwlock_init(&mm->ioctx_list_lock); | 
| 328 | mm->ioctx_list = NULL; | 325 | mm->ioctx_list = NULL; | 
| @@ -499,7 +496,7 @@ static int copy_mm(unsigned long clone_flags, struct task_struct * tsk) | |||
| 499 | if (retval) | 496 | if (retval) | 
| 500 | goto free_pt; | 497 | goto free_pt; | 
| 501 | 498 | ||
| 502 | mm->hiwater_rss = get_mm_counter(mm,rss); | 499 | mm->hiwater_rss = get_mm_rss(mm); | 
| 503 | mm->hiwater_vm = mm->total_vm; | 500 | mm->hiwater_vm = mm->total_vm; | 
| 504 | 501 | ||
| 505 | good_mm: | 502 | good_mm: | 
