From: "Michael S. Tsirkin" <mst@redhat.com>
To: qemu-devel@nongnu.org
Cc: Denis Plotnikov <den-plotnikov@yandex-team.ru>,
Peter Maydell <peter.maydell@linaro.org>
Subject: [PULL 03/35] vhost: make SET_VRING_ADDR, SET_FEATURES send replies
Date: Sat, 4 Sep 2021 17:36:02 -0400 [thread overview]
Message-ID: <20210904213506.486886-4-mst@redhat.com> (raw)
In-Reply-To: <20210904213506.486886-1-mst@redhat.com>
From: Denis Plotnikov <den-plotnikov@yandex-team.ru>
On vhost-user-blk migration, qemu normally sends a number of commands
to enable logging if VHOST_USER_PROTOCOL_F_LOG_SHMFD is negotiated.
Qemu sends VHOST_USER_SET_FEATURES to enable buffers logging and
VHOST_USER_SET_VRING_ADDR per each started ring to enable "used ring"
data logging.
The issue is that qemu doesn't wait for reply from the vhost daemon
for these commands which may result in races between qemu expectation
of logging starting and actual login starting in vhost daemon.
The race can appear as follows: on migration setup, qemu enables dirty page
logging by sending VHOST_USER_SET_FEATURES. The command doesn't arrive to a
vhost-user-blk daemon immediately and the daemon needs some time to turn the
logging on internally. If qemu doesn't wait for reply, after sending the
command, qemu may start migrateing memory pages to a destination. At this time,
the logging may not be actually turned on in the daemon but some guest pages,
which the daemon is about to write to, may have already been transferred
without logging to the destination. Since the logging wasn't turned on,
those pages won't be transferred again as dirty. So we may end up with
corrupted data on the destination.
The same scenario is applicable for "used ring" data logging, which is
turned on with VHOST_USER_SET_VRING_ADDR command.
To resolve this issue, this patch makes qemu wait for the command result
explicitly if VHOST_USER_PROTOCOL_F_REPLY_ACK is negotiated and logging enabled.
Signed-off-by: Denis Plotnikov <den-plotnikov@yandex-team.ru>
Message-Id: <20210809104824.78830-1-den-plotnikov@yandex-team.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
hw/virtio/vhost-user.c | 145 ++++++++++++++++++++++++++++-------------
1 file changed, 101 insertions(+), 44 deletions(-)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 33002300c2..a4eb6cde7e 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1095,23 +1095,6 @@ static int vhost_user_set_mem_table(struct vhost_dev *dev,
return 0;
}
-static int vhost_user_set_vring_addr(struct vhost_dev *dev,
- struct vhost_vring_addr *addr)
-{
- VhostUserMsg msg = {
- .hdr.request = VHOST_USER_SET_VRING_ADDR,
- .hdr.flags = VHOST_USER_VERSION,
- .payload.addr = *addr,
- .hdr.size = sizeof(msg.payload.addr),
- };
-
- if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
- }
-
- return 0;
-}
-
static int vhost_user_set_vring_endian(struct vhost_dev *dev,
struct vhost_vring_state *ring)
{
@@ -1288,33 +1271,6 @@ static int vhost_user_set_vring_call(struct vhost_dev *dev,
return vhost_set_vring_file(dev, VHOST_USER_SET_VRING_CALL, file);
}
-static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64)
-{
- VhostUserMsg msg = {
- .hdr.request = request,
- .hdr.flags = VHOST_USER_VERSION,
- .payload.u64 = u64,
- .hdr.size = sizeof(msg.payload.u64),
- };
-
- if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
- return -1;
- }
-
- return 0;
-}
-
-static int vhost_user_set_features(struct vhost_dev *dev,
- uint64_t features)
-{
- return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features);
-}
-
-static int vhost_user_set_protocol_features(struct vhost_dev *dev,
- uint64_t features)
-{
- return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features);
-}
static int vhost_user_get_u64(struct vhost_dev *dev, int request, uint64_t *u64)
{
@@ -1360,6 +1316,107 @@ static int vhost_user_get_features(struct vhost_dev *dev, uint64_t *features)
return 0;
}
+static int enforce_reply(struct vhost_dev *dev,
+ const VhostUserMsg *msg)
+{
+ uint64_t dummy;
+
+ if (msg->hdr.flags & VHOST_USER_NEED_REPLY_MASK) {
+ return process_message_reply(dev, msg);
+ }
+
+ /*
+ * We need to wait for a reply but the backend does not
+ * support replies for the command we just sent.
+ * Send VHOST_USER_GET_FEATURES which makes all backends
+ * send a reply.
+ */
+ return vhost_user_get_features(dev, &dummy);
+}
+
+static int vhost_user_set_vring_addr(struct vhost_dev *dev,
+ struct vhost_vring_addr *addr)
+{
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_SET_VRING_ADDR,
+ .hdr.flags = VHOST_USER_VERSION,
+ .payload.addr = *addr,
+ .hdr.size = sizeof(msg.payload.addr),
+ };
+
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+
+ /*
+ * wait for a reply if logging is enabled to make sure
+ * backend is actually logging changes
+ */
+ bool wait_for_reply = addr->flags & (1 << VHOST_VRING_F_LOG);
+
+ if (reply_supported && wait_for_reply) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (wait_for_reply) {
+ return enforce_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
+static int vhost_user_set_u64(struct vhost_dev *dev, int request, uint64_t u64,
+ bool wait_for_reply)
+{
+ VhostUserMsg msg = {
+ .hdr.request = request,
+ .hdr.flags = VHOST_USER_VERSION,
+ .payload.u64 = u64,
+ .hdr.size = sizeof(msg.payload.u64),
+ };
+
+ if (wait_for_reply) {
+ bool reply_supported = virtio_has_feature(dev->protocol_features,
+ VHOST_USER_PROTOCOL_F_REPLY_ACK);
+ if (reply_supported) {
+ msg.hdr.flags |= VHOST_USER_NEED_REPLY_MASK;
+ }
+ }
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ return -1;
+ }
+
+ if (wait_for_reply) {
+ return enforce_reply(dev, &msg);
+ }
+
+ return 0;
+}
+
+static int vhost_user_set_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ /*
+ * wait for a reply if logging is enabled to make sure
+ * backend is actually logging changes
+ */
+ bool log_enabled = features & (0x1ULL << VHOST_F_LOG_ALL);
+
+ return vhost_user_set_u64(dev, VHOST_USER_SET_FEATURES, features,
+ log_enabled);
+}
+
+static int vhost_user_set_protocol_features(struct vhost_dev *dev,
+ uint64_t features)
+{
+ return vhost_user_set_u64(dev, VHOST_USER_SET_PROTOCOL_FEATURES, features,
+ false);
+}
+
static int vhost_user_set_owner(struct vhost_dev *dev)
{
VhostUserMsg msg = {
--
MST
next prev parent reply other threads:[~2021-09-04 21:37 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-04 21:35 [PULL 00/35] pc,pci,virtio: fixes, cleanups Michael S. Tsirkin
2021-09-04 21:35 ` [PULL 01/35] vhost-vdpa: Do not send empty IOTLB update batches Michael S. Tsirkin
2021-09-04 21:35 ` [PULL 02/35] hw/virtio: Fix leak of host-notifier memory-region Michael S. Tsirkin
2021-09-04 21:36 ` Michael S. Tsirkin [this message]
2021-09-04 21:36 ` [PULL 04/35] hw/acpi: define PIIX4 acpi pci hotplug property strings at a single place Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 05/35] q35: catch invalid cpu hotplug configuration Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 06/35] hw/acpi: refactor acpi hp modules so that targets can just use what they need Michael S. Tsirkin
2021-09-06 9:58 ` Philippe Mathieu-Daudé
2021-09-06 10:03 ` Ani Sinha
2021-09-06 10:24 ` Philippe Mathieu-Daudé
2021-09-06 10:49 ` Ani Sinha
2021-09-07 5:55 ` Ani Sinha
2021-09-07 6:13 ` Philippe Mathieu-Daudé
2021-09-07 6:34 ` Ani Sinha
2021-09-07 9:49 ` Ani Sinha
2022-07-19 16:12 ` Peter Maydell
2022-07-19 16:21 ` Peter Maydell
2022-07-20 18:37 ` Ani Sinha
2022-07-20 21:34 ` Peter Maydell
2022-07-20 22:13 ` Ani Sinha
2022-07-21 10:51 ` BB
2022-07-21 12:35 ` Dr. David Alan Gilbert
2022-07-25 17:57 ` Ani Sinha
2021-09-04 21:36 ` [PULL 07/35] hw/virtio: move vhost_set_backend_type() to vhost.c Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 08/35] vhost-user: add missing space in error message Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 09/35] acpi: Delete broken ACPI_GED_X86 macro Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 10/35] Use PCI_HOST_BRIDGE macro Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 11/35] virtio-balloon: don't start free page hinting if postcopy is possible Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 12/35] virtio-balloon: free page hinting cleanups Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 13/35] virtio-bus: introduce iommu_enabled() Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 14/35] virtio-pci: implement iommu_enabled() Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 15/35] vhost: correctly detect the enabling IOMMU Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 16/35] hw/i386/acpi-build: Get NUMA information from struct NumaState Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 17/35] hw/pci: remove all references to find_i440fx function Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 18/35] hw/acpi: use existing references to pci device struct within functions Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 19/35] MAINTAINERS: Added myself as a reviewer for acpi/smbios subsystem Michael S. Tsirkin
2021-09-04 21:36 ` [PULL 20/35] hw/virtio: Document virtio_queue_packed_empty_rcu is called within RCU Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 21/35] hw/virtio: Remove NULL check in virtio_free_region_cache() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 22/35] hw/virtio: Add flatview update in vhost_user_cleanup() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 23/35] tests/vhost-user-bridge.c: Sanity check socket path length Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 24/35] tests/vhost-user-bridge.c: Fix typo in help message Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 25/35] vhost-vdpa: remove unused variable "acked_features" Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 26/35] vhost-vdpa: correctly return err in vhost_vdpa_set_backend_cap() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 27/35] vhost_net: remove the meaningless assignment in vhost_net_start_one() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 28/35] vhost: use unsigned int for nvqs Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 29/35] vhost_net: do not assume nvqs is always 2 Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 30/35] vhost-vdpa: remove the unnecessary check in vhost_vdpa_add() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 31/35] vhost-vdpa: don't cleanup twice " Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 32/35] vhost-vdpa: fix leaking of vhost_net " Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 33/35] vhost-vdpa: tweak the error label " Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 34/35] vhost-vdpa: fix the wrong assertion in vhost_vdpa_init() Michael S. Tsirkin
2021-09-04 21:37 ` [PULL 35/35] vhost-vdpa: remove the unncessary queue_index assignment Michael S. Tsirkin
2021-09-06 9:41 ` [PULL 00/35] pc,pci,virtio: fixes, cleanups Peter Maydell
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=20210904213506.486886-4-mst@redhat.com \
--to=mst@redhat.com \
--cc=den-plotnikov@yandex-team.ru \
--cc=peter.maydell@linaro.org \
--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 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).