Linux Headquarters
[ Register ]
[ About us ] [ Home Page ]

Advertisement
[ Kernel ] [ Documentation ] [ Links ] [ Books ]

Advertisement

Kernel v2.6.24 /kernel/exit.c

Filename:/kernel/exit.c
Lines Added:147
Lines Deleted:130
Also changed in: (Previous) 2.6.24-rc8  2.6.24-rc7  2.6.24-rc6  2.6.24-rc5  2.6.24-rc4  2.6.24-rc3-git7 
(Following) 2.6.24-git10  2.6.24-git11  2.6.24-git12  2.6.24-git13  2.6.24-git14  2.6.24-git15 

Location
[  2.6.24
  [  kernel
     o  exit.c

Patch

diff --git a/kernel/exit.c b/kernel/exit.c
index 993369e..549c055 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -31,7 +31,7 @@
 #include <linux/taskstats_kern.h>
 #include <linux/delayacct.h>
 #include <linux/freezer.h>
-#include <linux/cpuset.h>
+#include <linux/cgroup.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
 #include <linux/posix-timers.h>
@@ -44,7 +44,6 @@
 #include <linux/resource.h>
 #include <linux/blkdev.h>
 #include <linux/task_io_accounting_ops.h>
-#include <linux/freezer.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -93,10 +92,9 @@ static void __exit_signal(struct task_struct *tsk)
        * If there is any task waiting for the group exit
        * then notify it:
        */
-      if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count) {
+      if (sig->group_exit_task && atomic_read(&sig->count) == sig->notify_count)
          wake_up_process(sig->group_exit_task);
-         sig->group_exit_task = NULL;
-      }
+
       if (tsk == sig->curr_target)
          sig->curr_target = next_thread(tsk);
       /*
@@ -111,6 +109,7 @@ static void __exit_signal(struct task_struct *tsk)
        */
       sig->utime = cputime_add(sig->utime, tsk->utime);
       sig->stime = cputime_add(sig->stime, tsk->stime);
+      sig->gtime = cputime_add(sig->gtime, tsk->gtime);
       sig->min_flt += tsk->min_flt;
       sig->maj_flt += tsk->maj_flt;
       sig->nvcsw += tsk->nvcsw;
@@ -149,6 +148,7 @@ void release_task(struct task_struct * p)
    int zap_leader;
 repeat:
    atomic_dec(&p->user->processes);
+   proc_flush_task(p);
    write_lock_irq(&tasklist_lock);
    ptrace_unlink(p);
    BUG_ON(!list_empty(&p->ptrace_list) || !list_empty(&p->ptrace_children));
@@ -176,7 +176,6 @@ repeat:
    }
 
    write_unlock_irq(&tasklist_lock);
-   proc_flush_task(p);
    release_thread(p);
    call_rcu(&p->rcu, delayed_put_task_struct);
 
