All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kurz <gkurz@linux.vnet.ibm.com>
To: Cornelia Huck <cornelia.huck@de.ibm.com>
Cc: qemu-devel@nongnu.org, "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: [Qemu-devel] [PATCH v2 1/2] virtio-net: use the backend cross-endian capabilities
Date: Fri, 13 Nov 2015 09:26:26 +0100	[thread overview]
Message-ID: <20151113092626.4ef6a434@bahia.local> (raw)
In-Reply-To: <20151112185255.1bd6197b.cornelia.huck@de.ibm.com>

On Thu, 12 Nov 2015 18:52:55 +0100
Cornelia Huck <cornelia.huck@de.ibm.com> wrote:

> On Mon, 09 Nov 2015 18:41:33 +0100
> Greg Kurz <gkurz@linux.vnet.ibm.com> wrote:
> 
> > When running a fully emulated device in cross-endian conditions, including
> > a virtio 1.0 device offered to a big endian guest, we need to fix the vnet
> > headers. This is currently handled by the virtio_net_hdr_swap() function
> > in the core virtio-net code but it should actually be handled by the net
> > backend.
> > 
> > With this patch, virtio-net now tries to configure the backend to do the
> > endian fixing when the device starts. If the backend cannot support the
> > requested endiannes, we have to fall back on virtio_net_hdr_swap(): this
> > is recorded in the needs_vnet_hdr_swap flag.
> > 
> > The current vhost-net code also tries to configure net backends. This will
> > be no more needed and will be addressed in a subsequent patch.
> > 
> > Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
> > ---
> > v2: - introduced virtio_net_needs_hdr_swap() to consolidate the logic in one
> >       place
> > ---
> >  hw/net/virtio-net.c            |   43 ++++++++++++++++++++++++++++++++++++++--
> >  include/hw/virtio/virtio-net.h |    1 +
> >  2 files changed, 42 insertions(+), 2 deletions(-)
> > 
> > diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
> > index a877614e3e7a..a10f7a0b4d28 100644
> > --- a/hw/net/virtio-net.c
> > +++ b/hw/net/virtio-net.c
> > @@ -152,6 +152,33 @@ static void virtio_net_vhost_status(VirtIONet *n, uint8_t status)
> >      }
> >  }
> > 
> > +static int peer_has_vnet_hdr(VirtIONet *n);
> 
> Hm, you do not seem to use this?
> 

Oops I needed that in a earlier version of this patch and forgot to remove it...

> > +
> > +static void virtio_net_vnet_status(VirtIONet *n, uint8_t status)
> > +{
> > +    VirtIODevice *vdev = VIRTIO_DEVICE(n);
> > +    NetClientState *peer = qemu_get_queue(n->nic)->peer;
> > +
> > +    if (virtio_net_started(n, status)) {
> > +        int r;
> > +
> > +        if (virtio_is_big_endian(vdev)) {
> > +            r = qemu_set_vnet_be(peer, true);
> > +        } else {
> > +            r = qemu_set_vnet_le(peer, true);
> > +        }
> > +
> > +        n->needs_vnet_hdr_swap = !!r;
> > +    } else if (virtio_net_started(n, vdev->status) &&
> > +               !virtio_net_started(n, status)) {
> > +        if (virtio_is_big_endian(vdev)) {
> > +            qemu_set_vnet_be(peer, false);
> > +        } else {
> > +            qemu_set_vnet_le(peer, false);
> > +        }
> > +    }
> > +}
> > +
> >  static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
> >  {
> >      VirtIONet *n = VIRTIO_NET(vdev);
> > @@ -159,6 +186,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status)
> >      int i;
> >      uint8_t queue_status;
> > 
> > +    virtio_net_vnet_status(n, status);
> >      virtio_net_vhost_status(n, status);
> > 
> >      for (i = 0; i < n->max_queues; i++) {
> > @@ -949,6 +977,14 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr,
> >      }
> >  }
> > 
> > +static bool virtio_net_needs_hdr_swap(VirtIONet *n)
> > +{
> > +    /* virtio_needs_swap() is constant for fixed endian targets: call it
> > +     * first to filter them out without penalty.
> 
> What do you mean with 'constant' here? It still needs to retrieve the
> feature bit from the device, no?
> 

Yes the comment is inaccurate... With the "virtio: cross-endian helpers fixes"
series, virtio_needs_swap() indeed resolves to { return 0; } for fixed little
endian targets but we still need to check the feature bit when the target is big
endian.

If I drop the call to virtio_needs_swap(), all targets will have the same
penalty. If I keep it, fixed little endian targets have no penalty but fixed
big endian targets get an extra check and bi-endian targets get two extra checks...

Not sure what to decide...

> > +     */
> > +    return virtio_needs_swap(VIRTIO_DEVICE(n)) && n->needs_vnet_hdr_swap;
> > +}
> > +
> >  static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt,
> >                             const void *buf, size_t size)
> >  {
> > @@ -957,7 +993,10 @@ static void receive_header(VirtIONet *n, const struct iovec *iov, int iov_cnt,
> >          void *wbuf = (void *)buf;
> >          work_around_broken_dhclient(wbuf, wbuf + n->host_hdr_len,
> >                                      size - n->host_hdr_len);
> > -        virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf);
> > +
> > +        if (virtio_net_needs_hdr_swap(n)) {
> > +            virtio_net_hdr_swap(VIRTIO_DEVICE(n), wbuf);
> > +        }
> >          iov_from_buf(iov, iov_cnt, 0, buf, sizeof(struct virtio_net_hdr));
> >      } else {
> >          struct virtio_net_hdr hdr = {
> > @@ -1167,7 +1206,7 @@ static int32_t virtio_net_flush_tx(VirtIONetQueue *q)
> >                  error_report("virtio-net header incorrect");
> >                  exit(1);
> >              }
> > -            if (virtio_needs_swap(vdev)) {
> > +            if (virtio_net_needs_hdr_swap(n)) {
> >                  virtio_net_hdr_swap(vdev, (void *) &mhdr);
> >                  sg2[0].iov_base = &mhdr;
> >                  sg2[0].iov_len = n->guest_hdr_len;
> > diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
> > index f3cc25feca2b..27bc868fbc7d 100644
> > --- a/include/hw/virtio/virtio-net.h
> > +++ b/include/hw/virtio/virtio-net.h
> > @@ -94,6 +94,7 @@ typedef struct VirtIONet {
> >      uint64_t curr_guest_offloads;
> >      QEMUTimer *announce_timer;
> >      int announce_counter;
> > +    bool needs_vnet_hdr_swap;
> >  } VirtIONet;
> > 
> >  void virtio_net_set_netclient_name(VirtIONet *n, const char *name,
> > 
> > 
> 

  reply	other threads:[~2015-11-13  8:26 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-11-09 17:40 [Qemu-devel] [PATCH v2 0/2] virtio-net/vhost-net: share cross-endian enablement Greg Kurz
2015-11-09 17:41 ` [Qemu-devel] [PATCH v2 1/2] virtio-net: use the backend cross-endian capabilities Greg Kurz
2015-11-12 17:52   ` Cornelia Huck
2015-11-13  8:26     ` Greg Kurz [this message]
2015-11-13 14:46       ` Cornelia Huck
2015-11-13 14:54         ` Greg Kurz
2015-11-09 17:42 ` [Qemu-devel] [PATCH v2 2/2] Revert "vhost-net: tell tap backend about the vnet endianness" Greg Kurz

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=20151113092626.4ef6a434@bahia.local \
    --to=gkurz@linux.vnet.ibm.com \
    --cc=cornelia.huck@de.ibm.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /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.