All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Michael S. Tsirkin" <mst@redhat.com>
To: Stefano Garzarella <sgarzare@redhat.com>
Cc: Stefan Hajnoczi <stefanha@gmail.com>,
	Changpeng Liu <changpeng.liu@intel.com>,
	qemu-devel@nongnu.org, ldoktor@redhat.com, dgilbert@redhat.com,
	stefanha@redhat.com, Greg Kurz <groug@kaod.org>
Subject: Re: [Qemu-devel] [PATCH v4] virtio-blk: set correct config size for the host driver
Date: Wed, 13 Feb 2019 12:06:41 -0500	[thread overview]
Message-ID: <20190213120418-mutt-send-email-mst@kernel.org> (raw)
In-Reply-To: <20190213121703.zmzpgl4fvvsfg4pf@steredhat>

On Wed, Feb 13, 2019 at 01:17:03PM +0100, Stefano Garzarella wrote:
> On Wed, Feb 13, 2019 at 09:32:27AM +0100, Stefano Garzarella wrote:
> > On Wed, Feb 13, 2019 at 04:01:43PM +0800, Stefan Hajnoczi wrote:
> > > On Wed, Feb 13, 2019 at 09:48:57AM +0800, Changpeng Liu wrote:
> > > > Commit caa1ee43 "vhost-user-blk: add discard/write zeroes features
> > > > support" added fields to struct virtio_blk_config. This changes
> > > > the size of the config space and breaks migration from QEMU 3.1
> > > > and older:
> > > > 
> > > > qemu-system-ppc64: get_pci_config_device: Bad config data: i=0x10 read: 41 device: 1 cmask: ff wmask: 80 w1cmask:0
> > > > qemu-system-ppc64: Failed to load PCIDevice:config
> > > > qemu-system-ppc64: Failed to load virtio-blk:virtio
> > > > qemu-system-ppc64: error while loading state for instance 0x0 of device 'pci@800000020000000:01.0/virtio-blk'
> > > > qemu-system-ppc64: load of migration failed: Invalid argument
> > > > 
> > > > Since virtio-blk doesn't support the "discard" and "write zeroes"
> > > > features, it shouldn't even expose the associated fields in the
> > > > config space actually. Just include all fields up to num_queues to
> > > > match QEMU 3.1 and older.
> > > > 
> > > > Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
> > > > ---
> > > >  hw/block/virtio-blk.c | 13 +++++++++----
> > > >  1 file changed, 9 insertions(+), 4 deletions(-)
> > > 
> > > Stefano: Please rebase your DISCARD/WRITE_ZEROES series onto this and
> > > check that the config space is correctly sized.  Machine types before
> > > 4.0 shouldn't have these fields so that the config space size remains
> > > unchanged.
> > 
> > Sure!
> > 
> > Since I should set a correct config size checking if new features are
> > enabled or not at runtime, should be better to add a variable and an array
> > of sizes like in virtio-net?
> 
> In my series "[PATCH v4 0/6] virtio-blk: add DISCARD and WRITE_ZEROES"
> I'm adding the host_features field in VirtIOBlock. Then, I could add
> something like the following patch (proof of concept) inspired by the
> virtio-net approach, that would be simplest to maintain when we will add
> new features.
> 
> What do you think?
> 
> Thanks,
> Stefano
> 
> 
> diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
> index 843bb2bec8..84dcc1406c 100644
> --- a/hw/block/virtio-blk.c
> +++ b/hw/block/virtio-blk.c
> @@ -28,6 +28,51 @@
>  #include "hw/virtio/virtio-bus.h"
>  #include "hw/virtio/virtio-access.h"
>  
> +/*
> + * Calculate the number of bytes up to and including the given 'field' of
> + * 'container'.
> + */
> +#define endof(container, field) \
> +    (offsetof(container, field) + sizeof_field(container, field))
> +

e.g. virtio.h. just add virtio prefix.

