qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC 1/2] virtio: expose used buffers


From: Eugenio Perez Martin
Subject: Re: [RFC 1/2] virtio: expose used buffers
Date: Thu, 25 Aug 2022 10:59:40 +0200

On Thu, Aug 25, 2022 at 9:16 AM Guo Zhi <qtxuning1999@sjtu.edu.cn> wrote:
>
>
>
> ----- Original Message -----
> > From: "eperezma" <eperezma@redhat.com>
> > To: "Guo Zhi" <qtxuning1999@sjtu.edu.cn>
> > Cc: "jasowang" <jasowang@redhat.com>, "sgarzare" <sgarzare@redhat.com>, 
> > "Michael Tsirkin" <mst@redhat.com>,
> > "qemu-devel@nongnu.org Developers" <qemu-devel@nongnu.org>
> > Sent: Monday, August 22, 2022 10:08:32 PM
> > Subject: Re: [RFC 1/2] virtio: expose used buffers
>
> > On Thu, Aug 18, 2022 at 5:13 PM Guo Zhi <qtxuning1999@sjtu.edu.cn> wrote:
> >>
> >> Follow VIRTIO 1.1 spec, we can only writing out a single used ring for a
> >> batch of descriptors, and only notify guest when the batch of
> >> descriptors have all been used.
> >>
> >> We do that batch for tx, because the driver doesn't need to know the
> >> length of tx buffer, while for rx, we don't apply the batch strategy.
> >>
> >> Signed-off-by: Guo Zhi <qtxuning1999@sjtu.edu.cn>
> >> ---
> >>  hw/net/virtio-net.c | 29 ++++++++++++++++++++++++++---
> >>  1 file changed, 26 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> >> index dd0d056f..c8e83921 100644
> >> --- a/hw/net/virtio-net.c
> >> +++ b/hw/net/virtio-net.c
> >> @@ -2542,8 +2542,10 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue 
> >> *q)
> >>      VirtIONet *n = q->n;
> >>      VirtIODevice *vdev = VIRTIO_DEVICE(n);
> >>      VirtQueueElement *elem;
> >> +    VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE];
> >>      int32_t num_packets = 0;
> >>      int queue_index = vq2q(virtio_get_queue_index(q->tx_vq));
> >> +    size_t j;
> >>      if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
> >>          return num_packets;
> >>      }
> >> @@ -2621,14 +2623,35 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue 
> >> *q)
> >>          }
> >>
> >>  drop:
> >> -        virtqueue_push(q->tx_vq, elem, 0);
> >> -        virtio_notify(vdev, q->tx_vq);
> >> -        g_free(elem);
> >> +        if (!virtio_vdev_has_feature(vdev, VIRTIO_F_IN_ORDER)) {
> >> +            virtqueue_push(q->tx_vq, elem, 0);
> >> +            virtio_notify(vdev, q->tx_vq);
> >> +            g_free(elem);
> >> +        } else {
> >> +            elems[num_packets] = elem;
> >> +        }
> >>
> >>          if (++num_packets >= n->tx_burst) {
> >>              break;
> >>          }
> >>      }
> >> +
> >> +    if (virtio_vdev_has_feature(vdev, VIRTIO_F_IN_ORDER) && num_packets) {
> >> +        /**
> >> +         * If in order feature negotiated, devices can notify the use of a
> >> batch
> >> +         * of buffers to the driver by only writing out a single used ring
> >> entry
> >> +         * with the id corresponding to the head entry of the descriptor 
> >> chain
> >> +         * describing the last buffer in the batch.
> >> +         */
> >> +        virtqueue_fill(q->tx_vq, elems[num_packets - 1], 0, 0);
> >> +        for (j = 0; j < num_packets; j++) {
> >
> > There are a few calls on virtqueue_pop that we need to keep cleaning
> > here. For example, the increment on vq->inuse or dma_memory_map/unmap.
> > Maybe it is ok to call virtqueue_detach_element here for all skipped
> > buffers of the batch, but I haven't reviewed it in depth.
>
> Yeah, I think I should call virtqueue_detach_element for skipped buffers.
>
> >
> > Also, if we want to batch, we must increment used idx accordingly.
> > From the standard, "The device then skips forward in the [used] ring
> > according to the size of the batch. Accordingly, it increments the
> > used idx by the size of the batch."
> >
>
> used_idx has been added by the size of the batch, because of this:
>
> virtqueue_flush(q->tx_vq, num_packets);
>

Oh, right, good point!

Thanks!




reply via email to

[Prev in Thread] Current Thread [Next in Thread]