diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 21 | 
1 files changed, 7 insertions, 14 deletions
| diff --git a/kernel/exit.c b/kernel/exit.c index c9e5a1c14e08..c7740fa3252c 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -642,35 +642,31 @@ retry: | |||
| 642 | /* | 642 | /* | 
| 643 | * We found no owner yet mm_users > 1: this implies that we are | 643 | * We found no owner yet mm_users > 1: this implies that we are | 
| 644 | * most likely racing with swapoff (try_to_unuse()) or /proc or | 644 | * most likely racing with swapoff (try_to_unuse()) or /proc or | 
| 645 | * ptrace or page migration (get_task_mm()). Mark owner as NULL, | 645 | * ptrace or page migration (get_task_mm()). Mark owner as NULL. | 
| 646 | * so that subsystems can understand the callback and take action. | ||
| 647 | */ | 646 | */ | 
| 648 | down_write(&mm->mmap_sem); | ||
| 649 | cgroup_mm_owner_callbacks(mm->owner, NULL); | ||
| 650 | mm->owner = NULL; | 647 | mm->owner = NULL; | 
| 651 | up_write(&mm->mmap_sem); | ||
| 652 | return; | 648 | return; | 
| 653 | 649 | ||
| 654 | assign_new_owner: | 650 | assign_new_owner: | 
| 655 | BUG_ON(c == p); | 651 | BUG_ON(c == p); | 
| 656 | get_task_struct(c); | 652 | get_task_struct(c); | 
| 657 | read_unlock(&tasklist_lock); | ||
| 658 | down_write(&mm->mmap_sem); | ||
| 659 | /* | 653 | /* | 
| 660 | * The task_lock protects c->mm from changing. | 654 | * The task_lock protects c->mm from changing. | 
| 661 | * We always want mm->owner->mm == mm | 655 | * We always want mm->owner->mm == mm | 
| 662 | */ | 656 | */ | 
| 663 | task_lock(c); | 657 | task_lock(c); | 
| 658 | /* | ||
| 659 | * Delay read_unlock() till we have the task_lock() | ||
| 660 | * to ensure that c does not slip away underneath us | ||
| 661 | */ | ||
| 662 | read_unlock(&tasklist_lock); | ||
| 664 | if (c->mm != mm) { | 663 | if (c->mm != mm) { | 
| 665 | task_unlock(c); | 664 | task_unlock(c); | 
| 666 | up_write(&mm->mmap_sem); | ||
| 667 | put_task_struct(c); | 665 | put_task_struct(c); | 
| 668 | goto retry; | 666 | goto retry; | 
| 669 | } | 667 | } | 
| 670 | cgroup_mm_owner_callbacks(mm->owner, c); | ||
| 671 | mm->owner = c; | 668 | mm->owner = c; | 
| 672 | task_unlock(c); | 669 | task_unlock(c); | 
| 673 | up_write(&mm->mmap_sem); | ||
| 674 | put_task_struct(c); | 670 | put_task_struct(c); | 
| 675 | } | 671 | } | 
| 676 | #endif /* CONFIG_MM_OWNER */ | 672 | #endif /* CONFIG_MM_OWNER */ | 
| @@ -1055,10 +1051,7 @@ NORET_TYPE void do_exit(long code) | |||
| 1055 | preempt_count()); | 1051 | preempt_count()); | 
| 1056 | 1052 | ||
| 1057 | acct_update_integrals(tsk); | 1053 | acct_update_integrals(tsk); | 
| 1058 | if (tsk->mm) { | 1054 | |
| 1059 | update_hiwater_rss(tsk->mm); | ||
| 1060 | update_hiwater_vm(tsk->mm); | ||
| 1061 | } | ||
| 1062 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 1055 | group_dead = atomic_dec_and_test(&tsk->signal->live); | 
| 1063 | if (group_dead) { | 1056 | if (group_dead) { | 
| 1064 | hrtimer_cancel(&tsk->signal->real_timer); | 1057 | hrtimer_cancel(&tsk->signal->real_timer); | 
