Blame SOURCES/kvm-multifd-Use-normal-pages-array-on-the-send-side.patch

719b13
From c70c97cd59fd22de0957ea1c0a655fb5ef270f1e Mon Sep 17 00:00:00 2001
719b13
From: Juan Quintela <quintela@redhat.com>
719b13
Date: Wed, 18 May 2022 02:52:24 -0300
719b13
Subject: [PATCH 16/34] multifd: Use normal pages array on the send side
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: [16/34] 24f4ea3248f6ce883d57344600c8adbf51bd7d8c
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
We are only sending normal pages through multifd channels.
719b13
Later on this series, we are going to also send zero pages.
719b13
We are going to detect if a page is zero or non zero in the multifd
719b13
channel thread, not on the main thread.
719b13
719b13
So we receive an array of pages page->offset[N]
719b13
719b13
And we will end with:
719b13
719b13
p->normal[N - zero_pages]
719b13
p->zero[zero_pages].
719b13
719b13
In this patch, we just copy all the pages in offset to normal.
719b13
719b13
for (i = 0; i < pages->num; i++) {
719b13
    p->narmal[p->normal_num] = pages->offset[i];
719b13
    p->normal_num++:
719b13
}
719b13
719b13
Later in the series this becomes:
719b13
719b13
for (i = 0; i < pages->num; i++) {
719b13
    if (buffer_is_zero(page->offset[i])) {
719b13
        p->zerol[p->zero_num] = pages->offset[i];
719b13
        p->zero_num++:
719b13
    } else {
719b13
        p->narmal[p->normal_num] = pages->offset[i];
719b13
        p->normal_num++:
719b13
    }
719b13
}
719b13
719b13
Signed-off-by: Juan Quintela <quintela@redhat.com>
719b13
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
719b13
719b13
---
719b13
719b13
Improving comment (dave)
719b13
Renaming num_normal_pages to total_normal_pages (peter)
719b13
719b13
(cherry picked from commit 815956f03902980c771da64b17f7f791c1cb57b0)
719b13
Signed-off-by: Leonardo Bras <leobras@redhat.com>
719b13
---
719b13
 migration/multifd-zlib.c |  6 +++---
719b13
 migration/multifd-zstd.c |  6 +++---
719b13
 migration/multifd.c      | 30 +++++++++++++++++++-----------
719b13
 migration/multifd.h      |  8 ++++++--
719b13
 migration/trace-events   |  4 ++--
719b13
 5 files changed, 33 insertions(+), 21 deletions(-)
719b13
719b13
diff --git a/migration/multifd-zlib.c b/migration/multifd-zlib.c
719b13
index 8ed29b9633..8508f26adf 100644
719b13
--- a/migration/multifd-zlib.c
719b13
+++ b/migration/multifd-zlib.c
719b13
@@ -108,16 +108,16 @@ static int zlib_send_prepare(MultiFDSendParams *p, Error **errp)
719b13
     int ret;
719b13
     uint32_t i;
719b13
 
