To detect that a sequence number is done, we are doing math on unsigned
integers so the result is unsigned too. Not what was intended for the <=
comparison. The result is user stuck forever in flush call.
Convert to int to fix this.

Further, get rid of ({}) to make code clearer.

Signed-off-by: Michael S. Tsirkin <[email protected]>
---

I've put this on my vhost.git tree.

 drivers/vhost/vhost.c |   18 +++++++++++-------
 1 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 159c77a..522b8fc 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -98,22 +98,26 @@ void vhost_poll_stop(struct vhost_poll *poll)
        remove_wait_queue(poll->wqh, &poll->wait);
 }
 
+static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work,
+                               unsigned seq)
+{
+       int left;
+       spin_lock_irq(&dev->work_lock);
+       left = seq - work->done_seq;
+       spin_unlock_irq(&dev->work_lock);
+       return left <= 0;
+}
+
 static void vhost_work_flush(struct vhost_dev *dev, struct vhost_work *work)
 {
        unsigned seq;
-       int left;
        int flushing;
 
        spin_lock_irq(&dev->work_lock);
        seq = work->queue_seq;
        work->flushing++;
        spin_unlock_irq(&dev->work_lock);
-       wait_event(work->done, ({
-                  spin_lock_irq(&dev->work_lock);
-                  left = seq - work->done_seq <= 0;
-                  spin_unlock_irq(&dev->work_lock);
-                  left;
-       }));
+       wait_event(work->done, vhost_work_seq_done(dev, work, seq));
        spin_lock_irq(&dev->work_lock);
        flushing = --work->flushing;
        spin_unlock_irq(&dev->work_lock);
-- 
1.7.3.2.91.g446ac

_______________________________________________
stable mailing list
[email protected]
http://linux.kernel.org/mailman/listinfo/stable

Reply via email to