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

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