Message ID | 6461809211524b24210fd4ac2ea6b2593fc7538f.1683506133.git.lukasstraub2@web.de |
---|---|
State | New |
Headers | show |
Series | multifd: Add colo support | expand |
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 --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 */
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(-)