@@ -222,7 +221,7 @@ static int will_become_orphaned_pgrp(struct pid *pgrp, struct task_struct *ignor
    do_each_pid_task(pgrp, PIDTYPE_PGID, p) {
       if (p == ignored_task
             || p->exit_state
-            || is_init(p->real_parent))
+            || is_global_init(p->real_parent))
          continue;
       if (task_pgrp(p->real_parent) != pgrp &&
           task_session(p->real_parent) == task_session(p)) {
@@ -300,14 +299,14 @@ void __set_special_pids(pid_t session, pid_t pgrp)
 {
    struct task_struct *curr = current->group_leader;
 
-   if (process_session(curr) != session) {
+   if (task_session_nr(curr) != session) {
       detach_pid(curr, PIDTYPE_SID);
-      set_signal_session(curr->signal, session);
+      set_task_session(curr, session);
       attach_pid(curr, PIDTYPE_SID, find_pid(session));
    }
-   if (process_group(curr) != pgrp) {
+   if (task_pgrp_nr(curr) != pgrp) {
       detach_pid(curr, PIDTYPE_PGID);
-      curr->signal->pgrp = pgrp;
+      set_task_pgrp(curr, pgrp);
       attach_pid(curr, PIDTYPE_PGID, find_pid(pgrp));
    }
 }
@@ -401,11 +400,12 @@ void daemonize(const char *name, ...)
    current->fs = fs;
    atomic_inc(&fs->count);
 
-   exit_task_namespaces(current);
-   current->nsproxy = init_task.nsproxy;
-   get_task_namespaces(current);
+   if (current->nsproxy != init_task.nsproxy) {
+      get_nsproxy(init_task.nsproxy);
+      switch_task_namespaces(current, init_task.nsproxy);
+   }
 
-    exit_files(current);
+   exit_files(current);
    current->files = init_task.files;
    atomic_inc(¤t->files->count);
 
@@ -493,7 +493,7 @@ void reset_files_struct(struct task_struct *tsk, struct files_struct *files)
 }
 EXPORT_SYMBOL(reset_files_struct);
 
-static inline void __exit_files(struct task_struct *tsk)
+static void __exit_files(struct task_struct *tsk)
 {
    struct files_struct * files = tsk->files;
 
@@ -510,7 +510,7 @@ void exit_files(struct task_struct *tsk)
    __exit_files(tsk);
 }
 
-static inline void __put_fs_struct(struct fs_struct *fs)
+static void __put_fs_struct(struct fs_struct *fs)
 {
    /* No need to hold fs->lock if we are killing it */
    if (atomic_dec_and_test(&fs->count)) {
@@ -531,7 +531,7 @@ void put_fs_struct(struct fs_struct *fs)
    __put_fs_struct(fs);
 }
 
-static inline void __exit_fs(struct task_struct *tsk)
+static void __exit_fs(struct task_struct *tsk)
 {
    struct fs_struct * fs = tsk->fs;
 
@@ -592,17 +592,6 @@ static void exit_mm(struct task_struct * tsk)
    mmput(mm);
 }
 
-static inline void
-choose_new_parent(struct task_struct *p, struct task_struct *reaper)
-{
-   /*
-    * Make sure we're not reparenting to ourselves and that
-    * the parent is not a zombie.
-    */
-   BUG_ON(p == reaper || reaper->exit_state);
-   p->real_parent = reaper;
-}
-
 static void
 reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
 {
@@ -677,19 +666,22 @@ reparent_thread(struct task_struct *p, struct task_struct *father, int traced)
  * the child reaper process (ie "init") in our pid
  * space.
  */
-static void
-forget_original_parent(struct task_struct *father, struct list_head *to_release)
+static void forget_original_parent(struct task_struct *father)
 {
-   struct task_struct *p, *reaper = father;
-   struct list_head *_p, *_n;
+   struct task_struct *p, *n, *reaper = father;
+   struct list_head ptrace_dead;
+
+   INIT_LIST_HEAD(&ptrace_dead);
+
+   write_lock_irq(&tasklist_lock);
 
    do {
       reaper = next_thread(reaper);
       if (reaper == father) {
-         reaper = child_reaper(father);
+         reaper = task_child_reaper(father);
          break;
       }
-   } while (reaper->exit_state);
+   } while (reaper->flags & PF_EXITING);
 
    /*
     * There are only two places where our children can be:
@@ -699,9 +691,8 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
     *
     * Search them and reparent children.
     */
-   list_for_each_safe(_p, _n, &father->children) {
+   list_for_each_entry_safe(p, n, &father->children, sibling) {
       int ptrace;
-      p = list_entry(_p, struct task_struct, sibling);
 
       ptrace = p->ptrace;
 
@@ -710,7 +701,7 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
 
       if (father == p->real_parent) {
          /* reparent with a reaper, real father it's us */
-         choose_new_parent(p, reaper);
+         p->real_parent = reaper;
          reparent_thread(p, father, 0);
       } else {
          /* reparent ptraced task to its real parent */
@@ -727,13 +718,23 @@ forget_original_parent(struct task_struct *father, struct list_head *to_release)
        * while it was being traced by us, to be able to see it in wait4.
        */
       if (unlikely(ptrace && p->exit_state == EXIT_ZOMBIE && p->exit_signal == -1))
-         list_add(&p->ptrace_list, to_release);
+         list_add(&p->ptrace_list, &ptrace_dead);
    }
-   list_for_each_safe(_p, _n, &father->ptrace_children) {
-      p = list_entry(_p, struct task_struct, ptrace_list);
-      choose_new_parent(p, reaper);
+
+   list_for_each_entry_safe(p, n, &father->ptrace_children, ptrace_list) {
+      p->real_parent = reaper;
       reparent_thread(p, father, 1);
    }
+
+   write_unlock_irq(&tasklist_lock);
+   BUG_ON(!list_empty(&father->children));
+   BUG_ON(!list_empty(&father->ptrace_children));
+
+   list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_list) {
+      list_del_init(&p->ptrace_list);
+      release_task(p);
+   }
+
 }
 
 /*
@@ -744,7 +745,6 @@ static void exit_notify(struct task_struct *tsk)
 {
    int state;
    struct task_struct *t;
-   struct list_head ptrace_dead, *_p, *_n;
    struct pid *pgrp;
 
    if (signal_pending(tsk) && !(tsk->signal->flags & SIGNAL_GROUP_EXIT)
@@ -758,17 +758,13 @@ static void exit_notify(struct task_struct *tsk)
        * Now we'll wake all the threads in the group just to make
        * sure someone gets all the pending signals.
        */
-      read_lock(&tasklist_lock);
       spin_lock_irq(&tsk->sighand->siglock);
       for (t = next_thread(tsk); t != tsk; t = next_thread(t))
          if (!signal_pending(t) && !(t->flags & PF_EXITING))
             recalc_sigpending_and_wake(t);
       spin_unlock_irq(&tsk->sighand->siglock);
-      read_unlock(&tasklist_lock);
    }
 
-   write_lock_irq(&tasklist_lock);
-
    /*
     * This does two things:
     *
@@ -777,12 +773,10 @@ static void exit_notify(struct task_struct *tsk)
     *   as a result of our exiting, and if they have any stopped
     *   jobs, send them a SIGHUP and then a SIGCONT.  (POSIX 3.2.2.2)
     */
+   forget_original_parent(tsk);
+   exit_task_namespaces(tsk);
 
-   INIT_LIST_HEAD(&ptrace_dead);
-   forget_original_parent(tsk, &ptrace_dead);
-   BUG_ON(!list_empty(&tsk->children));
-   BUG_ON(!list_empty(&tsk->ptrace_children));
-
+   write_lock_irq(&tasklist_lock);
    /*
     * Check to see if any process groups have become orphaned
     * as a result of our exiting, and if they have any stopped
@@ -792,9 +786,8 @@ static void exit_notify(struct task_struct *tsk)
     * and we were the only connection outside, so our pgrp
     * is about to become orphaned.
     */
-    
    t = tsk->real_parent;
-   
+
    pgrp = task_pgrp(tsk);
    if ((task_pgrp(t) != pgrp) &&
        (task_session(t) == task_session(tsk)) &&
@@ -807,7 +800,7 @@ static void exit_notify(struct task_struct *tsk)
    /* Let father know we died
     *
     * Thread signals are configurable, but you aren't going to use
-    * that to send signals to arbitary processes. 
+    * that to send signals to arbitary processes.
     * That stops right now.
     *
     * If the parent exec id doesn't match the exec id we saved
@@ -841,13 +834,12 @@ static void exit_notify(struct task_struct *tsk)
       state = EXIT_DEAD;
    tsk->exit_state = state;
 
-   write_unlock_irq(&tasklist_lock);
+   if (thread_group_leader(tsk) &&
+       tsk->signal->notify_count < 0 &&
+       tsk->signal->group_exit_task)
+      wake_up_process(tsk->signal->group_exit_task);
 
-   list_for_each_safe(_p, _n, &ptrace_dead) {
-      list_del_init(_p);
-      t = list_entry(_p, struct task_struct, ptrace_list);
-      release_task(t);
-   }
+   write_unlock_irq(&tasklist_lock);
 
    /* If the process is dead, release it - nobody will wait for it */
    if (state == EXIT_DEAD)
@@ -882,6 +874,39 @@ static void check_stack_usage(void)
 static inline void check_stack_usage(void) {}
 #endif
 
+static inline void exit_child_reaper(struct task_struct *tsk)
+{
+   if (likely(tsk->group_leader != task_child_reaper(tsk)))
+      return;
+
+   if (tsk->nsproxy->pid_ns == &init_pid_ns)
+      panic("Attempted to kill init!");
+
+   /*
+    * @tsk is the last thread in the 'cgroup-init' and is exiting.
+    * Terminate all remaining processes in the namespace and reap them
+    * before exiting @tsk.
+    *
+    * Note that @tsk (last thread of cgroup-init) may not necessarily
+    * be the child-reaper (i.e main thread of cgroup-init) of the
+    * namespace i.e the child_reaper may have already exited.
+    *
+    * Even after a child_reaper exits, we let it inherit orphaned children,
+    * because, pid_ns->child_reaper remains valid as long as there is
+    * at least one living sub-thread in the cgroup init.
+
+    * This living sub-thread of the cgroup-init will be notified when
+    * a child inherited by the 'child-reaper' exits (do_notify_parent()
+    * uses __group_send_sig_info()). Further, when reaping child processes,
+    * do_wait() iterates over children of all living sub threads.
+
+    * i.e even though 'child_reaper' thread is listed as the parent of the
+    * orphaned children, any living sub-thread in the cgroup-init can
+    * perform the role of the child_reaper.
+    */
+   zap_pid_ns_processes(tsk->nsproxy->pid_ns);
+}
+
 fastcall NORET_TYPE void do_exit(long code)
 {
    struct task_struct *tsk = current;
@@ -895,13 +920,6 @@ fastcall NORET_TYPE void do_exit(long code)
       panic("Aiee, killing interrupt handler!");
    if (unlikely(!tsk->pid))
       panic("Attempted to kill the idle task!");
-   if (unlikely(tsk == child_reaper(tsk))) {
-      if (tsk->nsproxy->pid_ns != &init_pid_ns)
-         tsk->nsproxy->pid_ns->child_reaper = init_pid_ns.child_reaper;
-      else
-         panic("Attempted to kill init!");
-   }
-
 
    if (unlikely(current->ptrace & PT_TRACE_EXIT)) {
       current->ptrace_message = code;
@@ -931,17 +949,17 @@ fastcall NORET_TYPE void do_exit(long code)
       schedule();
    }
 
+   tsk->flags |= PF_EXITING;
    /*
     * tsk->flags are checked in the futex code to protect against
     * an exiting task cleaning up the robust pi futexes.
     */
-   spin_lock_irq(&tsk->pi_lock);
-   tsk->flags |= PF_EXITING;
-   spin_unlock_irq(&tsk->pi_lock);
+   smp_mb();
+   spin_unlock_wait(&tsk->pi_lock);
 
    if (unlikely(in_atomic()))
       printk(KERN_INFO "note: %s[%d] exited with preempt_count %d\n",
-            current->comm, current->pid,
+            current->comm, task_pid_nr(current),
             preempt_count());
 
    acct_update_integrals(tsk);
@@ -951,16 +969,19 @@ fastcall NORET_TYPE void do_exit(long code)
    }
    group_dead = atomic_dec_and_test(&tsk->signal->live);
    if (group_dead) {
+      exit_child_reaper(tsk);
       hrtimer_cancel(&tsk->signal->real_timer);
       exit_itimers(tsk->signal);
    }
    acct_collect(code, group_dead);
+#ifdef CONFIG_FUTEX
    if (unlikely(tsk->robust_list))
       exit_robust_list(tsk);
-#if defined(CONFIG_FUTEX) && defined(CONFIG_COMPAT)
+#ifdef CONFIG_COMPAT
    if (unlikely(tsk->compat_robust_list))
       compat_exit_robust_list(tsk);
 #endif
+#endif
    if (group_dead)
       tty_audit_exit();
    if (unlikely(tsk->audit_context))
@@ -978,7 +999,7 @@ fastcall NORET_TYPE void do_exit(long code)
    __exit_fs(tsk);
    check_stack_usage();
    exit_thread();
-   cpuset_exit(tsk);
+   cgroup_exit(tsk, 1);
    exit_keys(tsk);
 
    if (group_dead && tsk->signal->leader)
@@ -989,12 +1010,12 @@ fastcall NORET_TYPE void do_exit(long code)
       module_put(tsk->binfmt->module);
 
    proc_exit_connector(tsk);
-   exit_task_namespaces(tsk);
    exit_notify(tsk);
 #ifdef CONFIG_NUMA
    mpol_free(tsk->mempolicy);
    tsk->mempolicy = NULL;
 #endif
+#ifdef CONFIG_FUTEX
    /*
     * This must happen late, after the PID is not
     * hashed anymore:
@@ -1003,6 +1024,7 @@ fastcall NORET_TYPE void do_exit(long code)
       exit_pi_state_list(tsk);
    if (unlikely(current->pi_state_cache))
       kfree(current->pi_state_cache);
+#endif
    /*
     * Make sure we are holding no locks:
     */
@@ -1090,15 +1112,17 @@ asmlinkage void sys_exit_group(int error_code)
 static int eligible_child(pid_t pid, int options, struct task_struct *p)
 {
    int err;
+   struct pid_namespace *ns;
 
+   ns = current->nsproxy->pid_ns;
    if (pid > 0) {
-      if (p->pid != pid)
+      if (task_pid_nr_ns(p, ns) != pid)
          return 0;
    } else if (!pid) {
-      if (process_group(p) != process_group(current))
+      if (task_pgrp_nr_ns(p, ns) != task_pgrp_vnr(current))
          return 0;
    } else if (pid != -1) {
-      if (process_group(p) != -pid)
+      if (task_pgrp_nr_ns(p, ns) != -pid)
          return 0;
    }
 
@@ -1167,11 +1191,13 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
              int __user *stat_addr, struct rusage __user *ru)
 {
    unsigned long state;
-   int retval;
-   int status;
+   int retval, status, traced;
+   struct pid_namespace *ns;
+
+   ns = current->nsproxy->pid_ns;
 
    if (unlikely(noreap)) {
-      pid_t pid = p->pid;
+      pid_t pid = task_pid_nr_ns(p, ns);
       uid_t uid = p->uid;
       int exit_code = p->exit_code;
       int why, status;
@@ -1202,15 +1228,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
       BUG_ON(state != EXIT_DEAD);
       return 0;
    }
-   if (unlikely(p->exit_signal == -1 && p->ptrace == 0)) {
-      /*
-       * This can only happen in a race with a ptraced thread
-       * dying on another processor.
-       */
-      return 0;
-   }
 
-   if (likely(p->real_parent == p->parent) && likely(p->signal)) {
+   /* traced means p->ptrace, but not vice versa */
+   traced = (p->real_parent != p->parent);
+
+   if (likely(!traced)) {
       struct signal_struct *psig;
       struct signal_struct *sig;
 
@@ -1242,6 +1264,11 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
          cputime_add(p->stime,
          cputime_add(sig->stime,
                 sig->cstime)));
+      psig->cgtime =
+         cputime_add(psig->cgtime,
+         cputime_add(p->gtime,
+         cputime_add(sig->gtime,
+                sig->cgtime)));
       psig->cmin_flt +=
          p->min_flt + sig->min_flt + sig->cmin_flt;
       psig->cmaj_flt +=
@@ -1289,38 +1316,33 @@ static int wait_task_zombie(struct task_struct *p, int noreap,
          retval = put_user(status, &infop->si_status);
    }
    if (!retval && infop)
-      retval = put_user(p->pid, &infop->si_pid);
+      retval = put_user(task_pid_nr_ns(p, ns), &infop->si_pid);
    if (!retval && infop)
       retval = put_user(p->uid, &infop->si_uid);
-   if (retval) {
-      // TODO: is this safe?
-      p->exit_state = EXIT_ZOMBIE;
-      return retval;
-   }
-   retval = p->pid;
-   if (p->real_parent != p->parent) {
+   if (!retval)
+      retval = task_pid_nr_ns(p, ns);
+
+   if (traced) {
       write_lock_irq(&tasklist_lock);
-      /* Double-check with lock held.  */
-      if (p->real_parent != p->parent) {
-         __ptrace_unlink(p);
-         // TODO: is this safe?
-         p->exit_state = EXIT_ZOMBIE;
-         /*
-          * If this is not a detached task, notify the parent.
-          * If it's still not detached after that, don't release
-          * it now.
-          */
+      /* We dropped tasklist, ptracer could die and untrace */
+      ptrace_unlink(p);
+      /*
+       * If this is not a detached task, notify the parent.
+       * If it's still not detached after that, don't release
+       * it now.
+       */
+      if (p->exit_signal != -1) {
+         do_notify_parent(p, p->exit_signal);
          if (p->exit_signal != -1) {
-            do_notify_parent(p, p->exit_signal);
-            if (p->exit_signal != -1)
-               p = NULL;
+            p->exit_state = EXIT_ZOMBIE;
+            p = NULL;
          }
       }
       write_unlock_irq(&tasklist_lock);
    }
    if (p != NULL)
       release_task(p);
-   BUG_ON(!retval);
+
    return retval;
 }
 
@@ -1335,11 +1357,12 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
               int __user *stat_addr, struct rusage __user *ru)
 {
    int retval, exit_code;
+   pid_t pid;
 
    if (!p->exit_code)
       return 0;
    if (delayed_group_leader && !(p->ptrace & PT_PTRACED) &&
-       p->signal && p->signal->group_stop_count > 0)
+       p->signal->group_stop_count > 0)
       /*
        * A group stop is in progress and this is the group leader.
        * We won't report until all threads have stopped.
@@ -1353,20 +1376,19 @@ static int wait_task_stopped(struct task_struct *p, int delayed_group_leader,
     * keep holding onto the tasklist_lock while we call getrusage and
     * possibly take page faults for user memory.
     */
+   pid = task_pid_nr_ns(p, current->nsproxy->pid_ns);
    get_task_struct(p);
    read_unlock(&tasklist_lock);
 
    if (unlikely(noreap)) {
-      pid_t pid = p->pid;
       uid_t uid = p->uid;
       int why = (p->ptrace & PT_PTRACED) ? CLD_TRAPPED : CLD_STOPPED;
 
       exit_code = p->exit_code;
-      if (unlikely(!exit_code) ||
-          unlikely(p->state & TASK_TRACED))
+      if (unlikely(!exit_code) || unlikely(p->exit_state))
          goto bail_ref;
       return wait_noreap_copyout(p, pid, uid,
-                  why, (exit_code << 8) | 0x7f,
+                  why, exit_code,
                   infop, ru);
    }
 
@@ -1428,11 +1450,11 @@ bail_ref:
    if (!retval && infop)
       retval = put_user(exit_code, &infop->si_status);
    if (!retval && infop)
-      retval = put_user(p->pid, &infop->si_pid);
+      retval = put_user(pid, &infop->si_pid);
    if (!retval && infop)
       retval = put_user(p->uid, &infop->si_uid);
    if (!retval)
-      retval = p->pid;
+      retval = pid;
    put_task_struct(p);
 
    BUG_ON(!retval);
@@ -1452,9 +1474,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
    int retval;
    pid_t pid;
    uid_t uid;
-
-   if (unlikely(!p->signal))
-      return 0;
+   struct pid_namespace *ns;
 
    if (!(p->signal->flags & SIGNAL_STOP_CONTINUED))
       return 0;
@@ -1469,7 +1489,8 @@ static int wait_task_continued(struct task_struct *p, int noreap,
       p->signal->flags &= ~SIGNAL_STOP_CONTINUED;
    spin_unlock_irq(&p->sighand->siglock);
 
-   pid = p->pid;
+   ns = current->nsproxy->pid_ns;
+   pid = task_pid_nr_ns(p, ns);
    uid = p->uid;
    get_task_struct(p);
    read_unlock(&tasklist_lock);
@@ -1480,7 +1501,7 @@ static int wait_task_continued(struct task_struct *p, int noreap,
       if (!retval && stat_addr)
          retval = put_user(0xffff, stat_addr);
       if (!retval)
-         retval = p->pid;
+         retval = task_pid_nr_ns(p, ns);
    } else {
       retval = wait_noreap_copyout(p, pid, uid,
                     CLD_CONTINUED, SIGCONT,
@@ -1529,12 +1550,9 @@ repeat:
    tsk = current;
    do {
       struct task_struct *p;
-      struct list_head *_p;
       int ret;
 
-      list_for_each(_p,&tsk->children) {
-         p = list_entry(_p, struct task_struct, sibling);
-
+      list_for_each_entry(p, &tsk->children, sibling) {
          ret = eligible_child(pid, options, p);
          if (!ret)
             continue;
@@ -1616,9 +1634,8 @@ check_continued:
          }
       }
       if (!flag) {
-         list_for_each(_p, &tsk->ptrace_children) {
-            p = list_entry(_p, struct task_struct,
-                  ptrace_list);
+         list_for_each_entry(p, &tsk->ptrace_children,
+                   ptrace_list) {
             if (!eligible_child(pid, options, p))
                continue;
             flag = 1;


Comments: webmaster (at) linuxhq.com.
Advertising: banners (at) linuxhq.com.
Compilation ©1998-2008 Linux Headquarters, Inc.