Skip to content

Commit 6369fec

Browse files
Toshiaki Makitadavem330
authored andcommitted
vhost_net: Avoid rx vring kicks during busyloop
We may run out of avail rx ring descriptor under heavy load but busypoll did not detect it so busypoll may have exited prematurely. Avoid this by checking rx ring full during busypoll. Signed-off-by: Toshiaki Makita <[email protected]> Acked-by: Jason Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent be294a5 commit 6369fec

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

drivers/vhost/net.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,7 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,
658658
{
659659
struct vhost_net_virtqueue *rnvq = &net->vqs[VHOST_NET_VQ_RX];
660660
struct vhost_net_virtqueue *tnvq = &net->vqs[VHOST_NET_VQ_TX];
661+
struct vhost_virtqueue *rvq = &rnvq->vq;
661662
struct vhost_virtqueue *tvq = &tnvq->vq;
662663
unsigned long uninitialized_var(endtime);
663664
int len = peek_head_len(rnvq, sk);
@@ -677,7 +678,8 @@ static int vhost_net_rx_peek_head_len(struct vhost_net *net, struct sock *sk,
677678
*busyloop_intr = true;
678679
break;
679680
}
680-
if (sk_has_rx_data(sk) ||
681+
if ((sk_has_rx_data(sk) &&
682+
!vhost_vq_avail_empty(&net->dev, rvq)) ||
681683
!vhost_vq_avail_empty(&net->dev, tvq))
682684
break;
683685
cpu_relax();
@@ -827,7 +829,6 @@ static void handle_rx(struct vhost_net *net)
827829

828830
while ((sock_len = vhost_net_rx_peek_head_len(net, sock->sk,
829831
&busyloop_intr))) {
830-
busyloop_intr = false;
831832
sock_len += sock_hlen;
832833
vhost_len = sock_len + vhost_hlen;
833834
headcount = get_rx_bufs(vq, vq->heads + nvq->done_idx,
@@ -838,7 +839,9 @@ static void handle_rx(struct vhost_net *net)
838839
goto out;
839840
/* OK, now we need to know about added descriptors. */
840841
if (!headcount) {
841-
if (unlikely(vhost_enable_notify(&net->dev, vq))) {
842+
if (unlikely(busyloop_intr)) {
843+
vhost_poll_queue(&vq->poll);
844+
} else if (unlikely(vhost_enable_notify(&net->dev, vq))) {
842845
/* They have slipped one in as we were
843846
* doing that: check again. */
844847
vhost_disable_notify(&net->dev, vq);
@@ -848,6 +851,7 @@ static void handle_rx(struct vhost_net *net)
848851
* they refilled. */
849852
goto out;
850853
}
854+
busyloop_intr = false;
851855
if (nvq->rx_ring)
852856
msg.msg_control = vhost_net_buf_consume(&nvq->rxq);
853857
/* On overrun, truncate and discard */

0 commit comments

Comments
 (0)