diff options
Diffstat (limited to 'drivers/vhost/net.c')
-rw-r--r-- | drivers/vhost/net.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 248b25008d1a..882a51fe7b3c 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c @@ -182,15 +182,21 @@ static void handle_tx(struct vhost_net *net) break; /* Nothing new? Wait for eventfd to tell us they refilled. */ if (head == vq->num) { + int num_pends; + wmem = atomic_read(&sock->sk->sk_wmem_alloc); if (wmem >= sock->sk->sk_sndbuf * 3 / 4) { tx_poll_start(net, sock); set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); break; } - /* If more outstanding DMAs, queue the work */ - if (unlikely(vq->upend_idx - vq->done_idx > - VHOST_MAX_PEND)) { + /* If more outstanding DMAs, queue the work. + * Handle upend_idx wrap around + */ + num_pends = likely(vq->upend_idx >= vq->done_idx) ? + (vq->upend_idx - vq->done_idx) : + (vq->upend_idx + UIO_MAXIOV - vq->done_idx); + if (unlikely(num_pends > VHOST_MAX_PEND)) { tx_poll_start(net, sock); set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); break; |