diff options
author | Michael S. Tsirkin <mst@redhat.com> | 2011-01-10 09:03:20 +0100 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2011-01-10 09:03:39 +0100 |
commit | 0174b0c30a9de25dcb0d3049defcfad0c2947a36 (patch) | |
tree | c7d4430ea5f83b52c9074df6770ad6281735bbc3 /drivers/vhost/vhost.c | |
parent | Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/hch/... (diff) | |
download | linux-0174b0c30a9de25dcb0d3049defcfad0c2947a36.tar.xz linux-0174b0c30a9de25dcb0d3049defcfad0c2947a36.zip |
vhost: fix signed/unsigned comparison
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 <mst@redhat.com>
Diffstat (limited to 'drivers/vhost/vhost.c')
-rw-r--r-- | 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 38244f59cdd9..ade0568c07a4 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c @@ -97,22 +97,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); |