From: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
To: "Marc-André Lureau" <marcandre.lureau@gmail.com>
Cc: QEMU <qemu-devel@nongnu.org>,
Stefan Hajnoczi <stefanha@redhat.com>,
vgoyal@redhat.com, "Michael S. Tsirkin" <mst@redhat.com>
Subject: Re: vhost-user payload union restrictions ?
Date: Wed, 5 May 2021 18:54:16 +0100 [thread overview]
Message-ID: <YJLbyERdbaFBwgg+@work-vm> (raw)
In-Reply-To: <CAJ+F1CLZedsd4X9x5iLoaNNUXSqvet-AKOb-LNsuBjkqfnB3vg@mail.gmail.com>
* Marc-André Lureau (marcandre.lureau@gmail.com) wrote:
> Hi
>
> On Wed, May 5, 2021 at 4:38 PM Dr. David Alan Gilbert <dgilbert@redhat.com>
> wrote:
>
> > (Resend, remembering to add list)
> > Hi,
> > I'm trying to understand what restrictions there are on the
> > payload that's part of VhostUserMsg; and am confused by
> > inconsistencies.
> >
> > Lets start with this version:
> >
> > subprojects/libvhost-user/libvhost-user.h :
> > typedef struct VhostUserMsg {
> > int request;
> >
> > #define VHOST_USER_VERSION_MASK (0x3)
> > #define VHOST_USER_REPLY_MASK (0x1 << 2)
> > #define VHOST_USER_NEED_REPLY_MASK (0x1 << 3)
> > uint32_t flags;
> > uint32_t size; /* the following payload size */
> >
> > union {
> > #define VHOST_USER_VRING_IDX_MASK (0xff)
> > #define VHOST_USER_VRING_NOFD_MASK (0x1 << 8)
> > uint64_t u64;
> > struct vhost_vring_state state;
> > struct vhost_vring_addr addr;
> > VhostUserMemory memory;
> > VhostUserMemRegMsg memreg;
> > VhostUserLog log;
> > VhostUserConfig config;
> > VhostUserVringArea area;
> > VhostUserInflight inflight;
> > } payload;
> >
> > int fds[VHOST_MEMORY_BASELINE_NREGIONS];
> > int fd_num;
> > uint8_t *data;
> > } VU_PACKED VhostUserMsg;
> >
> > note the 'fds' array after the payload but before
> > the end of the structure.
> >
> > But then there's the version in:
> > hw/virtio/vhost-user.c
> > typedef union {
> > #define VHOST_USER_VRING_IDX_MASK (0xff)
> > #define VHOST_USER_VRING_NOFD_MASK (0x1<<8)
> > uint64_t u64;
> > struct vhost_vring_state state;
> > struct vhost_vring_addr addr;
> > VhostUserMemory memory;
> > VhostUserMemRegMsg mem_reg;
> > VhostUserLog log;
> > struct vhost_iotlb_msg iotlb;
> > VhostUserConfig config;
> > VhostUserCryptoSession session;
> > VhostUserVringArea area;
> > VhostUserInflight inflight;
> > } VhostUserPayload;
> >
> > typedef struct VhostUserMsg {
> > VhostUserHeader hdr;
> > VhostUserPayload payload;
> > } QEMU_PACKED VhostUserMsg;
> >
> > which hasn't got the 'fds' section.
> > Yet they're both marked as 'packed'.
> >
>
> They are packed, because both are used to serialize/deserialize the stream.
The header is (de)serialized and the payload is; but we don't ever try
and deal with both at the same time do we ? We read the header, check
the length, read the payload; so isn't it really each part is packed and
not the whole?
>
> > That's a bit unfortunate for two structures with the same name.
> >
> >
> Yes, maybe it's time to have a canonical system header used by both?
Any idea where that would live? I think the problem is that in some
respects the libvhost_user.h is the right place, but it's now formally a
separate/sub project.
> > Am I right in thinking that the vhost-user.c version is sent over
> > the wire, while the libvhost-user.h one is really just an interface?
> >
> >
> I believe the extra fields are not used for serializing the message, but
> just a convenient way to group related data.
OK
> > Is it safe for me to add a new, larger entry in the payload union
> > without breaking existing clients?
> >
>
> It should be.
Good.
> > I ended up at this question after trying to add a variable length
> > entry to the union:
> >
> > typedef struct {
> > VhostUserFSSlaveMsg fs;
> > VhostUserFSSlaveMsgEntry entries[VHOST_USER_FS_SLAVE_MAX_ENTRIES];
> > } QEMU_PACKED VhostUserFSSlaveMsgMax;
> >
> > ...
> > union ....
> > VhostUserFSSlaveMsg fs;
> > VhostUserFSSlaveMsgMax fs_max; /* Never actually used */
> > } VhostUserPayload;
> >
> > and in the .h I had:
> > typedef struct {
> > /* Generic flags for the overall message */
> > uint32_t flags;
> > /* Number of entries */
> > uint16_t count;
> > /* Spare */
> > uint16_t align;
> >
> > VhostUserFSSlaveMsgEntry entries[];
> > } VhostUserFSSlaveMsg;
> >
> > union {
> > ...
> > VhostUserInflight inflight;
> > VhostUserFSSlaveMsg fs;
> > } payload;
> >
> > which is apparently OK in the .c version, and gcc is happy with the same
> > in the libvhost-user.h version; but clang gets upset by the .h
> > version because it doesn't like the variable length structure
> > before the end of the struct - which I have sympathy for.
> >
> >
> Indeed, we probably want to allocate the message separately then.
I'm thinking that wecould change the libvhost-user.h to be:
(as the C file)
typedef struct VhostUserMsg {
VhostUserHeader hdr;
VhostUserPayload payload;
} VU_PACKED VhostUserMsgWire;
typedef struct VhostUserMsgExt {
int fds[VHOST_MEMORY_BASELINE_NREGIONS];
int fd_num;
uint8_t *data;
VhostUserMsgWire msg;
} VhostUserMsg;
Dave
> thanks
>
> --
> Marc-André Lureau
--
Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK
prev parent reply other threads:[~2021-05-05 17:56 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-05-05 12:36 vhost-user payload union restrictions ? Dr. David Alan Gilbert
2021-05-05 12:59 ` Marc-André Lureau
2021-05-05 17:54 ` Dr. David Alan Gilbert [this message]
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=YJLbyERdbaFBwgg+@work-vm \
--to=dgilbert@redhat.com \
--cc=marcandre.lureau@gmail.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=vgoyal@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.