diff options
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 29 |
1 files changed, 4 insertions, 25 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 091a78be3b09..3076f3089919 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -511,7 +511,7 @@ static void exit_mm(struct task_struct *tsk) | |||
511 | mm_update_next_owner(mm); | 511 | mm_update_next_owner(mm); |
512 | mmput(mm); | 512 | mmput(mm); |
513 | if (test_thread_flag(TIF_MEMDIE)) | 513 | if (test_thread_flag(TIF_MEMDIE)) |
514 | exit_oom_victim(tsk); | 514 | exit_oom_victim(); |
515 | } | 515 | } |
516 | 516 | ||
517 | static struct task_struct *find_alive_thread(struct task_struct *p) | 517 | static struct task_struct *find_alive_thread(struct task_struct *p) |
@@ -725,7 +725,7 @@ static void check_stack_usage(void) | |||
725 | static inline void check_stack_usage(void) {} | 725 | static inline void check_stack_usage(void) {} |
726 | #endif | 726 | #endif |
727 | 727 | ||
728 | void do_exit(long code) | 728 | void __noreturn do_exit(long code) |
729 | { | 729 | { |
730 | struct task_struct *tsk = current; | 730 | struct task_struct *tsk = current; |
731 | int group_dead; | 731 | int group_dead; |
@@ -836,6 +836,7 @@ void do_exit(long code) | |||
836 | */ | 836 | */ |
837 | perf_event_exit_task(tsk); | 837 | perf_event_exit_task(tsk); |
838 | 838 | ||
839 | sched_autogroup_exit_task(tsk); | ||
839 | cgroup_exit(tsk); | 840 | cgroup_exit(tsk); |
840 | 841 | ||
841 | /* | 842 | /* |
@@ -882,29 +883,7 @@ void do_exit(long code) | |||
882 | exit_rcu(); | 883 | exit_rcu(); |
883 | TASKS_RCU(__srcu_read_unlock(&tasks_rcu_exit_srcu, tasks_rcu_i)); | 884 | TASKS_RCU(__srcu_read_unlock(&tasks_rcu_exit_srcu, tasks_rcu_i)); |
884 | 885 | ||
885 | /* | 886 | do_task_dead(); |
886 | * The setting of TASK_RUNNING by try_to_wake_up() may be delayed | ||
887 | * when the following two conditions become true. | ||
888 | * - There is race condition of mmap_sem (It is acquired by | ||
889 | * exit_mm()), and | ||
890 | * - SMI occurs before setting TASK_RUNINNG. | ||
891 | * (or hypervisor of virtual machine switches to other guest) | ||
892 | * As a result, we may become TASK_RUNNING after becoming TASK_DEAD | ||
893 | * | ||
894 | * To avoid it, we have to wait for releasing tsk->pi_lock which | ||
895 | * is held by try_to_wake_up() | ||
896 | */ | ||
897 | smp_mb(); | ||
898 | raw_spin_unlock_wait(&tsk->pi_lock); | ||
899 | |||
900 | /* causes final put_task_struct in finish_task_switch(). */ | ||
901 | tsk->state = TASK_DEAD; | ||
902 | tsk->flags |= PF_NOFREEZE; /* tell freezer to ignore us */ | ||
903 | schedule(); | ||
904 | BUG(); | ||
905 | /* Avoid "noreturn function does return". */ | ||
906 | for (;;) | ||
907 | cpu_relax(); /* For when BUG is null */ | ||
908 | } | 887 | } |
909 | EXPORT_SYMBOL_GPL(do_exit); | 888 | EXPORT_SYMBOL_GPL(do_exit); |
910 | 889 | ||