719b13
-    for (i = 0; i < p->pages->num; i++) {
719b13
+    for (i = 0; i < p->normal_num; i++) {
719b13
         uint32_t available = z->zbuff_len - out_size;
719b13
         int flush = Z_NO_FLUSH;
719b13
 
719b13
-        if (i == p->pages->num - 1) {
719b13
+        if (i == p->normal_num - 1) {
719b13
             flush = Z_SYNC_FLUSH;
719b13
         }
719b13
 
719b13
         zs->avail_in = page_size;
719b13
-        zs->next_in = p->pages->block->host + p->pages->offset[i];
719b13
+        zs->next_in = p->pages->block->host + p->normal[i];
719b13
 
719b13
         zs->avail_out = available;
719b13
         zs->next_out = z->zbuff + out_size;
719b13
diff --git a/migration/multifd-zstd.c b/migration/multifd-zstd.c
719b13
index 25e1f517b5..693af3a140 100644
719b13
--- a/migration/multifd-zstd.c
719b13
+++ b/migration/multifd-zstd.c
719b13
@@ -123,13 +123,13 @@ static int zstd_send_prepare(MultiFDSendParams *p, Error **errp)
719b13
     z->out.size = z->zbuff_len;
719b13
     z->out.pos = 0;
719b13
 
719b13
-    for (i = 0; i < p->pages->num; i++) {
719b13
+    for (i = 0; i < p->normal_num; i++) {
719b13
         ZSTD_EndDirective flush = ZSTD_e_continue;
719b13
 
719b13
-        if (i == p->pages->num - 1) {
719b13
+        if (i == p->normal_num - 1) {
719b13
             flush = ZSTD_e_flush;
719b13
         }
719b13
-        z->in.src = p->pages->block->host + p->pages->offset[i];
719b13
+        z->in.src = p->pages->block->host + p->normal[i];
719b13
         z->in.size = page_size;
719b13
         z->in.pos = 0;
719b13
 
719b13
diff --git a/migration/multifd.c b/migration/multifd.c
719b13
index d0f86542b1..3725226400 100644
719b13
--- a/migration/multifd.c
719b13
+++ b/migration/multifd.c
719b13
@@ -89,13 +89,13 @@ static int nocomp_send_prepare(MultiFDSendParams *p, Error **errp)
719b13
     MultiFDPages_t *pages = p->pages;
719b13
     size_t page_size = qemu_target_page_size();
719b13
 
719b13
-    for (int i = 0; i < p->pages->num; i++) {
719b13
-        p->iov[p->iovs_num].iov_base = pages->block->host + pages->offset[i];
719b13
+    for (int i = 0; i < p->normal_num; i++) {
719b13
+        p->iov[p->iovs_num].iov_base = pages->block->host + p->normal[i];
719b13
         p->iov[p->iovs_num].iov_len = page_size;
719b13
         p->iovs_num++;
719b13
     }
719b13
 
719b13
-    p->next_packet_size = p->pages->num * page_size;
719b13
+    p->next_packet_size = p->normal_num * page_size;
719b13
     p->flags |= MULTIFD_FLAG_NOCOMP;
719b13
     return 0;
719b13
 }
719b13
@@ -262,7 +262,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
719b13
 
719b13
     packet->flags = cpu_to_be32(p->flags);
719b13
     packet->pages_alloc = cpu_to_be32(p->pages->allocated);
719b13
-    packet->pages_used = cpu_to_be32(p->pages->num);
719b13
+    packet->pages_used = cpu_to_be32(p->normal_num);
719b13
     packet->next_packet_size = cpu_to_be32(p->next_packet_size);
719b13
     packet->packet_num = cpu_to_be64(p->packet_num);
719b13
 
719b13
@@ -270,9 +270,9 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
719b13
         strncpy(packet->ramblock, p->pages->block->idstr, 256);
719b13
     }
719b13
 
719b13
-    for (i = 0; i < p->pages->num; i++) {
719b13
+    for (i = 0; i < p->normal_num; i++) {
719b13
         /* there are architectures where ram_addr_t is 32 bit */
719b13
-        uint64_t temp = p->pages->offset[i];
719b13
+        uint64_t temp = p->normal[i];
719b13
 
719b13
         packet->offset[i] = cpu_to_be64(temp);
719b13
     }
719b13
@@ -556,6 +556,8 @@ void multifd_save_cleanup(void)
719b13
         p->packet = NULL;
719b13
         g_free(p->iov);
719b13
         p->iov = NULL;
719b13
+        g_free(p->normal);
719b13
+        p->normal = NULL;
719b13
         multifd_send_state->ops->send_cleanup(p, &local_err);
719b13
         if (local_err) {
719b13
             migrate_set_error(migrate_get_current(), local_err);
719b13
@@ -640,12 +642,17 @@ static void *multifd_send_thread(void *opaque)
719b13
         qemu_mutex_lock(&p->mutex);
719b13
 
719b13
         if (p->pending_job) {
719b13
-            uint32_t used = p->pages->num;
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
+            for (int i = 0; i < p->pages->num; i++) {
719b13
+                p->normal[p->normal_num] = p->pages->offset[i];
719b13
+                p->normal_num++;
719b13
+            }
719b13
 
719b13
-            if (used) {
719b13
+            if (p->normal_num) {
719b13
                 ret = multifd_send_state->ops->send_prepare(p, &local_err);
719b13
                 if (ret != 0) {
719b13
                     qemu_mutex_unlock(&p->mutex);
719b13
@@ -655,12 +662,12 @@ static void *multifd_send_thread(void *opaque)
719b13
             multifd_send_fill_packet(p);
719b13
             p->flags = 0;
719b13
             p->num_packets++;
719b13
-            p->num_pages += used;
719b13
+            p->total_normal_pages += p->normal_num;
719b13
             p->pages->num = 0;
719b13
             p->pages->block = NULL;
719b13
             qemu_mutex_unlock(&p->mutex);
719b13
 
719b13
-            trace_multifd_send(p->id, packet_num, used, flags,
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
@@ -710,7 +717,7 @@ out:
719b13
     qemu_mutex_unlock(&p->mutex);
719b13
 
719b13
     rcu_unregister_thread();
719b13
-    trace_multifd_send_thread_end(p->id, p->num_packets, p->num_pages);
719b13
+    trace_multifd_send_thread_end(p->id, p->num_packets, p->total_normal_pages);
719b13
 
719b13
     return NULL;
719b13
 }
719b13
@@ -910,6 +917,7 @@ int multifd_save_setup(Error **errp)
719b13
         p->tls_hostname = g_strdup(s->hostname);
719b13
         /* We need one extra place for the packet header */
719b13
         p->iov = g_new0(struct iovec, page_count + 1);
719b13
+        p->normal = g_new0(ram_addr_t, page_count);
719b13
         socket_send_channel_create(multifd_new_send_channel_async, p);
719b13
     }
719b13
 
719b13
diff --git a/migration/multifd.h b/migration/multifd.h
719b13
index 7496f951a7..7823199dbe 100644
719b13
--- a/migration/multifd.h
719b13
+++ b/migration/multifd.h
719b13
@@ -104,14 +104,18 @@ typedef struct {
719b13
     /* thread local variables */
719b13
     /* packets sent through this channel */
719b13
     uint64_t num_packets;
719b13
-    /* pages sent through this channel */
719b13
-    uint64_t num_pages;
719b13
+    /* non zero pages sent through this channel */
719b13
+    uint64_t total_normal_pages;
719b13
     /* syncs main thread and channels */
719b13
     QemuSemaphore sem_sync;
719b13
     /* buffers to send */
719b13
     struct iovec *iov;
719b13
     /* number of iovs used */
719b13
     uint32_t iovs_num;
719b13
+    /* Pages that are not zero */
719b13
+    ram_addr_t *normal;
719b13
+    /* num of non zero pages */
719b13
+    uint32_t normal_num;
719b13
     /* used for compression methods */
719b13
     void *data;
719b13
 }  MultiFDSendParams;
719b13
diff --git a/migration/trace-events b/migration/trace-events
719b13
index 5172cb3b3d..171a83a55d 100644
719b13
--- a/migration/trace-events
719b13
+++ b/migration/trace-events
719b13
@@ -124,13 +124,13 @@ multifd_recv_sync_main_wait(uint8_t id) "channel %u"
719b13
 multifd_recv_terminate_threads(bool error) "error %d"
719b13
 multifd_recv_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel %u packets %" PRIu64 " pages %" PRIu64
719b13
 multifd_recv_thread_start(uint8_t id) "%u"
719b13
-multifd_send(uint8_t id, uint64_t packet_num, uint32_t used, uint32_t flags, uint32_t next_packet_size) "channel %u packet_num %" PRIu64 " pages %u flags 0x%x next packet size %u"
719b13
+multifd_send(uint8_t id, uint64_t packet_num, uint32_t normal, uint32_t flags, uint32_t next_packet_size) "channel %u packet_num %" PRIu64 " normal pages %u flags 0x%x next packet size %u"
719b13
 multifd_send_error(uint8_t id) "channel %u"
719b13
 multifd_send_sync_main(long packet_num) "packet num %ld"
719b13
 multifd_send_sync_main_signal(uint8_t id) "channel %u"
719b13
 multifd_send_sync_main_wait(uint8_t id) "channel %u"
719b13
 multifd_send_terminate_threads(bool error) "error %d"
719b13
-multifd_send_thread_end(uint8_t id, uint64_t packets, uint64_t pages) "channel %u packets %" PRIu64 " pages %"  PRIu64
719b13
+multifd_send_thread_end(uint8_t id, uint64_t packets, uint64_t normal_pages) "channel %u packets %" PRIu64 " normal pages %"  PRIu64
719b13
 multifd_send_thread_start(uint8_t id) "%u"
719b13
 multifd_tls_outgoing_handshake_start(void *ioc, void *tioc, const char *hostname) "ioc=%p tioc=%p hostname=%s"
719b13
 multifd_tls_outgoing_handshake_error(void *ioc, const char *err) "ioc=%p err=%s"
719b13
-- 
719b13
2.35.3
719b13