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); |