> +typedef struct VirtIOFeature {
> +    uint64_t flags;
> +    size_t end;
> +} VirtIOFeature;
> +
> +static VirtIOFeature feature_sizes[] = {
> +    {.flags = 1ULL << VIRTIO_NET_F_SIZE_MAX,
> +     .end = endof(struct virtio_blk_config, size_max)},
> +    {.flags = 1ULL << VIRTIO_NET_F_SEG_MAX,
> +     .end = endof(struct virtio_blk_config, seg_max)},
> +    {.flags = 1ULL << VIRTIO_NET_F_GEOMETRY,
> +     .end = endof(struct virtio_blk_config, geometry)},
> +    {.flags = 1ULL << VIRTIO_NET_F_BLK_SIZE,
> +     .end = endof(struct virtio_blk_config, blk_size)},
> +    {.flags = 1ULL << VIRTIO_NET_F_TOPOLOGY,
> +     .end = endof(struct virtio_blk_config, opt_io_size)},
> +    {.flags = 1ULL << VIRTIO_NET_F_CONFIG_WCE,
> +     .end = endof(struct virtio_blk_config, wce)},
> +    {.flags = 1ULL << VIRTIO_NET_F_MQ,
> +     .end = endof(struct virtio_blk_config, num_queues)},
> +    {}

All names above with net look wrong to me.

> +};
> +
> +static void virtio_blk_set_config_size(VirtIOBlock *s, uint64_t host_features)
> +{
> +    int i, config_size;
> +
> +    config_size = endof(struct virtio_blk_config, capacity);
> +
> +    for (i = 0; feature_sizes[i].flags != 0; i++) {
> +        if (host_features & feature_sizes[i].flags) {
> +            config_size = MAX(feature_sizes[i].end, config_size);
> +        }
> +    }
> +
> +    s->config_size = config_size;
> +}
> +

Put this in virtio.c maybe? size can be returned.


>  static void virtio_blk_init_request(VirtIOBlock *s, VirtQueue *vq,
>                                      VirtIOBlockReq *req)
>  {
> @@ -757,7 +802,7 @@ static void virtio_blk_update_config(VirtIODevice *vdev, uint8_t *config)
>      blkcfg.alignment_offset = 0;
>      blkcfg.wce = blk_enable_write_cache(s->blk);
>      virtio_stw_p(vdev, &blkcfg.num_queues, s->conf.num_queues);
> -    memcpy(config, &blkcfg, sizeof(struct virtio_blk_config));
> +    memcpy(config, &blkcfg, s->config_size);
>  }
>  
>  static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
> @@ -765,7 +810,7 @@ static void virtio_blk_set_config(VirtIODevice *vdev, const uint8_t *config)
>      VirtIOBlock *s = VIRTIO_BLK(vdev);
>      struct virtio_blk_config blkcfg;
>  
> -    memcpy(&blkcfg, config, sizeof(blkcfg));
> +    memcpy(&blkcfg, config, s->config_size);
>  
>      aio_context_acquire(blk_get_aio_context(s->blk));
>      blk_set_enable_write_cache(s->blk, blkcfg.wce != 0);
> @@ -948,8 +993,9 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp)
>          return;
>      }
>  
> -    virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
> -                sizeof(struct virtio_blk_config));
> +    virtio_blk_set_config_size(s, s->host_features);
> +
> +    virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, s->config_size);
>  
>      s->blk = conf->conf.blk;
>      s->rq = NULL;

  reply	other threads:[~2019-02-13 17:07 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-13  1:48 [Qemu-devel] [PATCH v4] virtio-blk: set correct config size for the host driver Changpeng Liu
2019-02-13  2:05 ` Michael S. Tsirkin
2019-02-13  8:00   ` Stefan Hajnoczi
2019-02-13  8:01 ` Stefan Hajnoczi
2019-02-13  8:32   ` Stefano Garzarella
2019-02-13 12:17     ` Stefano Garzarella
2019-02-13 17:06       ` Michael S. Tsirkin [this message]
2019-02-13 17:45         ` Stefano Garzarella
2019-02-14  3:37           ` Stefan Hajnoczi
2019-02-13  8:07 ` 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=20190213120418-mutt-send-email-mst@kernel.org \
    --to=mst@redhat.com \
    --cc=changpeng.liu@intel.com \
    --cc=dgilbert@redhat.com \
    --cc=groug@kaod.org \
    --cc=ldoktor@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sgarzare@redhat.com \
    --cc=stefanha@gmail.com \
    --cc=stefanha@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.