void futex_q_unlock(struct futex_hash_bucket *hb)
        __releases(&hb->lock)
 {
-       spin_unlock(&hb->lock);
        futex_hb_waiters_dec(hb);
+       spin_unlock(&hb->lock);
 }
 
 void __futex_queue(struct futex_q *q, struct futex_hash_bucket *hb,
 
                        ret = futex_get_value_locked(&curval, uaddr1);
 
                        if (unlikely(ret)) {
-                               double_unlock_hb(hb1, hb2);
                                futex_hb_waiters_dec(hb2);
+                               double_unlock_hb(hb1, hb2);
 
                                ret = get_user(curval, uaddr1);
                                if (ret)
                                 * waiter::requeue_state is correct.
                                 */
                        case -EFAULT:
-                               double_unlock_hb(hb1, hb2);
                                futex_hb_waiters_dec(hb2);
+                               double_unlock_hb(hb1, hb2);
                                ret = fault_in_user_writeable(uaddr2);
                                if (!ret)
                                        goto retry;
                                 *   exit to complete.
                                 * - EAGAIN: The user space value changed.
                                 */
-                               double_unlock_hb(hb1, hb2);
                                futex_hb_waiters_dec(hb2);
+                               double_unlock_hb(hb1, hb2);
                                /*
                                 * Handle the case where the owner is in the middle of
                                 * exiting. Wait for the exit to complete otherwise
                put_pi_state(pi_state);
 
 out_unlock:
-               double_unlock_hb(hb1, hb2);
                futex_hb_waiters_dec(hb2);
+               double_unlock_hb(hb1, hb2);
        }
        wake_up_q(&wake_q);
        return ret ? ret : task_count;