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

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