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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).