diff options
-rw-r--r-- | drivers/vhost/net.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c index 93f2d6741f34..28ad7752e0f3 100644 --- a/drivers/vhost/net.c +++ b/drivers/vhost/net.c | |||
@@ -197,8 +197,18 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success) | |||
197 | { | 197 | { |
198 | struct vhost_ubuf_ref *ubufs = ubuf->ctx; | 198 | struct vhost_ubuf_ref *ubufs = ubuf->ctx; |
199 | struct vhost_virtqueue *vq = ubufs->vq; | 199 | struct vhost_virtqueue *vq = ubufs->vq; |
200 | 200 | int cnt = atomic_read(&ubufs->kref.refcount); | |
201 | vhost_poll_queue(&vq->poll); | 201 | |
202 | /* | ||
203 | * Trigger polling thread if guest stopped submitting new buffers: | ||
204 | * in this case, the refcount after decrement will eventually reach 1 | ||
205 | * so here it is 2. | ||
206 | * We also trigger polling periodically after each 16 packets | ||
207 | * (the value 16 here is more or less arbitrary, it's tuned to trigger | ||
208 | * less than 10% of times). | ||
209 | */ | ||
210 | if (cnt <= 2 || !(cnt % 16)) | ||
211 | vhost_poll_queue(&vq->poll); | ||
202 | /* set len to mark this desc buffers done DMA */ | 212 | /* set len to mark this desc buffers done DMA */ |
203 | vq->heads[ubuf->desc].len = success ? | 213 | vq->heads[ubuf->desc].len = success ? |
204 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; | 214 | VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN; |