All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jason Wang <jasowang@redhat.com>
To: wexu@redhat.com, mst@redhat.com, tiwei.bie@intel.com,
	jfreimann@redhat.com, qemu-devel@nongnu.org
Subject: Re: [Qemu-devel] [PATCH 3/8] virtio: add empty check for packed ring
Date: Tue, 10 Apr 2018 15:23:03 +0800	[thread overview]
Message-ID: <6a78b53a-0830-74de-5447-63ecab67e5ed@redhat.com> (raw)
In-Reply-To: <1522846444-31725-4-git-send-email-wexu@redhat.com>



On 2018年04月04日 20:53, wexu@redhat.com wrote:
> From: Wei Xu <wexu@redhat.com>
>
> helper for ring empty check.

And descriptor read.

>
> Signed-off-by: Wei Xu <wexu@redhat.com>
> ---
>   hw/virtio/virtio.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++---
>   1 file changed, 59 insertions(+), 3 deletions(-)
>
> diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
> index 73a35a4..478df3d 100644
> --- a/hw/virtio/virtio.c
> +++ b/hw/virtio/virtio.c
> @@ -24,6 +24,9 @@
>   #include "hw/virtio/virtio-access.h"
>   #include "sysemu/dma.h"
>   
> +#define AVAIL_DESC_PACKED(b) ((b) << 7)
> +#define USED_DESC_PACKED(b)  ((b) << 15)

Can we pass value other than 1 to this macro?

