aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 2b44d82b8237..8e7e135d0817 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -383,15 +383,14 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
383 get_file(file); 383 get_file(file);
384 if (tmp->vm_flags & VM_DENYWRITE) 384 if (tmp->vm_flags & VM_DENYWRITE)
385 atomic_dec(&inode->i_writecount); 385 atomic_dec(&inode->i_writecount);
386 spin_lock(&mapping->i_mmap_lock); 386 mutex_lock(&mapping->i_mmap_mutex);
387 if (tmp->vm_flags & VM_SHARED) 387 if (tmp->vm_flags & VM_SHARED)
388 mapping->i_mmap_writable++; 388 mapping->i_mmap_writable++;
389 tmp->vm_truncate_count = mpnt->vm_truncate_count;
390 flush_dcache_mmap_lock(mapping); 389 flush_dcache_mmap_lock(mapping);
391 /* insert tmp into the share list, just after mpnt */ 390 /* insert tmp into the share list, just after mpnt */
392 vma_prio_tree_add(tmp, mpnt); 391 vma_prio_tree_add(tmp, mpnt);
393 flush_dcache_mmap_unlock(mapping); 392 flush_dcache_mmap_unlock(mapping);
394 spin_unlock(&mapping->i_mmap_lock); 393 mutex_unlock(&mapping->i_mmap_mutex);
395 } 394 }
396 395
397 /* 396 /*
@@ -486,6 +485,20 @@ static void mm_init_aio(struct mm_struct *mm)
486#endif 485#endif
487} 486}
488 487
488int mm_init_cpumask(struct mm_struct *mm, struct mm_struct *oldmm)
489{
490#ifdef CONFIG_CPUMASK_OFFSTACK
491 if (!alloc_cpumask_var(&mm->cpu_vm_mask_var, GFP_KERNEL))
492 return -ENOMEM;
493
494 if (oldmm)
495 cpumask_copy(mm_cpumask(mm), mm_cpumask(oldmm));
496 else
497 memset(mm_cpumask(mm), 0, cpumask_size());
498#endif
499 return 0;
500}
501
489static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p) 502static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
490{ 503{
491 atomic_set(&mm->mm_users, 1); 504 atomic_set(&mm->mm_users, 1);
@@ -522,10 +535,20 @@ struct mm_struct * mm_alloc(void)
522 struct mm_struct * mm; 535 struct mm_struct * mm;
523 536
524 mm = allocate_mm(); 537 mm = allocate_mm();
525 if (mm) { 538 if (!mm)
526 memset(mm, 0, sizeof(*mm)); 539 return NULL;
527 mm = mm_init(mm, current); 540
541 memset(mm, 0, sizeof(*mm));
542 mm = mm_init(mm, current);
543 if (!mm)
544 return NULL;
545
546 if (mm_init_cpumask(mm, NULL)) {
547 mm_free_pgd(mm);
548 free_mm(mm);
549 return NULL;
528 } 550 }
551
529 return mm; 552 return mm;
530} 553}
531 554
@@ -537,6 +560,7 @@ struct mm_struct * mm_alloc(void)
537void __mmdrop(struct mm_struct *mm) 560void __mmdrop(struct mm_struct *mm)
538{ 561{
539 BUG_ON(mm == &init_mm); 562 BUG_ON(mm == &init_mm);
563 free_cpumask_var(mm->cpu_vm_mask_var);
540 mm_free_pgd(mm); 564 mm_free_pgd(mm);
541 destroy_context(mm); 565 destroy_context(mm);
542 mmu_notifier_mm_destroy(mm); 566 mmu_notifier_mm_destroy(mm);
@@ -691,6 +715,9 @@ struct mm_struct *dup_mm(struct task_struct *tsk)
691 if (!mm_init(mm, tsk)) 715 if (!mm_init(mm, tsk))
692 goto fail_nomem; 716 goto fail_nomem;
693 717
718 if (mm_init_cpumask(mm, oldmm))
719 goto fail_nocpumask;
720
694 if (init_new_context(tsk, mm)) 721 if (init_new_context(tsk, mm))
695 goto fail_nocontext; 722 goto fail_nocontext;
696 723
@@ -717,6 +744,9 @@ fail_nomem:
717 return NULL; 744 return NULL;
718 745
719fail_nocontext: 746fail_nocontext:
747 free_cpumask_var(mm->cpu_vm_mask_var);
748
749fail_nocpumask:
720 /* 750 /*
721 * If init_new_context() failed, we cannot use mmput() to free the mm 751 * If init_new_context() failed, we cannot use mmput() to free the mm
722 * because it calls destroy_context() 752 * because it calls destroy_context()