diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/virtio/virtio_ring.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c index a5fadc40c448..68b9136847af 100644 --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c | |||
@@ -376,6 +376,33 @@ bool virtqueue_enable_cb(struct virtqueue *_vq) | |||
376 | } | 376 | } |
377 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); | 377 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb); |
378 | 378 | ||
379 | bool virtqueue_enable_cb_delayed(struct virtqueue *_vq) | ||
380 | { | ||
381 | struct vring_virtqueue *vq = to_vvq(_vq); | ||
382 | u16 bufs; | ||
383 | |||
384 | START_USE(vq); | ||
385 | |||
386 | /* We optimistically turn back on interrupts, then check if there was | ||
387 | * more to do. */ | ||
388 | /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to | ||
389 | * either clear the flags bit or point the event index at the next | ||
390 | * entry. Always do both to keep code simple. */ | ||
391 | vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT; | ||
392 | /* TODO: tune this threshold */ | ||
393 | bufs = (u16)(vq->vring.avail->idx - vq->last_used_idx) * 3 / 4; | ||
394 | vring_used_event(&vq->vring) = vq->last_used_idx + bufs; | ||
395 | virtio_mb(); | ||
396 | if (unlikely((u16)(vq->vring.used->idx - vq->last_used_idx) > bufs)) { | ||
397 | END_USE(vq); | ||
398 | return false; | ||
399 | } | ||
400 | |||
401 | END_USE(vq); | ||
402 | return true; | ||
403 | } | ||
404 | EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed); | ||
405 | |||
379 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) | 406 | void *virtqueue_detach_unused_buf(struct virtqueue *_vq) |
380 | { | 407 | { |
381 | struct vring_virtqueue *vq = to_vvq(_vq); | 408 | struct vring_virtqueue *vq = to_vvq(_vq); |