kyber: fix hang on domain token wait queue
[linux-block.git] / block / kyber-iosched.c
index f58cab82105ba66e859b08872c6f588512315746..db5bfc6342d342f53d4ec2f6b26b9cc743fb75ef 100644 (file)
@@ -541,9 +541,17 @@ static int kyber_get_domain_token(struct kyber_queue_data *kqd,
 
                /*
                 * Try again in case a token was freed before we got on the wait
-                * queue.
+                * queue. The waker may have already removed the entry from the
+                * wait queue, but list_del_init() is okay with that.
                 */
                nr = __sbitmap_queue_get(domain_tokens);
+               if (nr >= 0) {
+                       unsigned long flags;
+
+                       spin_lock_irqsave(&ws->wait.lock, flags);
+                       list_del_init(&wait->entry);
+                       spin_unlock_irqrestore(&ws->wait.lock, flags);
+               }
        }
        return nr;
 }