> +
>   /*
>    * The alignment to use between consumer and producer parts of vring.
>    * x86 pagesize again. This is the default, used by transports like PCI
> @@ -446,10 +449,27 @@ int virtio_queue_ready(VirtQueue *vq)
>       return vq->vring.avail != 0;
>   }
>   
> +static void vring_desc_read_packed(VirtIODevice *vdev, VRingDescPacked *desc,
> +                            MemoryRegionCache *cache, int i)
> +{
> +    address_space_read_cached(cache, i * sizeof(VRingDescPacked),
> +                              desc, sizeof(VRingDescPacked));
> +    virtio_tswap64s(vdev, &desc->addr);
> +    virtio_tswap32s(vdev, &desc->len);
> +    virtio_tswap16s(vdev, &desc->id);
> +    virtio_tswap16s(vdev, &desc->flags);
> +}
> +
> +static inline bool is_desc_avail(struct VRingDescPacked* desc)
> +{
> +    return (!!(desc->flags & AVAIL_DESC_PACKED(1)) !=
> +            !!(desc->flags & USED_DESC_PACKED(1)));

Don't we need to care about endian here?

> +}
> +
>   /* Fetch avail_idx from VQ memory only when we really need to know if
>    * guest has added some buffers.
>    * Called within rcu_read_lock().  */
> -static int virtio_queue_empty_rcu(VirtQueue *vq)
> +static int virtio_queue_empty_split_rcu(VirtQueue *vq)
>   {
>       if (unlikely(!vq->vring.avail)) {
>           return 1;
> @@ -462,7 +482,7 @@ static int virtio_queue_empty_rcu(VirtQueue *vq)
>       return vring_avail_idx(vq) == vq->last_avail_idx;
>   }
>   
> -int virtio_queue_empty(VirtQueue *vq)
> +static int virtio_queue_empty_split(VirtQueue *vq)
>   {
>       bool empty;
>   
> @@ -480,6 +500,42 @@ int virtio_queue_empty(VirtQueue *vq)
>       return empty;
>   }
>   
> +static int virtio_queue_empty_packed_rcu(VirtQueue *vq)
> +{
> +    struct VRingDescPacked desc;
> +    VRingMemoryRegionCaches *cache;
> +
> +    if (unlikely(!vq->packed.desc)) {
> +        return 1;
> +    }
> +
> +    cache = vring_get_region_caches(vq);
> +    vring_desc_read_packed(vq->vdev, &desc, &cache->desc_packed, vq->last_avail_idx);
> +
> +    /* Make sure we see the updated flag */
> +    smp_mb();

What we need here is to make sure flag is read before all other fields, 
looks like this barrier can't.

> +    return !is_desc_avail(&desc);
> +}
> +
> +static int virtio_queue_empty_packed(VirtQueue *vq)
> +{
> +    bool empty;
> +
> +    rcu_read_lock();
> +    empty = virtio_queue_empty_packed_rcu(vq);
> +    rcu_read_unlock();
> +    return empty;
> +}
> +
> +int virtio_queue_empty(VirtQueue *vq)
> +{
> +    if (virtio_vdev_has_feature(vq->vdev, VIRTIO_F_RING_PACKED)) {
> +        return virtio_queue_empty_packed(vq);
> +    } else {
> +        return virtio_queue_empty_split(vq);
> +    }
> +}
> +
>   static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
>                                  unsigned int len)
>   {
> @@ -951,7 +1007,7 @@ void *virtqueue_pop(VirtQueue *vq, size_t sz)
>           return NULL;
>       }
>       rcu_read_lock();
> -    if (virtio_queue_empty_rcu(vq)) {
> +    if (virtio_queue_empty_split_rcu(vq)) {

I think you'd better have a switch inside virtio_queue_empty_rcu() like 
virtio_queue_empty() here.

Thanks

>           goto done;
>       }
>       /* Needed after virtio_queue_empty(), see comment in

  reply	other threads:[~2018-04-10  7:23 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-04 12:53 [Qemu-devel] [RFC PATCH 0/8] virtio-net 1.1 userspace backend support wexu
2018-04-04 12:53 ` [Qemu-devel] [PATCH 1/8] virtio: feature bit, data structure for packed ring wexu
2018-04-10  7:05   ` Jason Wang
2018-06-03 16:21     ` Wei Xu
2018-04-04 12:53 ` [Qemu-devel] [PATCH 2/8] virtio: memory cache " wexu
2018-04-10  7:06   ` Jason Wang
2018-04-04 12:53 ` [Qemu-devel] [PATCH 3/8] virtio: add empty check " wexu
2018-04-10  7:23   ` Jason Wang [this message]
2018-06-03 17:44     ` Wei Xu
2018-06-04  8:32       ` Jason Wang
2018-04-04 12:54 ` [Qemu-devel] [PATCH 4/8] virtio: add detach element for packed ring(1.1) wexu
2018-04-10  7:32   ` Jason Wang
2018-06-04  1:34     ` Wei Xu
2018-06-04  1:54       ` Michael S. Tsirkin
2018-06-04  9:40         ` Wei Xu
2018-04-04 12:54 ` [Qemu-devel] [PATCH 5/8] virtio: notification tweak for packed ring wexu
2018-04-04 12:54 ` [Qemu-devel] [PATCH 6/8] virtio: flush/push support " wexu
2018-04-11  2:58   ` Jason Wang
2018-04-04 12:54 ` [Qemu-devel] [PATCH 7/8] virtio: get avail bytes check " wexu
2018-04-11  3:03   ` Jason Wang
2018-06-04  6:07     ` Wei Xu
2018-04-04 12:54 ` [Qemu-devel] [PATCH 8/8] virtio: queue pop support " wexu
2018-04-11  2:43   ` Jason Wang
2018-06-04  7:07     ` Wei Xu
2018-04-04 13:11 ` [Qemu-devel] [RFC PATCH 0/8] virtio-net 1.1 userspace backend support no-reply
2018-04-04 13:14 ` no-reply
2018-04-04 13:14 ` no-reply
2018-04-10  3:46 ` Jason Wang
2018-04-11  2:22   ` Wei Xu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=6a78b53a-0830-74de-5447-63ecab67e5ed@redhat.com \
    --to=jasowang@redhat.com \
    --cc=jfreimann@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=tiwei.bie@intel.com \
    --cc=wexu@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.