aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/vhost/net.c37
1 files changed, 24 insertions, 13 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 986058a57917..eeaf6739215f 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -105,7 +105,9 @@ struct vhost_net_virtqueue {
105 /* vhost zerocopy support fields below: */ 105 /* vhost zerocopy support fields below: */
106 /* last used idx for outstanding DMA zerocopy buffers */ 106 /* last used idx for outstanding DMA zerocopy buffers */
107 int upend_idx; 107 int upend_idx;
108 /* first used idx for DMA done zerocopy buffers */ 108 /* For TX, first used idx for DMA done zerocopy buffers
109 * For RX, number of batched heads
110 */
109 int done_idx; 111 int done_idx;
110 /* an array of userspace buffers info */ 112 /* an array of userspace buffers info */
111 struct ubuf_info *ubuf_info; 113 struct ubuf_info *ubuf_info;
@@ -626,6 +628,18 @@ static int sk_has_rx_data(struct sock *sk)
626 return skb_queue_empty(&sk->sk_receive_queue); 628 return skb_queue_empty(&sk->sk_receive_queue);
627} 629}
628 630
631static void vhost_rx_signal_used(struct vhost_net_virtqueue *nvq)
632{
633 struct vhost_virtqueue *vq = &nvq->vq;
634 struct vhost_dev *dev = vq->dev;
635
636 if (!nvq->done_idx)
637 return;
638
639 vhost_add_used_and_signal_n(dev, vq, vq->heads, nvq->done_idx);
640 nvq->done_idx = 0;
641}
642
629static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk) 643static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
630{ 644{
631 struct vhost_net_virtqueue *rvq = &net->vqs[VHOST_NET_VQ_RX]; 645 struct vhost_net_virtqueue *rvq = &net->vqs[VHOST_NET_VQ_RX];
@@ -635,6 +649,8 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk)
635 int len = peek_head_len(rvq, sk); 649 int len = peek_head_len(rvq, sk);
636 650
637 if (!len && vq->busyloop_timeout) { 651 if (!len && vq->busyloop_timeout) {
652 /* Flush batched heads first */
653 vhost_rx_signal_used(rvq);
638 /* Both tx vq and rx socket were polled here */ 654 /* Both tx vq and rx socket were polled here */
639 mutex_lock_nested(&vq->mutex, 1); 655 mutex_lock_nested(&vq->mutex, 1);
640 vhost_disable_notify(&net->dev, vq); 656 vhost_disable_notify(&net->dev, vq);
@@ -762,7 +778,7 @@ static void handle_rx(struct vhost_net *net)
762 }; 778 };
763 size_t total_len = 0; 779 size_t total_len = 0;
764 int err, mergeable; 780 int err, mergeable;
765 s16 headcount, nheads = 0; 781 s16 headcount;
766 size_t vhost_hlen, sock_hlen; 782 size_t vhost_hlen, sock_hlen;
767 size_t vhost_len, sock_len; 783 size_t vhost_len, sock_len;
768 struct socket *sock; 784 struct socket *sock;
@@ -790,8 +806,8 @@ static void handle_rx(struct vhost_net *net)
790 while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk))) { 806 while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk))) {
791 sock_len += sock_hlen; 807 sock_len += sock_hlen;
792 vhost_len = sock_len + vhost_hlen; 808 vhost_len = sock_len + vhost_hlen;
793 headcount = get_rx_bufs(vq, vq->heads + nheads, vhost_len, 809 headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
794 &in, vq_log, &log, 810 vhost_len, &in, vq_log, &log,
795 likely(mergeable) ? UIO_MAXIOV : 1); 811 likely(mergeable) ? UIO_MAXIOV : 1);
796 /* On error, stop handling until the next kick. */ 812 /* On error, stop handling until the next kick. */
797 if (unlikely(headcount < 0)) 813 if (unlikely(headcount < 0))
@@ -862,12 +878,9 @@ static void handle_rx(struct vhost_net *net)
862 vhost_discard_vq_desc(vq, headcount); 878 vhost_discard_vq_desc(vq, headcount);
863 goto out; 879 goto out;
864 } 880 }
865 nheads += headcount; 881 nvq->done_idx += headcount;
866 if (nheads > VHOST_RX_BATCH) { 882 if (nvq->done_idx > VHOST_RX_BATCH)
867 vhost_add_used_and_signal_n(&net->dev, vq, vq->heads, 883 vhost_rx_signal_used(nvq);
868 nheads);
869 nheads = 0;
870 }
871 if (unlikely(vq_log)) 884 if (unlikely(vq_log))
872 vhost_log_write(vq, vq_log, log, vhost_len); 885 vhost_log_write(vq, vq_log, log, vhost_len);
873 total_len += vhost_len; 886 total_len += vhost_len;
@@ -878,9 +891,7 @@ static void handle_rx(struct vhost_net *net)
878 } 891 }
879 vhost_net_enable_vq(net, vq); 892 vhost_net_enable_vq(net, vq);
880out: 893out:
881 if (nheads) 894 vhost_rx_signal_used(nvq);
882 vhost_add_used_and_signal_n(&net->dev, vq, vq->heads,
883 nheads);
884 mutex_unlock(&vq->mutex); 895 mutex_unlock(&vq->mutex);
885} 896}
886 897