Blame SOURCES/kvm-multifd-Send-header-packet-without-flags-if-zero-cop.patch

719b13
From 8a1b74503b17a1f48283eeec547579aad5bdb8f9 Mon Sep 17 00:00:00 2001
719b13
From: Leonardo Bras <leobras@redhat.com>
719b13
Date: Wed, 18 May 2022 02:52:25 -0300
719b13
Subject: [PATCH 22/34] multifd: Send header packet without flags if
719b13
 zero-copy-send is enabled
719b13
MIME-Version: 1.0
719b13
Content-Type: text/plain; charset=UTF-8
719b13
Content-Transfer-Encoding: 8bit
719b13
719b13
RH-Author: Leonardo Brás <leobras@redhat.com>
719b13
RH-MergeRequest: 185: MSG_ZEROCOPY + Multifd @ rhel8.6
719b13
RH-Commit: [22/34] f8ea6e11134afe5291b6f404dc9b59557fbf1030
719b13
RH-Bugzilla: 2117252
719b13
RH-Acked-by: quintela1 <quintela@redhat.com>
719b13
RH-Acked-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
719b13
RH-Acked-by: Peter Xu <peterx@redhat.com>
719b13
719b13
Since d48c3a0445 ("multifd: Use a single writev on the send side"),
719b13
sending the header packet and the memory pages happens in the same
719b13
writev, which can potentially make the migration faster.
719b13
719b13
Using channel-socket as example, this works well with the default copying
719b13
mechanism of sendmsg(), but with zero-copy-send=true, it will cause
719b13
the migration to often break.
719b13
719b13
This happens because the header packet buffer gets reused quite often,
719b13
and there is a high chance that by the time the MSG_ZEROCOPY mechanism get
719b13
to send the buffer, it has already changed, sending the wrong data and
719b13
causing the migration to abort.
719b13
719b13
It means that, as it is, the buffer for the header packet is not suitable
719b13
for sending with MSG_ZEROCOPY.
719b13
719b13
In order to enable zero copy for multifd, send the header packet on an
719b13
individual write(), without any flags, and the remanining pages with a
719b13
writev(), as it was happening before. This only changes how a migration
719b13
with zero-copy-send=true works, not changing any current behavior for
719b13
migrations with zero-copy-send=false.
719b13
719b13
Signed-off-by: Leonardo Bras <leobras@redhat.com>
719b13
Reviewed-by: Peter Xu <peterx@redhat.com>
719b13
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
719b13
Message-Id: <20220513062836.965425-8-leobras@redhat.com>
719b13
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
719b13
(cherry picked from commit b7dbdd8e76cd03453c234dbb9578d20969859d74)
719b13
Signed-off-by: Leonardo Bras <leobras@redhat.com>
719b13
---
719b13
 migration/multifd.c | 22 +++++++++++++++++++---
719b13
 1 file changed, 19 insertions(+), 3 deletions(-)
719b13
719b13
diff --git a/migration/multifd.c b/migration/multifd.c
719b13
index 1e34e01ebc..193f70cdba 100644
719b13
--- a/migration/multifd.c
719b13
+++ b/migration/multifd.c
719b13
@@ -624,6 +624,7 @@ static void *multifd_send_thread(void *opaque)
719b13
     MultiFDSendParams *p = opaque;
719b13
     Error *local_err = NULL;
719b13
     int ret = 0;
719b13
+    bool use_zero_copy_send = migrate_use_zero_copy_send();
719b13
 
719b13
     trace_multifd_send_thread_start(p->id);
719b13
     rcu_register_thread();
719b13
@@ -646,9 +647,14 @@ static void *multifd_send_thread(void *opaque)
719b13
         if (p->pending_job) {
719b13
             uint64_t packet_num = p->packet_num;
719b13
             uint32_t flags = p->flags;
719b13
-            p->iovs_num = 1;
719b13
             p->normal_num = 0;
719b13
 
719b13
+            if (use_zero_copy_send) {
719b13
+                p->iovs_num = 0;
719b13
+            } else {
719b13
+                p->iovs_num = 1;
719b13
+            }
719b13
+
719b13
             for (int i = 0; i < p->pages->num; i++) {
719b13
                 p->normal[p->normal_num] = p->pages->offset[i];
719b13
                 p->normal_num++;
719b13
@@ -672,8 +678,18 @@ static void *multifd_send_thread(void *opaque)
719b13
             trace_multifd_send(p->id, packet_num, p->normal_num, flags,
719b13
                                p->next_packet_size);
719b13
 
719b13
-            p->iov[0].iov_len = p->packet_len;
719b13
-            p->iov[0].iov_base = p->packet;
719b13
+            if (use_zero_copy_send) {
719b13
+                /* Send header first, without zerocopy */
719b13
+                ret = qio_channel_write_all(p->c, (void *)p->packet,
719b13
+                                            p->packet_len, &local_err);
719b13
+                if (ret != 0) {
719b13
+                    break;
719b13
+                }
719b13
+            } else {
719b13
+                /* Send header using the same writev call */
719b13
+                p->iov[0].iov_len = p->packet_len;
719b13
+                p->iov[0].iov_base = p->packet;
719b13
+            }
719b13
 
719b13
             ret = qio_channel_writev_all(p->c, p->iov, p->iovs_num,
719b13
                                          &local_err);
719b13
-- 
719b13
2.35.3
719b13