aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/exit.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/exit.c')
-rw-r--r--kernel/exit.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/kernel/exit.c b/kernel/exit.c
index 7b71f87f1207..138887881a11 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -644,24 +644,23 @@ retry:
644assign_new_owner: 644assign_new_owner:
645 BUG_ON(c == p); 645 BUG_ON(c == p);
646 get_task_struct(c); 646 get_task_struct(c);
647 read_unlock(&tasklist_lock);
648 down_write(&mm->mmap_sem);
647 /* 649 /*
648 * The task_lock protects c->mm from changing. 650 * The task_lock protects c->mm from changing.
649 * We always want mm->owner->mm == mm 651 * We always want mm->owner->mm == mm
650 */ 652 */
651 task_lock(c); 653 task_lock(c);
652 /*
653 * Delay read_unlock() till we have the task_lock()
654 * to ensure that c does not slip away underneath us
655 */
656 read_unlock(&tasklist_lock);
657 if (c->mm != mm) { 654 if (c->mm != mm) {
658 task_unlock(c); 655 task_unlock(c);
656 up_write(&mm->mmap_sem);
659 put_task_struct(c); 657 put_task_struct(c);
660 goto retry; 658 goto retry;
661 } 659 }
662 cgroup_mm_owner_callbacks(mm->owner, c); 660 cgroup_mm_owner_callbacks(mm->owner, c);
663 mm->owner = c; 661 mm->owner = c;
664 task_unlock(c); 662 task_unlock(c);
663 up_write(&mm->mmap_sem);
665 put_task_struct(c); 664 put_task_struct(c);
666} 665}
667#endif /* CONFIG_MM_OWNER */ 666#endif /* CONFIG_MM_OWNER */