aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/vhost
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2013-09-02 04:41:00 -0400
committerDavid S. Miller <davem@davemloft.net>2013-09-03 22:46:57 -0400
commit19c73b3e08d16ee923f3962df4abf6205127896a (patch)
treec41a951349c70e683ab84028facd68d97d9aab9a /drivers/vhost
parentce21a02913dc79205485637b6e0927a4c800c4a4 (diff)
vhost_net: poll vhost queue after marking DMA is done
We used to poll vhost queue before making DMA is done, this is racy if vhost thread were waked up before marking DMA is done which can result the signal to be missed. Fix this by always polling the vhost thread before DMA is done. Signed-off-by: Jason Wang <jasowang@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/vhost')
-rw-r--r--drivers/vhost/net.c9
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 3f89dea297a3..8e9dc554b1ef 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -308,6 +308,11 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
308 struct vhost_virtqueue *vq = ubufs->vq; 308 struct vhost_virtqueue *vq = ubufs->vq;
309 int cnt = atomic_read(&ubufs->kref.refcount); 309 int cnt = atomic_read(&ubufs->kref.refcount);
310 310
311 /* set len to mark this desc buffers done DMA */
312 vq->heads[ubuf->desc].len = success ?
313 VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
314 vhost_net_ubuf_put(ubufs);
315
311 /* 316 /*
312 * Trigger polling thread if guest stopped submitting new buffers: 317 * Trigger polling thread if guest stopped submitting new buffers:
313 * in this case, the refcount after decrement will eventually reach 1 318 * in this case, the refcount after decrement will eventually reach 1
@@ -318,10 +323,6 @@ static void vhost_zerocopy_callback(struct ubuf_info *ubuf, bool success)
318 */ 323 */
319 if (cnt <= 2 || !(cnt % 16)) 324 if (cnt <= 2 || !(cnt % 16))
320 vhost_poll_queue(&vq->poll); 325 vhost_poll_queue(&vq->poll);
321 /* set len to mark this desc buffers done DMA */
322 vq->heads[ubuf->desc].len = success ?
323 VHOST_DMA_DONE_LEN : VHOST_DMA_FAILED_LEN;
324 vhost_net_ubuf_put(ubufs);
325} 326}
326 327
327/* Expects to be always run from workqueue - which acts as 328/* Expects to be always run from workqueue - which acts as