diff options
-rw-r--r-- | drivers/vhost/net.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 280ee66ae552..8a6dd0d5667c 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -281,7 +281,7 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net, | |||
281 | { | 281 | { |
282 | struct vhost_net_virtqueue *nvq = | 282 | struct vhost_net_virtqueue *nvq = |
283 | container_of(vq, struct vhost_net_virtqueue, vq); | 283 | container_of(vq, struct vhost_net_virtqueue, vq); |
284 | int i; | 284 | int i, add; |
285 | int j = 0; | 285 | int j = 0; |
286 | 286 | ||
287 | for (i = nvq->done_idx; i != nvq->upend_idx; i = (i + 1) % UIO_MAXIOV) { | 287 | for (i = nvq->done_idx; i != nvq->upend_idx; i = (i + 1) % UIO_MAXIOV) { |
@@ -289,14 +289,17 @@ static void vhost_zerocopy_signal_used(struct vhost_net *net, | |||
289 | vhost_net_tx_err(net); | 289 | vhost_net_tx_err(net); |
290 | if (VHOST_DMA_IS_DONE(vq->heads[i].len)) { | 290 | if (VHOST_DMA_IS_DONE(vq->heads[i].len)) { |
291 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; | 291 | vq->heads[i].len = VHOST_DMA_CLEAR_LEN; |
292 | vhost_add_used_and_signal(vq->dev, vq, | ||
293 | vq->heads[i].id, 0); | ||
294 | ++j; | 292 | ++j; |
295 | } else | 293 | } else |
296 | break; | 294 | break; |
297 | } | 295 | } |
298 | if (j) | 296 | while (j) { |
299 | nvq->done_idx = i; | 297 | add = min(UIO_MAXIOV - nvq->done_idx, j); |
298 | vhost_add_used_and_signal_n(vq->dev, vq, | ||
299 | &vq->heads[nvq->done_idx], add); | ||
300 | nvq->done_idx = (nvq->done_idx + add) % UIO_MAXIOV; | ||
301 | j -= add; | ||
302 | } | ||
300 | } | 303 | } |
301 | 304 | ||
302 | static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | 305 | static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) |