diff options
Diffstat (limited to 'drivers/vhost/vhost.c')
| -rw-r--r-- | drivers/vhost/vhost.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c index 34389f75fe65..9759249e6d90 100644 --- a/drivers/vhost/vhost.c +++ b/drivers/vhost/vhost.c | |||
| @@ -77,26 +77,38 @@ void vhost_poll_init(struct vhost_poll *poll, vhost_work_fn_t fn, | |||
| 77 | init_poll_funcptr(&poll->table, vhost_poll_func); | 77 | init_poll_funcptr(&poll->table, vhost_poll_func); |
| 78 | poll->mask = mask; | 78 | poll->mask = mask; |
| 79 | poll->dev = dev; | 79 | poll->dev = dev; |
| 80 | poll->wqh = NULL; | ||
| 80 | 81 | ||
| 81 | vhost_work_init(&poll->work, fn); | 82 | vhost_work_init(&poll->work, fn); |
| 82 | } | 83 | } |
| 83 | 84 | ||
| 84 | /* Start polling a file. We add ourselves to file's wait queue. The caller must | 85 | /* Start polling a file. We add ourselves to file's wait queue. The caller must |
| 85 | * keep a reference to a file until after vhost_poll_stop is called. */ | 86 | * keep a reference to a file until after vhost_poll_stop is called. */ |
| 86 | void vhost_poll_start(struct vhost_poll *poll, struct file *file) | 87 | int vhost_poll_start(struct vhost_poll *poll, struct file *file) |
| 87 | { | 88 | { |
| 88 | unsigned long mask; | 89 | unsigned long mask; |
| 90 | int ret = 0; | ||
| 89 | 91 | ||
| 90 | mask = file->f_op->poll(file, &poll->table); | 92 | mask = file->f_op->poll(file, &poll->table); |
| 91 | if (mask) | 93 | if (mask) |
| 92 | vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); | 94 | vhost_poll_wakeup(&poll->wait, 0, 0, (void *)mask); |
| 95 | if (mask & POLLERR) { | ||
| 96 | if (poll->wqh) | ||
| 97 | remove_wait_queue(poll->wqh, &poll->wait); | ||
| 98 | ret = -EINVAL; | ||
| 99 | } | ||
| 100 | |||
| 101 | return ret; | ||
| 93 | } | 102 | } |
| 94 | 103 | ||
| 95 | /* Stop polling a file. After this function returns, it becomes safe to drop the | 104 | /* Stop polling a file. After this function returns, it becomes safe to drop the |
| 96 | * file reference. You must also flush afterwards. */ | 105 | * file reference. You must also flush afterwards. */ |
| 97 | void vhost_poll_stop(struct vhost_poll *poll) | 106 | void vhost_poll_stop(struct vhost_poll *poll) |
| 98 | { | 107 | { |
| 99 | remove_wait_queue(poll->wqh, &poll->wait); | 108 | if (poll->wqh) { |
| 109 | remove_wait_queue(poll->wqh, &poll->wait); | ||
| 110 | poll->wqh = NULL; | ||
| 111 | } | ||
| 100 | } | 112 | } |
| 101 | 113 | ||
| 102 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, | 114 | static bool vhost_work_seq_done(struct vhost_dev *dev, struct vhost_work *work, |
| @@ -792,7 +804,7 @@ long vhost_vring_ioctl(struct vhost_dev *d, int ioctl, void __user *argp) | |||
| 792 | fput(filep); | 804 | fput(filep); |
| 793 | 805 | ||
| 794 | if (pollstart && vq->handle_kick) | 806 | if (pollstart && vq->handle_kick) |
| 795 | vhost_poll_start(&vq->poll, vq->kick); | 807 | r = vhost_poll_start(&vq->poll, vq->kick); |
| 796 | 808 | ||
| 797 | mutex_unlock(&vq->mutex); | 809 | mutex_unlock(&vq->mutex); |
| 798 | 810 | ||
