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(-)
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 */
--
2.39.2
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 */
© 2016 - 2026 Red Hat, Inc.