lkml.org 
[lkml]   [2011]   [May]   [4]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH 14/18] virtio: add api for delayed callbacks
    Add an API that tells the other side that callbacks
    should be delayed until a lot of work has been done.
    Implement using the new used_event feature.

    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    ---
    drivers/virtio/virtio_ring.c | 27 +++++++++++++++++++++++++++
    include/linux/virtio.h | 9 +++++++++
    2 files changed, 36 insertions(+), 0 deletions(-)

    diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
    index 262dfe6..3a70d70 100644
    --- a/drivers/virtio/virtio_ring.c
    +++ b/drivers/virtio/virtio_ring.c
    @@ -397,6 +397,33 @@ bool virtqueue_enable_cb(struct virtqueue *_vq)
    }
    EXPORT_SYMBOL_GPL(virtqueue_enable_cb);

    +bool virtqueue_enable_cb_delayed(struct virtqueue *_vq)
    +{
    + struct vring_virtqueue *vq = to_vvq(_vq);
    + int bufs;
    +
    + START_USE(vq);
    +
    + /* We optimistically turn back on interrupts, then check if there was
    + * more to do. */
    + /* Depending on the VIRTIO_RING_F_USED_EVENT_IDX feature, we need to
    + * either clear the flags bit or point the event index at the next
    + * entry. Always do both to keep code simple. */
    + vq->vring.avail->flags &= ~VRING_AVAIL_F_NO_INTERRUPT;
    + /* TODO: tune this threshold */
    + bufs = (vq->vring.avail->idx - vq->last_used_idx) * 3 / 4;
    + vring_used_event(&vq->vring) = vq->last_used_idx + bufs;
    + virtio_mb();
    + if (unlikely(vq->vring.used->idx - vq->last_used_idx > bufs)) {
    + END_USE(vq);
    + return false;
    + }
    +
    + END_USE(vq);
    + return true;
    +}
    +EXPORT_SYMBOL_GPL(virtqueue_enable_cb_delayed);
    +
    void *virtqueue_detach_unused_buf(struct virtqueue *_vq)
    {
    struct vring_virtqueue *vq = to_vvq(_vq);
    diff --git a/include/linux/virtio.h b/include/linux/virtio.h
    index 718336b..5151fd1 100644
    --- a/include/linux/virtio.h
    +++ b/include/linux/virtio.h
    @@ -51,6 +51,13 @@ struct virtqueue {
    * This re-enables callbacks; it returns "false" if there are pending
    * buffers in the queue, to detect a possible race between the driver
    * checking for more work, and enabling callbacks.
    + * virtqueue_enable_cb_delayed: restart callbacks after disable_cb.
    + * vq: the struct virtqueue we're talking about.
    + * This re-enables callbacks but hints to the other side to delay
    + * interrupts until most of the available buffers have been processed;
    + * it returns "false" if there are many pending buffers in the queue,
    + * to detect a possible race between the driver checking for more work,
    + * and enabling callbacks.
    * virtqueue_detach_unused_buf: detach first unused buffer
    * vq: the struct virtqueue we're talking about.
    * Returns NULL or the "data" token handed to add_buf
    @@ -86,6 +93,8 @@ void virtqueue_disable_cb(struct virtqueue *vq);

    bool virtqueue_enable_cb(struct virtqueue *vq);

    +bool virtqueue_enable_cb_delayed(struct virtqueue *vq);
    +
    void *virtqueue_detach_unused_buf(struct virtqueue *vq);

    /**
    --
    1.7.5.53.gc233e


    \
     
     \ /
      Last update: 2011-05-04 22:57    [W:0.022 / U:2.028 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site