diff options
author | Shirley Ma <mashirle@us.ibm.com> | 2011-07-20 13:23:12 -0400 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2011-07-21 03:48:27 -0400 |
commit | 9e380825ab3f5176f65306c4ac119fd23634ce03 (patch) | |
tree | 4fdf3f2609da5ee3222103682f3ce10c976353d0 /drivers/vhost | |
parent | c047e5f3170c2595e66ed67f87cec01afd717212 (diff) |
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')
-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) | |||
182 | break; | 182 | break; |
183 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | 183 | /* Nothing new? Wait for eventfd to tell us they refilled. */ |
184 | if (head == vq->num) { | 184 | if (head == vq->num) { |
185 | int num_pends; | ||
186 | |||
185 | wmem = atomic_read(&sock->sk->sk_wmem_alloc); | 187 | wmem = atomic_read(&sock->sk->sk_wmem_alloc); |
186 | if (wmem >= sock->sk->sk_sndbuf * 3 / 4) { | 188 | if (wmem >= sock->sk->sk_sndbuf * 3 / 4) { |
187 | tx_poll_start(net, sock); | 189 | tx_poll_start(net, sock); |
188 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 190 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); |
189 | break; | 191 | break; |
190 | } | 192 | } |
191 | /* If more outstanding DMAs, queue the work */ | 193 | /* If more outstanding DMAs, queue the work. |
192 | if (unlikely(vq->upend_idx - vq->done_idx > | 194 | * Handle upend_idx wrap around |
193 | VHOST_MAX_PEND)) { | 195 | */ |
196 | num_pends = likely(vq->upend_idx >= vq->done_idx) ? | ||
197 | (vq->upend_idx - vq->done_idx) : | ||
198 | (vq->upend_idx + UIO_MAXIOV - vq->done_idx); | ||
199 | if (unlikely(num_pends > VHOST_MAX_PEND)) { | ||
194 | tx_poll_start(net, sock); | 200 | tx_poll_start(net, sock); |
195 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); | 201 | set_bit(SOCK_ASYNC_NOSPACE, &sock->flags); |
196 | break; | 202 | break; |