vhost_net: zerocopy: adding and signalling immediately when fully copied
[firefly-linux-kernel-4.4.55.git] / drivers / vhost / net.c
index 9dab1f51dd43b3bac6e275eac77f995fb245d48d..853db7a08a26bb27e7d7d219262e5974cc312f39 100644 (file)
@@ -166,7 +166,7 @@ static void handle_tx(struct vhost_net *net)
        if (wmem < sock->sk->sk_sndbuf / 2)
                tx_poll_stop(net);
        hdr_size = vq->vhost_hlen;
-       zcopy = vhost_sock_zcopy(sock);
+       zcopy = vq->ubufs;
 
        for (;;) {
                /* Release DMAs done buffers first */
@@ -238,7 +238,7 @@ static void handle_tx(struct vhost_net *net)
 
                                vq->heads[vq->upend_idx].len = len;
                                ubuf->callback = vhost_zerocopy_callback;
-                               ubuf->arg = vq->ubufs;
+                               ubuf->ctx = vq->ubufs;
                                ubuf->desc = vq->upend_idx;
                                msg.msg_control = ubuf;
                                msg.msg_controllen = sizeof(ubuf);
@@ -257,7 +257,8 @@ static void handle_tx(struct vhost_net *net)
                                        UIO_MAXIOV;
                        }
                        vhost_discard_vq_desc(vq, 1);
-                       tx_poll_start(net, sock);
+                       if (err == -EAGAIN || err == -ENOBUFS)
+                               tx_poll_start(net, sock);
                        break;
                }
                if (err != len)
@@ -265,6 +266,8 @@ static void handle_tx(struct vhost_net *net)
                                 " len %d != %zd\n", err, len);
                if (!zcopy)
                        vhost_add_used_and_signal(&net->dev, vq, head, 0);
+               else
+                       vhost_zerocopy_signal_used(vq);
                total_len += len;
                if (unlikely(total_len >= VHOST_NET_WEIGHT)) {
                        vhost_poll_queue(&vq->poll);
@@ -588,7 +591,7 @@ static int vhost_net_release(struct inode *inode, struct file *f)
 
        vhost_net_stop(n, &tx_sock, &rx_sock);
        vhost_net_flush(n);
-       vhost_dev_cleanup(&n->dev);
+       vhost_dev_cleanup(&n->dev, false);
        if (tx_sock)
                fput(tx_sock->file);
        if (rx_sock)