Based on patch by Christoph for virtio_blk speedup: Split virtqueue_kick to be able to do the actual notification outside the lock protecting the virtqueue. This patch was originally done by Stefan Hajnoczi, but I can't find the original one anymore and had to recreated it from memory. Pointers to the original or corrections for the commit message are welcome. Signed-off-by: Rusty Russell <rusty at rustcorp.com.au> diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c --- a/drivers/virtio/virtio_ring.c +++ b/drivers/virtio/virtio_ring.c @@ -237,10 +237,12 @@ add_head: } EXPORT_SYMBOL_GPL(virtqueue_add_buf); -void virtqueue_kick(struct virtqueue *_vq) +bool virtqueue_kick_prepare(struct virtqueue *_vq) { struct vring_virtqueue *vq = to_vvq(_vq); u16 new, old; + bool needs_kick; + START_USE(vq); /* Descriptors and available array need to be set before we expose the * new available array entries. */ @@ -253,13 +255,30 @@ void virtqueue_kick(struct virtqueue *_v /* Need to update avail index before checking if we should notify */ virtio_mb(); - if (vq->event ? - vring_need_event(vring_avail_event(&vq->vring), new, old) : - !(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)) - /* Prod other side to tell it about changes. */ - vq->notify(&vq->vq); + if (vq->event) { + needs_kick = vring_need_event(vring_avail_event(&vq->vring), + new, old); + } else { + needs_kick = (!(vq->vring.used->flags & VRING_USED_F_NO_NOTIFY)); + } + END_USE(vq); + return needs_kick; +} +EXPORT_SYMBOL_GPL(virtqueue_kick_prepare); - END_USE(vq); +void virtqueue_notify(struct virtqueue *_vq) +{ + struct vring_virtqueue *vq = to_vvq(_vq); + + /* Prod other side to tell it about changes. */ + vq->notify(_vq); +} +EXPORT_SYMBOL_GPL(virtqueue_notify); + +void virtqueue_kick(struct virtqueue *vq) +{ + if (virtqueue_kick_prepare(vq)) + virtqueue_notify(vq); } EXPORT_SYMBOL_GPL(virtqueue_kick); diff --git a/include/linux/virtio.h b/include/linux/virtio.h --- a/include/linux/virtio.h +++ b/include/linux/virtio.h @@ -62,6 +62,27 @@ int virtqueue_add_buf(struct virtqueue * void virtqueue_kick(struct virtqueue *vq); /** + * virtqueue_kick_prepare - first half of split virtqueue_kick call. + * @vq: the struct virtqueue + * + * Instead of virtqueue_kick(), you can do: + * if (virtqueue_kick_prepare(vq)) + * virtqueue_notify(vq); + * + * This is sometimes useful because the virtqueue_kick_prepare() needs + * to be serialized, but the actual virtqueue_notify() call does not. + */ +bool virtqueue_kick_prepare(struct virtqueue *vq); + +/** + * virtqueue_notify - second half of split virtqueue_kick call. + * @vq: the struct virtqueue + * + * This does not need to be serialized. + */ +void virtqueue_notify(struct virtqueue *vq); + +/** * virtqueue_get_buf - get the next used buffer * @vq: the struct virtqueue we're talking about. * @len: the length written into the buffer
Christoph Hellwig
2011-Nov-03 07:52 UTC
[PATCH 3 of 5] virtio: support unlocked queue kick
On Thu, Nov 03, 2011 at 06:12:51PM +1030, Rusty Russell wrote:> Based on patch by Christoph for virtio_blk speedup:Please credit it to Stefan - he also sent a pointer to his original version in reply to the previous thread. Also shouldn't virtqueue_kick have kerneldoc comments? I also notices that you documented the functions bother here and in the first patch in the headers. At least historically the kerneldoc tools didn't parse comments at declarations, but only at the function defintions. Did you check these actually get picked up?
On Thu, Nov 3, 2011 at 7:52 AM, Christoph Hellwig <hch at infradead.org> wrote:> On Thu, Nov 03, 2011 at 06:12:51PM +1030, Rusty Russell wrote: >> Based on patch by Christoph for virtio_blk speedup: > > Please credit it to Stefan - he also sent a pointer to his original > version in reply to the previous thread.Thank you Christoph. Here the pointer to the original mailing list thread: "Here is the patch: https://github.com/stefanha/linux/commit/a6d06644e3a58e57a774e77d7dc34c4a5a2e7496 Or as an email if you want to track it down in your inbox: http://www.spinics.net/lists/linux-virtualization/msg14616.html" Stefan