aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2012-11-01 05:16:55 -0400
committerDavid S. Miller <davem@davemloft.net>2012-11-02 21:29:58 -0400
commit24eb21a14896e5c1c7cbca8e9a40405a51745f1d (patch)
treefc754d17a01a4f56272401fd4d73ebe5ee60ede6 /drivers/vhost
parenteaae8132ef6032ffe612e789e8ff145dcf5bc2bb (diff)
vhost-net: reduce vq polling on tx zerocopy
It seems that to avoid deadlocks it is enough to poll vq before we are going to use the last buffer. This is faster than c70aa540c7a9f67add11ad3161096fb95233aa2e. Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/vhost')
-rw-r--r--drivers/vhost/net.c14
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;