aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/fork.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/fork.c')
-rw-r--r--kernel/fork.c37
1 files changed, 28 insertions, 9 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 98b450876f93..5447dc7defa9 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -65,6 +65,7 @@
65#include <linux/perf_event.h> 65#include <linux/perf_event.h>
66#include <linux/posix-timers.h> 66#include <linux/posix-timers.h>
67#include <linux/user-return-notifier.h> 67#include <linux/user-return-notifier.h>
68#include <linux/oom.h>
68 69
69#include <asm/pgtable.h> 70#include <asm/pgtable.h>
70#include <asm/pgalloc.h> 71#include <asm/pgalloc.h>
@@ -272,6 +273,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
272 273
273 setup_thread_stack(tsk, orig); 274 setup_thread_stack(tsk, orig);
274 clear_user_return_notifier(tsk); 275 clear_user_return_notifier(tsk);
276 clear_tsk_need_resched(tsk);
275 stackend = end_of_stack(tsk); 277 stackend = end_of_stack(tsk);
276 *stackend = STACK_END_MAGIC; /* for overflow detection */ 278 *stackend = STACK_END_MAGIC; /* for overflow detection */
277 279
@@ -300,7 +302,7 @@ out:
300#ifdef CONFIG_MMU 302#ifdef CONFIG_MMU
301static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm) 303static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
302{ 304{
303 struct vm_area_struct *mpnt, *tmp, **pprev; 305 struct vm_area_struct *mpnt, *tmp, *prev, **pprev;
304 struct rb_node **rb_link, *rb_parent; 306 struct rb_node **rb_link, *rb_parent;
305 int retval; 307 int retval;
306 unsigned long charge; 308 unsigned long charge;
@@ -328,6 +330,7 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
328 if (retval) 330 if (retval)
329 goto out; 331 goto out;
330 332
333 prev = NULL;
331 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) { 334 for (mpnt = oldmm->mmap; mpnt; mpnt = mpnt->vm_next) {
332 struct file *file; 335 struct file *file;
333 336
@@ -355,11 +358,11 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
355 if (IS_ERR(pol)) 358 if (IS_ERR(pol))
356 goto fail_nomem_policy; 359 goto fail_nomem_policy;
357 vma_set_policy(tmp, pol); 360 vma_set_policy(tmp, pol);
361 tmp->vm_mm = mm;
358 if (anon_vma_fork(tmp, mpnt)) 362 if (anon_vma_fork(tmp, mpnt))
359 goto fail_nomem_anon_vma_fork; 363 goto fail_nomem_anon_vma_fork;
360 tmp->vm_flags &= ~VM_LOCKED; 364 tmp->vm_flags &= ~VM_LOCKED;
361 tmp->vm_mm = mm; 365 tmp->vm_next = tmp->vm_prev = NULL;
362 tmp->vm_next = NULL;
363 file = tmp->vm_file; 366 file = tmp->vm_file;
364 if (file) { 367 if (file) {
365 struct inode *inode = file->f_path.dentry->d_inode; 368 struct inode *inode = file->f_path.dentry->d_inode;
@@ -392,6 +395,8 @@ static int dup_mmap(struct mm_struct *mm, struct mm_struct *oldmm)
392 */ 395 */
393 *pprev = tmp; 396 *pprev = tmp;
394 pprev = &tmp->vm_next; 397 pprev = &tmp->vm_next;
398 tmp->vm_prev = prev;
399 prev = tmp;
395 400
396 __vma_link_rb(mm, tmp, rb_link, rb_parent); 401 __vma_link_rb(mm, tmp, rb_link, rb_parent);
397 rb_link = &tmp->vm_rb.rb_right; 402 rb_link = &tmp->vm_rb.rb_right;
@@ -485,6 +490,7 @@ static struct mm_struct * mm_init(struct mm_struct * mm, struct task_struct *p)
485 mm->cached_hole_size = ~0UL; 490 mm->cached_hole_size = ~0UL;
486 mm_init_aio(mm); 491 mm_init_aio(mm);
487 mm_init_owner(mm, p); 492 mm_init_owner(mm, p);
493 atomic_set(&mm->oom_disable_count, 0);
488 494
489 if (likely(!mm_alloc_pgd(mm))) { 495 if (likely(!mm_alloc_pgd(mm))) {
490 mm->def_flags = 0; 496 mm->def_flags = 0;
@@ -738,6 +744,8 @@ good_mm:
738 /* Initializing for Swap token stuff */ 744 /* Initializing for Swap token stuff */
739 mm->token_priority = 0; 745 mm->token_priority = 0;
740 mm->last_interval = 0; 746 mm->last_interval = 0;
747 if (tsk->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
748 atomic_inc(&mm->oom_disable_count);
741 749
742 tsk->mm = mm; 750 tsk->mm = mm;
743 tsk->active_mm = mm; 751 tsk->active_mm = mm;
@@ -752,13 +760,13 @@ static int copy_fs(unsigned long clone_flags, struct task_struct *tsk)
752 struct fs_struct *fs = current->fs; 760 struct fs_struct *fs = current->fs;
753 if (clone_flags & CLONE_FS) { 761 if (clone_flags & CLONE_FS) {
754 /* tsk->fs is already what we want */ 762 /* tsk->fs is already what we want */
755 write_lock(&fs->lock); 763 spin_lock(&fs->lock);
756 if (fs->in_exec) { 764 if (fs->in_exec) {
757 write_unlock(&fs->lock); 765 spin_unlock(&fs->lock);
758 return -EAGAIN; 766 return -EAGAIN;
759 } 767 }
760 fs->users++; 768 fs->users++;
761 write_unlock(&fs->lock); 769 spin_unlock(&fs->lock);
762 return 0; 770 return 0;
763 } 771 }
764 tsk->fs = copy_fs_struct(fs); 772 tsk->fs = copy_fs_struct(fs);
@@ -901,6 +909,8 @@ static int copy_signal(unsigned long clone_flags, struct task_struct *tsk)
901 sig->oom_adj = current->signal->oom_adj; 909 sig->oom_adj = current->signal->oom_adj;
902 sig->oom_score_adj = current->signal->oom_score_adj; 910 sig->oom_score_adj = current->signal->oom_score_adj;
903 911
912 mutex_init(&sig->cred_guard_mutex);
913
904 return 0; 914 return 0;
905} 915}
906 916
@@ -1296,8 +1306,13 @@ bad_fork_cleanup_io:
1296bad_fork_cleanup_namespaces: 1306bad_fork_cleanup_namespaces:
1297 exit_task_namespaces(p); 1307 exit_task_namespaces(p);
1298bad_fork_cleanup_mm: 1308bad_fork_cleanup_mm:
1299 if (p->mm) 1309 if (p->mm) {
1310 task_lock(p);
1311 if (p->signal->oom_score_adj == OOM_SCORE_ADJ_MIN)
1312 atomic_dec(&p->mm->oom_disable_count);
1313 task_unlock(p);
1300 mmput(p->mm); 1314 mmput(p->mm);
1315 }
1301bad_fork_cleanup_signal: 1316bad_fork_cleanup_signal:
1302 if (!(clone_flags & CLONE_THREAD)) 1317 if (!(clone_flags & CLONE_THREAD))
1303 free_signal_struct(p->signal); 1318 free_signal_struct(p->signal);
@@ -1676,13 +1691,13 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1676 1691
1677 if (new_fs) { 1692 if (new_fs) {
1678 fs = current->fs; 1693 fs = current->fs;
1679 write_lock(&fs->lock); 1694 spin_lock(&fs->lock);
1680 current->fs = new_fs; 1695 current->fs = new_fs;
1681 if (--fs->users) 1696 if (--fs->users)
1682 new_fs = NULL; 1697 new_fs = NULL;
1683 else 1698 else
1684 new_fs = fs; 1699 new_fs = fs;
1685 write_unlock(&fs->lock); 1700 spin_unlock(&fs->lock);
1686 } 1701 }
1687 1702
1688 if (new_mm) { 1703 if (new_mm) {
@@ -1690,6 +1705,10 @@ SYSCALL_DEFINE1(unshare, unsigned long, unshare_flags)
1690 active_mm = current->active_mm; 1705 active_mm = current->active_mm;
1691 current->mm = new_mm; 1706 current->mm = new_mm;
1692 current->active_mm = new_mm; 1707 current->active_mm = new_mm;
1708 if (current->signal->oom_score_adj == OOM_SCORE_ADJ_MIN) {
1709 atomic_dec(&mm->oom_disable_count);
1710 atomic_inc(&new_mm->oom_disable_count);
1711 }
1693 activate_mm(active_mm, new_mm); 1712 activate_mm(active_mm, new_mm);
1694 new_mm = mm; 1713 new_mm = mm;
1695 } 1714 }