diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2007-02-20 14:13:30 -0500 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-02-20 14:13:30 -0500 |
commit | 5a84d159061d914c8dd4aa372ac6e9529c2be453 (patch) | |
tree | 9b08af78085334af44414adafe0096276f8fe0ff /kernel/exit.c | |
parent | e80a0e6e7ccdf64575d4384cb4172860422f5b81 (diff) | |
parent | 7d477a04a619e90ee08724e8f2d8803c6bdfcef8 (diff) |
Merge ARM fixes
Diffstat (limited to 'kernel/exit.c')
-rw-r--r-- | kernel/exit.c | 67 |
1 files changed, 34 insertions, 33 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index fec12eb12471..f132349c0325 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -185,21 +185,19 @@ repeat: | |||
185 | * This checks not only the pgrp, but falls back on the pid if no | 185 | * This checks not only the pgrp, but falls back on the pid if no |
186 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly | 186 | * satisfactory pgrp is found. I dunno - gdb doesn't work correctly |
187 | * without this... | 187 | * without this... |
188 | * | ||
189 | * The caller must hold rcu lock or the tasklist lock. | ||
188 | */ | 190 | */ |
189 | int session_of_pgrp(int pgrp) | 191 | struct pid *session_of_pgrp(struct pid *pgrp) |
190 | { | 192 | { |
191 | struct task_struct *p; | 193 | struct task_struct *p; |
192 | int sid = 0; | 194 | struct pid *sid = NULL; |
193 | |||
194 | read_lock(&tasklist_lock); | ||
195 | 195 | ||
196 | p = find_task_by_pid_type(PIDTYPE_PGID, pgrp); | 196 | p = pid_task(pgrp, PIDTYPE_PGID); |
197 | if (p == NULL) | 197 | if (p == NULL) |
198 | p = find_task_by_pid(pgrp); | 198 | p = pid_task(pgrp, PIDTYPE_PID); |
199 | if (p != NULL) | 199 | if (p != NULL) |
200 | sid = process_session(p); | 200 | sid = task_session(p); |
201 | |||
202 | read_unlock(&tasklist_lock); | ||
203 | 201 | ||
204 | return sid; | 202 | return sid; |
205 | } | 203 | } |
@@ -212,53 +210,52 @@ int session_of_pgrp(int pgrp) | |||
212 | * | 210 | * |
213 | * "I ask you, have you ever known what it is to be an orphan?" | 211 | * "I ask you, have you ever known what it is to be an orphan?" |
214 | */ | 212 | */ |
215 | static int will_become_orphaned_pgrp(int pgrp, struct task_struct *ignored_task) | 213 | static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignored_task) |
216 | { | 214 | { |
217 | struct task_struct *p; | 215 | struct task_struct *p; |
218 | int ret = 1; | 216 | int ret = 1; |
219 | 217 | ||
220 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { | 218 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
221 | if (p == ignored_task | 219 | if (p == ignored_task |
222 | || p->exit_state | 220 | || p->exit_state |
223 | || is_init(p->real_parent)) | 221 | || is_init(p->real_parent)) |
224 | continue; | 222 | continue; |
225 | if (process_group(p->real_parent) != pgrp && | 223 | if (task_pgrp(p->real_parent) != pgrp && |
226 | process_session(p->real_parent) == process_session(p)) { | 224 | task_session(p->real_parent) == task_session(p)) { |
227 | ret = 0; | 225 | ret = 0; |
228 | break; | 226 | break; |
229 | } | 227 | } |
230 | } while_each_task_pid(pgrp, PIDTYPE_PGID, p); | 228 | } while_each_pid_task(pgrp, PIDTYPE_PGID, p); |
231 | return ret; /* (sighing) "Often!" */ | 229 | return ret; /* (sighing) "Often!" */ |
232 | } | 230 | } |
233 | 231 | ||
234 | int is_orphaned_pgrp(int pgrp) | 232 | int is_current_pgrp_orphaned(void) |
235 | { | 233 | { |
236 | int retval; | 234 | int retval; |
237 | 235 | ||
238 | read_lock(&tasklist_lock); | 236 | read_lock(&tasklist_lock); |
239 | retval = will_become_orphaned_pgrp(pgrp, NULL); | 237 | retval = will_become_orphaned_pgrp(task_pgrp(current), NULL); |
240 | read_unlock(&tasklist_lock); | 238 | read_unlock(&tasklist_lock); |
241 | 239 | ||
242 | return retval; | 240 | return retval; |
243 | } | 241 | } |
244 | 242 | ||
245 | static int has_stopped_jobs(int pgrp) | 243 | static int has_stopped_jobs(struct pid *pgrp) |
246 | { | 244 | { |
247 | int retval = 0; | 245 | int retval = 0; |
248 | struct task_struct *p; | 246 | struct task_struct *p; |
249 | 247 | ||
250 | do_each_task_pid(pgrp, PIDTYPE_PGID, p) { | 248 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
251 | if (p->state != TASK_STOPPED) | 249 | if (p->state != TASK_STOPPED) |
252 | continue; | 250 | continue; |
253 | retval = 1; | 251 | retval = 1; |
254 | break; | 252 | break; |
255 | } while_each_task_pid(pgrp, PIDTYPE_PGID, p); | 253 | } while_each_pid_task(pgrp, PIDTYPE_PGID, p); |
256 | return retval; | 254 | return retval; |
257 | } | 255 | } |
258 | 256 | ||
259 | /** | 257 | /** |
260 | * reparent_to_init - Reparent the calling kernel thread to the init task | 258 | * reparent_to_init - Reparent the calling kernel thread to the init task of the pid space that the thread belongs to. |
261 | * of the pid space that the thread belongs to. | ||
262 | * | 259 | * |
263 | * If a kernel thread is launched as a result of a system call, or if | 260 | * If a kernel thread is launched as a result of a system call, or if |
264 | * it ever exits, it should generally reparent itself to init so that | 261 | * it ever exits, it should generally reparent itself to init so that |
@@ -431,8 +428,10 @@ static void close_files(struct files_struct * files) | |||
431 | while (set) { | 428 | while (set) { |
432 | if (set & 1) { | 429 | if (set & 1) { |
433 | struct file * file = xchg(&fdt->fd[i], NULL); | 430 | struct file * file = xchg(&fdt->fd[i], NULL); |
434 | if (file) | 431 | if (file) { |
435 | filp_close(file, files); | 432 | filp_close(file, files); |
433 | cond_resched(); | ||
434 | } | ||
436 | } | 435 | } |
437 | i++; | 436 | i++; |
438 | set >>= 1; | 437 | set >>= 1; |
@@ -649,14 +648,14 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced) | |||
649 | * than we are, and it was the only connection | 648 | * than we are, and it was the only connection |
650 | * outside, so the child pgrp is now orphaned. | 649 | * outside, so the child pgrp is now orphaned. |
651 | */ | 650 | */ |
652 | if ((process_group(p) != process_group(father)) && | 651 | if ((task_pgrp(p) != task_pgrp(father)) && |
653 | (process_session(p) == process_session(father))) { | 652 | (task_session(p) == task_session(father))) { |
654 | int pgrp = process_group(p); | 653 | struct pid *pgrp = task_pgrp(p); |
655 | 654 | ||
656 | if (will_become_orphaned_pgrp(pgrp, NULL) && | 655 | if (will_become_orphaned_pgrp(pgrp, NULL) && |
657 | has_stopped_jobs(pgrp)) { | 656 | has_stopped_jobs(pgrp)) { |
658 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp); | 657 | __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); |
659 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp); | 658 | __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp); |
660 | } | 659 | } |
661 | } | 660 | } |
662 | } | 661 | } |
@@ -736,6 +735,7 @@ static void exit_notify(struct task_struct *tsk) | |||
736 | int state; | 735 | int state; |
737 | struct task_struct *t; | 736 | struct task_struct *t; |
738 | struct list_head ptrace_dead, *_p, *_n; | 737 | struct list_head ptrace_dead, *_p, *_n; |
738 | struct pid *pgrp; | ||
739 | 739 | ||
740 | if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT) | 740 | if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT) |
741 | && !thread_group_empty(tsk)) { | 741 | && !thread_group_empty(tsk)) { |
@@ -788,12 +788,13 @@ static void exit_notify(struct task_struct *tsk) | |||
788 | 788 | ||
789 | t = tsk->real_parent; | 789 | t = tsk->real_parent; |
790 | 790 | ||
791 | if ((process_group(t) != process_group(tsk)) && | 791 | pgrp = task_pgrp(tsk); |
792 | (process_session(t) == process_session(tsk)) && | 792 | if ((task_pgrp(t) != pgrp) && |
793 | will_become_orphaned_pgrp(process_group(tsk), tsk) && | 793 | (task_session(t) != task_session(tsk)) && |
794 | has_stopped_jobs(process_group(tsk))) { | 794 | will_become_orphaned_pgrp(pgrp, tsk) && |
795 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk)); | 795 | has_stopped_jobs(pgrp)) { |
796 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk)); | 796 | __kill_pgrp_info(SIGHUP, SEND_SIG_PRIV, pgrp); |
797 | __kill_pgrp_info(SIGCONT, SEND_SIG_PRIV, pgrp); | ||
797 | } | 798 | } |
798 | 799 | ||
799 | /* Let father know we died | 800 | /* Let father know we died |