vhost: fix interrupt mitigation with raw sockets
[safe/jmp/linux-2.6] / drivers / vhost / net.c
index 91a324c..a6a88df 100644 (file)
@@ -114,14 +114,18 @@ static void handle_tx(struct vhost_net *net)
                return;
 
        wmem = atomic_read(&sock->sk->sk_wmem_alloc);
-       if (wmem >= sock->sk->sk_sndbuf)
+       if (wmem >= sock->sk->sk_sndbuf) {
+               mutex_lock(&vq->mutex);
+               tx_poll_start(net, sock);
+               mutex_unlock(&vq->mutex);
                return;
+       }
 
        use_mm(net->dev.mm);
        mutex_lock(&vq->mutex);
        vhost_disable_notify(vq);
 
-       if (wmem < sock->sk->sk_sndbuf * 2)
+       if (wmem < sock->sk->sk_sndbuf / 2)
                tx_poll_stop(net);
        hdr_size = vq->hdr_size;
 
@@ -504,12 +508,12 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        /* Verify that ring has been setup correctly. */
        if (!vhost_vq_access_ok(vq)) {
                r = -EFAULT;
-               goto err;
+               goto err_vq;
        }
        sock = get_socket(fd);
        if (IS_ERR(sock)) {
                r = PTR_ERR(sock);
-               goto err;
+               goto err_vq;
        }
 
        /* start polling new socket */
@@ -520,12 +524,14 @@ static long vhost_net_set_backend(struct vhost_net *n, unsigned index, int fd)
        vhost_net_disable_vq(n, vq);
        rcu_assign_pointer(vq->private_data, sock);
        vhost_net_enable_vq(n, vq);
-       mutex_unlock(&vq->mutex);
 done:
        if (oldsock) {
                vhost_net_flush_vq(n, index);
                fput(oldsock->file);
        }
+
+err_vq:
+       mutex_unlock(&vq->mutex);
 err:
        mutex_unlock(&n->dev.mutex);
        return r;