diff options
Diffstat (limited to 'kernel/exit.c')
| -rw-r--r-- | kernel/exit.c | 39 |
1 files changed, 19 insertions, 20 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index d891883420f7..2e4c13cba95a 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -219,7 +219,7 @@ static int will_become_orphaned_pgrp(int pgrp, struct task_struct *ignored_task) | |||
| 219 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { | 219 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { |
| 220 | if (p == ignored_task | 220 | if (p == ignored_task |
| 221 | || p->exit_state | 221 | || p->exit_state |
| 222 | || p->real_parent->pid == 1) | 222 | || is_init(p->real_parent)) |
| 223 | continue; | 223 | continue; |
| 224 | if (process_group(p->real_parent) != pgrp | 224 | if (process_group(p->real_parent) != pgrp |
| 225 | && p->real_parent->signal->session == p->signal->session) { | 225 | && p->real_parent->signal->session == p->signal->session) { |
| @@ -249,17 +249,6 @@ static int has_stopped_jobs(int pgrp) | |||
| 249 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { | 249 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { |
| 250 | if (p->state != TASK_STOPPED) | 250 | if (p->state != TASK_STOPPED) |
| 251 | continue; | 251 | continue; |
| 252 | |||
| 253 | /* If p is stopped by a debugger on a signal that won't | ||
| 254 | stop it, then don't count p as stopped. This isn't | ||
| 255 | perfect but it's a good approximation. */ | ||
| 256 | if (unlikely (p->ptrace) | ||
| 257 | && p->exit_code != SIGSTOP | ||
| 258 | && p->exit_code != SIGTSTP | ||
| 259 | && p->exit_code != SIGTTOU | ||
| 260 | && p->exit_code != SIGTTIN) | ||
| 261 | continue; | ||
| 262 | |||
| 263 | retval = 1; | 252 | retval = 1; |
| 264 | break; | 253 | break; |
| 265 | } while_each_task_pid(pgrp, PIDTYPE_PGID, p); | 254 | } while_each_task_pid(pgrp, PIDTYPE_PGID, p); |
| @@ -292,9 +281,7 @@ static void reparent_to_init(void) | |||
| 292 | /* Set the exit signal to SIGCHLD so we signal init on exit */ | 281 | /* Set the exit signal to SIGCHLD so we signal init on exit */ |
| 293 | current->exit_signal = SIGCHLD; | 282 | current->exit_signal = SIGCHLD; |
| 294 | 283 | ||
| 295 | if ((current->policy == SCHED_NORMAL || | 284 | if (!has_rt_policy(current) && (task_nice(current) < 0)) |
| 296 | current->policy == SCHED_BATCH) | ||
| 297 | && (task_nice(current) < 0)) | ||
| 298 | set_user_nice(current, 0); | 285 | set_user_nice(current, 0); |
| 299 | /* cpus_allowed? */ | 286 | /* cpus_allowed? */ |
| 300 | /* rt_priority? */ | 287 | /* rt_priority? */ |
| @@ -487,6 +474,18 @@ void fastcall put_files_struct(struct files_struct *files) | |||
| 487 | 474 | ||
| 488 | EXPORT_SYMBOL(put_files_struct); | 475 | EXPORT_SYMBOL(put_files_struct); |
| 489 | 476 | ||
| 477 | void reset_files_struct(struct task_struct *tsk, struct files_struct *files) | ||
| 478 | { | ||
| 479 | struct files_struct *old; | ||
| 480 | |||
| 481 | old = tsk->files; | ||
| 482 | task_lock(tsk); | ||
| 483 | tsk->files = files; | ||
| 484 | task_unlock(tsk); | ||
| 485 | put_files_struct(old); | ||
| 486 | } | ||
| 487 | EXPORT_SYMBOL(reset_files_struct); | ||
| 488 | |||
| 490 | static inline void __exit_files(struct task_struct *tsk) | 489 | static inline void __exit_files(struct task_struct *tsk) |
| 491 | { | 490 | { |
| 492 | struct files_struct * files = tsk->files; | 491 | struct files_struct * files = tsk->files; |
| @@ -954,15 +953,15 @@ fastcall NORET_TYPE void do_exit(long code) | |||
| 954 | if (tsk->splice_pipe) | 953 | if (tsk->splice_pipe) |
| 955 | __free_pipe_info(tsk->splice_pipe); | 954 | __free_pipe_info(tsk->splice_pipe); |
| 956 | 955 | ||
| 957 | /* PF_DEAD causes final put_task_struct after we schedule. */ | ||
| 958 | preempt_disable(); | 956 | preempt_disable(); |
| 959 | BUG_ON(tsk->flags & PF_DEAD); | 957 | /* causes final put_task_struct in finish_task_switch(). */ |
| 960 | tsk->flags |= PF_DEAD; | 958 | tsk->state = TASK_DEAD; |
| 961 | 959 | ||
| 962 | schedule(); | 960 | schedule(); |
| 963 | BUG(); | 961 | BUG(); |
| 964 | /* Avoid "noreturn function does return". */ | 962 | /* Avoid "noreturn function does return". */ |
| 965 | for (;;) ; | 963 | for (;;) |
| 964 | cpu_relax(); /* For when BUG is null */ | ||
| 966 | } | 965 | } |
| 967 | 966 | ||
| 968 | EXPORT_SYMBOL_GPL(do_exit); | 967 | EXPORT_SYMBOL_GPL(do_exit); |
| @@ -971,7 +970,7 @@ NORET_TYPE void complete_and_exit(struct completion *comp, long code) | |||
| 971 | { | 970 | { |
| 972 | if (comp) | 971 | if (comp) |
| 973 | complete(comp); | 972 | complete(comp); |
| 974 | 973 | ||
| 975 | do_exit(code); | 974 | do_exit(code); |
| 976 | } | 975 | } |
| 977 | 976 | ||
