#ifdef CONFIG_FUTEX
 enum {
        FUTEX_STATE_OK,
+       FUTEX_STATE_EXITING,
        FUTEX_STATE_DEAD,
 };
 
        tsk->futex_state = FUTEX_STATE_OK;
 }
 
-/**
- * futex_exit_done - Sets the tasks futex state to FUTEX_STATE_DEAD
- * @tsk:       task to set the state on
- *
- * Set the futex exit state of the task lockless. The futex waiter code
- * observes that state when a task is exiting and loops until the task has
- * actually finished the futex cleanup. The worst case for this is that the
- * waiter runs through the wait loop until the state becomes visible.
- *
- * This has two callers:
- *
- * - futex_mm_release() after the futex exit cleanup has been done
- *
- * - do_exit() from the recursive fault handling path.
- *
- * In case of a recursive fault this is best effort. Either the futex exit
- * code has run already or not. If the OWNER_DIED bit has been set on the
- * futex then the waiter can take it over. If not, the problem is pushed
- * back to user space. If the futex exit code did not run yet, then an
- * already queued waiter might block forever, but there is nothing which
- * can be done about that.
- */
-static inline void futex_exit_done(struct task_struct *tsk)
-{
-       tsk->futex_state = FUTEX_STATE_DEAD;
-}
-
+void futex_exit_recursive(struct task_struct *tsk);
 void futex_exit_release(struct task_struct *tsk);
 void futex_exec_release(struct task_struct *tsk);
 
              u32 __user *uaddr2, u32 val2, u32 val3);
 #else
 static inline void futex_init_task(struct task_struct *tsk) { }
-static inline void futex_exit_done(struct task_struct *tsk) { }
+static inline void futex_exit_recursive(struct task_struct *tsk) { }
 static inline void futex_exit_release(struct task_struct *tsk) { }
 static inline void futex_exec_release(struct task_struct *tsk) { }
 static inline long do_futex(u32 __user *uaddr, int op, u32 val,
 
         */
        if (unlikely(tsk->flags & PF_EXITING)) {
                pr_alert("Fixing recursive fault but reboot is needed!\n");
-               futex_exit_done(tsk);
+               futex_exit_recursive(tsk);
                set_current_state(TASK_UNINTERRUPTIBLE);
                schedule();
        }
 
        exit_signals(tsk);  /* sets PF_EXITING */
-       /*
-        * Ensure that all new tsk->pi_lock acquisitions must observe
-        * PF_EXITING. Serializes against futex.c:attach_to_pi_owner().
-        */
-       smp_mb();
-       /*
-        * Ensure that we must observe the pi_state in exit_mm() ->
-        * mm_release() -> exit_pi_state_list().
-        */
-       raw_spin_lock_irq(&tsk->pi_lock);
-       raw_spin_unlock_irq(&tsk->pi_lock);
 
        if (unlikely(in_atomic())) {
                pr_info("note: %s[%d] exited with preempt_count %d\n",
 
                exit_pi_state_list(tsk);
 }
 
+/**
+ * futex_exit_recursive - Set the tasks futex state to FUTEX_STATE_DEAD
+ * @tsk:       task to set the state on
+ *
+ * Set the futex exit state of the task lockless. The futex waiter code
+ * observes that state when a task is exiting and loops until the task has
+ * actually finished the futex cleanup. The worst case for this is that the
+ * waiter runs through the wait loop until the state becomes visible.
+ *
+ * This is called from the recursive fault handling path in do_exit().
+ *
+ * This is best effort. Either the futex exit code has run already or
+ * not. If the OWNER_DIED bit has been set on the futex then the waiter can
+ * take it over. If not, the problem is pushed back to user space. If the
+ * futex exit code did not run yet, then an already queued waiter might
+ * block forever, but there is nothing which can be done about that.
+ */
+void futex_exit_recursive(struct task_struct *tsk)
+{
+       tsk->futex_state = FUTEX_STATE_DEAD;
+}
+
 void futex_exit_release(struct task_struct *tsk)
 {
+       tsk->futex_state = FUTEX_STATE_EXITING;
+       /*
+        * Ensure that all new tsk->pi_lock acquisitions must observe
+        * FUTEX_STATE_EXITING. Serializes against attach_to_pi_owner().
+        */
+       smp_mb();
+       /*
+        * Ensure that we must observe the pi_state in exit_pi_state_list().
+        */
+       raw_spin_lock_irq(&tsk->pi_lock);
+       raw_spin_unlock_irq(&tsk->pi_lock);
+
        futex_exec_release(tsk);
-       futex_exit_done(tsk);
+
+       tsk->futex_state = FUTEX_STATE_DEAD;
 }
 
 long do_futex(u32 __user *uaddr, int op, u32 val, ktime_t *timeout,