|
@@ -165,12 +165,16 @@ static void tx_poll_stop(struct vhost_net *net)
|
|
|
}
|
|
|
|
|
|
/* Caller must have TX VQ lock */
|
|
|
-static void tx_poll_start(struct vhost_net *net, struct socket *sock)
|
|
|
+static int tx_poll_start(struct vhost_net *net, struct socket *sock)
|
|
|
{
|
|
|
+ int ret;
|
|
|
+
|
|
|
if (unlikely(net->tx_poll_state != VHOST_NET_POLL_STOPPED))
|
|
|
- return;
|
|
|
- vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
|
|
|
- net->tx_poll_state = VHOST_NET_POLL_STARTED;
|
|
|
+ return 0;
|
|
|
+ ret = vhost_poll_start(net->poll + VHOST_NET_VQ_TX, sock->file);
|
|
|
+ if (!ret)
|
|
|
+ net->tx_poll_state = VHOST_NET_POLL_STARTED;
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
/* In case of DMA done not in order in lower device driver for some reason.
|
|
@@ -642,20 +646,23 @@ static void vhost_net_disable_vq(struct vhost_net *n,
|
|
|
vhost_poll_stop(n->poll + VHOST_NET_VQ_RX);
|
|
|
}
|
|
|
|
|
|
-static void vhost_net_enable_vq(struct vhost_net *n,
|
|
|
+static int vhost_net_enable_vq(struct vhost_net *n,
|
|
|
struct vhost_virtqueue *vq)
|
|
|
{
|
|
|
struct socket *sock;
|
|
|
+ int ret;
|
|
|
|
|
|
sock = rcu_dereference_protected(vq->private_data,
|
|
|
lockdep_is_held(&vq->mutex));
|
|
|
if (!sock)
|
|
|
- return;
|
|
|
+ return 0;
|
|
|
if (vq == n->vqs + VHOST_NET_VQ_TX) {
|
|
|
n->tx_poll_state = VHOST_NET_POLL_STOPPED;
|
|
|
- tx_poll_start(n, sock);
|
|
|
+ ret = tx_poll_start(n, sock);
|
|
|
} else
|
|
|
- vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
|
|
|
+ ret = vhost_poll_start(n->poll + VHOST_NET_VQ_RX, sock->file);
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static struct socket *vhost_net_stop_vq(struct vhost_net *n,
|
|
@@ -833,7 +840,9 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
|
|
|
r = vhost_init_used(vq);
|
|
|
if (r)
|
|
|
goto err_used;
|
|
|
- vhost_net_enable_vq(n, vq);
|
|
|
+ r = vhost_net_enable_vq(n, vq);
|
|
|
+ if (r)
|
|
|
+ goto err_used;
|
|
|
|
|
|
oldubufs = vq->ubufs;
|
|
|
vq->ubufs = ubufs;
|