Merge tag 'char-misc-3.3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh...
[firefly-linux-kernel-4.4.55.git] / kernel / hung_task.c
index 2e48ec0c2e91cf099642f8bf43e90476fb6457a3..c21449f85a2a4061bd9a34fc4844b5a3240850b3 100644 (file)
@@ -119,15 +119,20 @@ static void check_hung_task(struct task_struct *t, unsigned long timeout)
  * For preemptible RCU it is sufficient to call rcu_read_unlock in order
  * to exit the grace period. For classic RCU, a reschedule is required.
  */
-static void rcu_lock_break(struct task_struct *g, struct task_struct *t)
+static bool rcu_lock_break(struct task_struct *g, struct task_struct *t)
 {
+       bool can_cont;
+
        get_task_struct(g);
        get_task_struct(t);
        rcu_read_unlock();
        cond_resched();
        rcu_read_lock();
+       can_cont = pid_alive(g) && pid_alive(t);
        put_task_struct(t);
        put_task_struct(g);
+
+       return can_cont;
 }
 
 /*
@@ -154,9 +159,7 @@ static void check_hung_uninterruptible_tasks(unsigned long timeout)
                        goto unlock;
                if (!--batch_count) {
                        batch_count = HUNG_TASK_BATCHING;
-                       rcu_lock_break(g, t);
-                       /* Exit if t or g was unhashed during refresh. */
-                       if (t->state == TASK_DEAD || g->state == TASK_DEAD)
+                       if (!rcu_lock_break(g, t))
                                goto unlock;
                }
                /* use "==" to skip the TASK_KILLABLE tasks waiting on NFS */