diff mbox series

[5/5] multifd: Add colo support

Message ID 6461809211524b24210fd4ac2ea6b2593fc7538f.1683506133.git.lukasstraub2@web.de (mailing list archive)
State New, archived
Headers show
Series multifd: Add colo support | expand

Commit Message

Lukas Straub May 8, 2023, 12:52 a.m. UTC
Signed-off-by: Lukas Straub <lukasstraub2@web.de>
---
 migration/multifd-colo.c | 30 +++++++++++++++++++++++++++++-
 migration/multifd.c      | 11 +++++------
 migration/multifd.h      |  2 ++
 3 files changed, 36 insertions(+), 7 deletions(-)

Comments

Juan Quintela May 8, 2023, 3:13 p.m. UTC | #1
Lukas Straub <lukasstraub2@web.de> wrote:
> Signed-off-by: Lukas Straub <lukasstraub2@web.de>
> ---

Please, split the move the creation of the p->block and the rest of the patch.



> diff --git a/migration/multifd.c b/migration/multifd.c
> index fb5e8859de..fddbf86596 100644
> --- a/migration/multifd.c
> +++ b/migration/multifd.c
> @@ -284,7 +284,6 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
>  static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
>  {
>      MultiFDPacket_t *packet = p->packet;
> -    RAMBlock *block;
>      int i;
>  
>      packet->magic = be32_to_cpu(packet->magic);
> @@ -334,21 +333,21 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
>  
>      /* make sure that ramblock is 0 terminated */
>      packet->ramblock[255] = 0;
> -    block = qemu_ram_block_by_name(packet->ramblock);
> -    if (!block) {
> +    p->block = qemu_ram_block_by_name(packet->ramblock);
> +    if (!p->block) {
>          error_setg(errp, "multifd: unknown ram block %s",
>                     packet->ramblock);
>          return -1;
>      }
>  
> -    p->host = block->host;
> +    p->host = p->block->host;
>      for (i = 0; i < p->normal_num; i++) {
>          uint64_t offset = be64_to_cpu(packet->offset[i]);
>  
> -        if (offset > (block->used_length - p->page_size)) {
> +        if (offset > (p->block->used_length - p->page_size)) {
>              error_setg(errp, "multifd: offset too long %" PRIu64
>                         " (max " RAM_ADDR_FMT ")",
> -                       offset, block->used_length);
> +                       offset, p->block->used_length);
>              return -1;
>          }
>          p->normal[i] = offset;
> diff --git a/migration/multifd.h b/migration/multifd.h
> index 7cfc265148..a835643b48 100644
> --- a/migration/multifd.h
> +++ b/migration/multifd.h
> @@ -175,6 +175,8 @@ typedef struct {
>      uint32_t next_packet_size;
>      /* packets sent through this channel */
>      uint64_t num_packets;
> +    /* ramblock */
> +    RAMBlock *block;
>      /* ramblock host address */
>      uint8_t *host;
>      /* non zero pages recv through this channel */
diff mbox series

Patch

diff --git a/migration/multifd-colo.c b/migration/multifd-colo.c
index c035d15e87..305a1b7000 100644
--- a/migration/multifd-colo.c
+++ b/migration/multifd-colo.c
@@ -15,13 +15,41 @@ 
 #include "ram.h"
 #include "multifd.h"
 #include "io/channel-socket.h"
+#include "migration/colo.h"
 
 #define MULTIFD_INTERNAL
 #include "multifd-internal.h"
 
 static int multifd_colo_recv_pages(MultiFDRecvParams *p, Error **errp)
 {
-    return multifd_recv_state->ops->recv_pages(p, errp);
+    int ret = 0;
+
+    /*
+     * While we're still in precopy mode, we copy received pages to both guest
+     * and cache. No need to set dirty bits, since guest and cache memory are
+     * in sync.
+     */
+    if (migration_incoming_in_colo_state()) {
+        colo_record_bitmap(p->block, p->normal, p->normal_num);
+    }
+
+    p->host = p->block->colo_cache;
+    ret = multifd_recv_state->ops->recv_pages(p, errp);
+    if (ret != 0) {
+        p->host = p->block->host;
+        return ret;
+    }
+
+    if (!migration_incoming_in_colo_state()) {
+        for (int i = 0; i < p->normal_num; i++) {
+            void *guest = p->block->host + p->normal[i];
+            void *cache = p->host + p->normal[i];
+            memcpy(guest, cache, p->page_size);
+        }
+    }
+
+    p->host = p->block->host;
+    return ret;
 }
 
 int multifd_colo_load_setup(Error **errp)
diff --git a/migration/multifd.c b/migration/multifd.c
index fb5e8859de..fddbf86596 100644
--- a/migration/multifd.c
+++ b/migration/multifd.c
@@ -284,7 +284,6 @@  static void multifd_send_fill_packet(MultiFDSendParams *p)
 static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
 {
     MultiFDPacket_t *packet = p->packet;
-    RAMBlock *block;
     int i;
 
     packet->magic = be32_to_cpu(packet->magic);
@@ -334,21 +333,21 @@  static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
 
     /* make sure that ramblock is 0 terminated */
     packet->ramblock[255] = 0;
-    block = qemu_ram_block_by_name(packet->ramblock);
-    if (!block) {
+    p->block = qemu_ram_block_by_name(packet->ramblock);
+    if (!p->block) {
         error_setg(errp, "multifd: unknown ram block %s",
                    packet->ramblock);
         return -1;
     }
 
-    p->host = block->host;
+    p->host = p->block->host;
     for (i = 0; i < p->normal_num; i++) {
         uint64_t offset = be64_to_cpu(packet->offset[i]);
 
-        if (offset > (block->used_length - p->page_size)) {
+        if (offset > (p->block->used_length - p->page_size)) {
             error_setg(errp, "multifd: offset too long %" PRIu64
                        " (max " RAM_ADDR_FMT ")",
-                       offset, block->used_length);
+                       offset, p->block->used_length);
             return -1;
         }
         p->normal[i] = offset;
diff --git a/migration/multifd.h b/migration/multifd.h
index 7cfc265148..a835643b48 100644
--- a/migration/multifd.h
+++ b/migration/multifd.h
@@ -175,6 +175,8 @@  typedef struct {
     uint32_t next_packet_size;
     /* packets sent through this channel */
     uint64_t num_packets;
+    /* ramblock */
+    RAMBlock *block;
     /* ramblock host address */
     uint8_t *host;
     /* non zero pages recv through this channel */