diff options
author | Shirley Ma <mashirle@us.ibm.com> | 2011-07-20 21:23:12 +0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2011-07-21 11:48:27 +0400 |
commit | 9e380825ab3f5176f65306c4ac119fd23634ce03 (patch) | |
tree | 4fdf3f2609da5ee3222103682f3ce10c976353d0 /drivers/vhost/net.c | |
parent | c047e5f3170c2595e66ed67f87cec01afd717212 (diff) | |
download | linux-9e380825ab3f5176f65306c4ac119fd23634ce03.tar.xz |
vhost: handle wrap around in # of bufs math
The meth for calculating the # of outstanding buffers gives
incorrect results when vq->upend_idx wraps around zero.
Fix that.
Signed-off-by: Shirley Ma <xma@us.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
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; |