aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2018-05-29 02:18:19 -0400
committerDavid S. Miller <davem@davemloft.net>2018-05-30 13:29:03 -0400
commitf5a4941aa6d190e676065e8f4ed35999f52a01c3 (patch)
treec40fee18c8d0dff90a7c1efb37a0af2ee9bf0750
parent6547e387d7f52f2ba681a229de3c13e5b9e01ee1 (diff)
vhost_net: flush batched heads before trying to busy polling
After commit e2b3b35eb989 ("vhost_net: batch used ring update in rx"), we tend to batch updating used heads. But it doesn't flush batched heads before trying to do busy polling, this will cause vhost to wait for guest TX which waits for the used RX. Fixing by flush batched heads before busy loop. 1 byte TCP_RR performance recovers from 13107.83 to 50402.65. Fixes: e2b3b35eb989 ("vhost_net: batch used ring update in rx") Signed-off-by: Jason Wang <jasowang@redhat.com> Acked-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-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