diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/exit.c | 6 | ||||
-rw-r--r-- | kernel/sched.c | 16 |
2 files changed, 10 insertions, 12 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 3d759c98fb11..9dd5f1336da2 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -953,10 +953,8 @@ fastcall NORET_TYPE void do_exit(long code) | |||
953 | if (tsk->splice_pipe) | 953 | if (tsk->splice_pipe) |
954 | __free_pipe_info(tsk->splice_pipe); | 954 | __free_pipe_info(tsk->splice_pipe); |
955 | 955 | ||
956 | /* PF_DEAD causes final put_task_struct after we schedule. */ | ||
957 | preempt_disable(); | 956 | preempt_disable(); |
958 | BUG_ON(tsk->flags & PF_DEAD); | 957 | /* causes final put_task_struct in finish_task_switch(). */ |
959 | tsk->flags |= PF_DEAD; | ||
960 | tsk->state = EXIT_DEAD; | 958 | tsk->state = EXIT_DEAD; |
961 | 959 | ||
962 | schedule(); | 960 | schedule(); |
@@ -972,7 +970,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code) | |||
972 | { | 970 | { |
973 | if (comp) | 971 | if (comp) |
974 | complete(comp); | 972 | complete(comp); |
975 | 973 | ||
976 | do_exit(code); | 974 | do_exit(code); |
977 | } | 975 | } |
978 | 976 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index e1646b044b69..a9405d7cc6ab 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -1755,27 +1755,27 @@ static inline void finish_task_switch(struct rq *rq, struct task_struct *prev) | |||
1755 | __releases(rq->lock) | 1755 | __releases(rq->lock) |
1756 | { | 1756 | { |
1757 | struct mm_struct *mm = rq->prev_mm; | 1757 | struct mm_struct *mm = rq->prev_mm; |
1758 | unsigned long prev_task_flags; | 1758 | long prev_state; |
1759 | 1759 | ||
1760 | rq->prev_mm = NULL; | 1760 | rq->prev_mm = NULL; |
1761 | 1761 | ||
1762 | /* | 1762 | /* |
1763 | * A task struct has one reference for the use as "current". | 1763 | * A task struct has one reference for the use as "current". |
1764 | * If a task dies, then it sets EXIT_ZOMBIE in tsk->exit_state and | 1764 | * If a task dies, then it sets EXIT_DEAD in tsk->state and calls |
1765 | * calls schedule one last time. The schedule call will never return, | 1765 | * schedule one last time. The schedule call will never return, and |
1766 | * and the scheduled task must drop that reference. | 1766 | * the scheduled task must drop that reference. |
1767 | * The test for EXIT_ZOMBIE must occur while the runqueue locks are | 1767 | * The test for EXIT_DEAD must occur while the runqueue locks are |
1768 | * still held, otherwise prev could be scheduled on another cpu, die | 1768 | * still held, otherwise prev could be scheduled on another cpu, die |
1769 | * there before we look at prev->state, and then the reference would | 1769 | * there before we look at prev->state, and then the reference would |
1770 | * be dropped twice. | 1770 | * be dropped twice. |
1771 | * Manfred Spraul <manfred@colorfullife.com> | 1771 | * Manfred Spraul <manfred@colorfullife.com> |
1772 | */ | 1772 | */ |
1773 | prev_task_flags = prev->flags; | 1773 | prev_state = prev->state; |
1774 | finish_arch_switch(prev); | 1774 | finish_arch_switch(prev); |
1775 | finish_lock_switch(rq, prev); | 1775 | finish_lock_switch(rq, prev); |
1776 | if (mm) | 1776 | if (mm) |
1777 | mmdrop(mm); | 1777 | mmdrop(mm); |
1778 | if (unlikely(prev_task_flags & PF_DEAD)) { | 1778 | if (unlikely(prev_state == EXIT_DEAD)) { |
1779 | /* | 1779 | /* |
1780 | * Remove function-return probe instances associated with this | 1780 | * Remove function-return probe instances associated with this |
1781 | * task and put them back on the free list. | 1781 | * task and put them back on the free list. |
@@ -5153,7 +5153,7 @@ static void migrate_dead(unsigned int dead_cpu, struct task_struct *p) | |||
5153 | BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD); | 5153 | BUG_ON(p->exit_state != EXIT_ZOMBIE && p->exit_state != EXIT_DEAD); |
5154 | 5154 | ||
5155 | /* Cannot have done final schedule yet: would have vanished. */ | 5155 | /* Cannot have done final schedule yet: would have vanished. */ |
5156 | BUG_ON(p->flags & PF_DEAD); | 5156 | BUG_ON(p->state == EXIT_DEAD); |
5157 | 5157 | ||
5158 | get_task_struct(p); | 5158 | get_task_struct(p); |
5159 | 5159 | ||