aboutsummaryrefslogtreecommitdiff
path: root/migration/ram.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-03-25 18:15:43 +0000
committerPeter Maydell <peter.maydell@linaro.org>2019-03-25 18:15:43 +0000
commit7e9a2137ce3bdae00cb864b5f14d7880aa699ad0 (patch)
tree0dadc2a74d588ab9eac1aa8f25b37c92615c15c9 /migration/ram.c
parentd132baa05ed7a647067c807fd452ec794cc2ecb7 (diff)
parentc38c1c142e64901b09f5ac000695071ed8c0e3a5 (diff)
downloadqemu-7e9a2137ce3bdae00cb864b5f14d7880aa699ad0.zip
qemu-7e9a2137ce3bdae00cb864b5f14d7880aa699ad0.tar.gz
qemu-7e9a2137ce3bdae00cb864b5f14d7880aa699ad0.tar.bz2
Merge remote-tracking branch 'remotes/juanquintela/tags/migration-pull-request' into staging
Pull request - Rebase last pull request - Drop multifd - several other minor fixesLaLaLa # gpg: Signature made Mon 25 Mar 2019 17:46:29 GMT # gpg: using RSA key F487EF185872D723 # gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full] # gpg: aka "Juan Quintela <quintela@trasno.org>" [full] # Primary key fingerprint: 1899 FF8E DEBF 58CC EE03 4B82 F487 EF18 5872 D723 * remotes/juanquintela/tags/migration-pull-request: migration/postcopy: Update the bandwidth during postcopy Migration/colo.c: Make user obtain the last COLO mode info after failover Migration/colo.c: Add the necessary checks for colo_do_failover Migration/colo.c: Add new COLOExitReason to handle all failover state Migration/colo.c: Fix COLO failover status error migration/rdma: Check qemu_rdma_init_one_block migration: add support for a "tls-authz" migration parameter multifd: Drop x- multifd: Add some padding multifd: Change default packet size multifd: Be flexible about packet size multifd: Drop x-multifd-page-count parameter multifd: Create new next_packet_size field multifd: Rename "size" member to pages_alloc multifd: Only send pages when packet are not empty Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'migration/ram.c')
-rw-r--r--migration/ram.c82
1 files changed, 60 insertions, 22 deletions
diff --git a/migration/ram.c b/migration/ram.c
index 35bd621..d7f8fe4 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -583,20 +583,29 @@ exit:
#define MULTIFD_FLAG_SYNC (1 << 0)
+/* This value needs to be a multiple of qemu_target_page_size() */
+#define MULTIFD_PACKET_SIZE (512 * 1024)
+
typedef struct {
uint32_t magic;
uint32_t version;
unsigned char uuid[16]; /* QemuUUID */
uint8_t id;
+ uint8_t unused1[7]; /* Reserved for future use */
+ uint64_t unused2[4]; /* Reserved for future use */
} __attribute__((packed)) MultiFDInit_t;
typedef struct {
uint32_t magic;
uint32_t version;
uint32_t flags;
- uint32_t size;
- uint32_t used;
+ /* maximum number of allocated pages */
+ uint32_t pages_alloc;
+ uint32_t pages_used;
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
uint64_t packet_num;
+ uint64_t unused[4]; /* Reserved for future use */
char ramblock[256];
uint64_t offset[];
} __attribute__((packed)) MultiFDPacket_t;
@@ -643,6 +652,8 @@ typedef struct {
MultiFDPacket_t *packet;
/* multifd flags for each packet */
uint32_t flags;
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
/* global number of generated multifd packets */
uint64_t packet_num;
/* thread local variables */
@@ -679,6 +690,8 @@ typedef struct {
/* global number of generated multifd packets */
uint64_t packet_num;
/* thread local variables */
+ /* size of the next packet that contains pages */
+ uint32_t next_packet_size;
/* packets sent through this channel */
uint64_t num_packets;
/* pages sent through this channel */
@@ -776,13 +789,15 @@ static void multifd_pages_clear(MultiFDPages_t *pages)
static void multifd_send_fill_packet(MultiFDSendParams *p)
{
MultiFDPacket_t *packet = p->packet;
+ uint32_t page_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
int i;
packet->magic = cpu_to_be32(MULTIFD_MAGIC);
packet->version = cpu_to_be32(MULTIFD_VERSION);
packet->flags = cpu_to_be32(p->flags);
- packet->size = cpu_to_be32(migrate_multifd_page_count());
- packet->used = cpu_to_be32(p->pages->used);
+ packet->pages_alloc = cpu_to_be32(page_max);
+ packet->pages_used = cpu_to_be32(p->pages->used);
+ packet->next_packet_size = cpu_to_be32(p->next_packet_size);
packet->packet_num = cpu_to_be64(p->packet_num);
if (p->pages->block) {
@@ -797,6 +812,7 @@ static void multifd_send_fill_packet(MultiFDSendParams *p)
static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
{
MultiFDPacket_t *packet = p->packet;
+ uint32_t pages_max = MULTIFD_PACKET_SIZE / qemu_target_page_size();
RAMBlock *block;
int i;
@@ -818,22 +834,35 @@ static int multifd_recv_unfill_packet(MultiFDRecvParams *p, Error **errp)
p->flags = be32_to_cpu(packet->flags);
- packet->size = be32_to_cpu(packet->size);
- if (packet->size > migrate_multifd_page_count()) {
+ packet->pages_alloc = be32_to_cpu(packet->pages_alloc);
+ /*
+ * If we recevied a packet that is 100 times bigger than expected
+ * just stop migration. It is a magic number.
+ */
+ if (packet->pages_alloc > pages_max * 100) {
error_setg(errp, "multifd: received packet "
- "with size %d and expected maximum size %d",
- packet->size, migrate_multifd_page_count()) ;
+ "with size %d and expected a maximum size of %d",
+ packet->pages_alloc, pages_max * 100) ;
return -1;
}
+ /*
+ * We received a packet that is bigger than expected but inside
+ * reasonable limits (see previous comment). Just reallocate.
+ */
+ if (packet->pages_alloc > p->pages->allocated) {
+ multifd_pages_clear(p->pages);
+ multifd_pages_init(packet->pages_alloc);
+ }
- p->pages->used = be32_to_cpu(packet->used);
- if (p->pages->used > packet->size) {
+ p->pages->used = be32_to_cpu(packet->pages_used);
+ if (p->pages->used > packet->pages_alloc) {
error_setg(errp, "multifd: received packet "
- "with size %d and expected maximum size %d",
- p->pages->used, packet->size) ;
+ "with %d pages and expected maximum pages are %d",
+ p->pages->used, packet->pages_alloc) ;
return -1;
}
+ p->next_packet_size = be32_to_cpu(packet->next_packet_size);
p->packet_num = be64_to_cpu(packet->packet_num);
if (p->pages->used) {
@@ -1073,6 +1102,7 @@ static void *multifd_send_thread(void *opaque)
uint64_t packet_num = p->packet_num;
uint32_t flags = p->flags;
+ p->next_packet_size = used * qemu_target_page_size();
multifd_send_fill_packet(p);
p->flags = 0;
p->num_packets++;
@@ -1080,7 +1110,8 @@ static void *multifd_send_thread(void *opaque)
p->pages->used = 0;
qemu_mutex_unlock(&p->mutex);
- trace_multifd_send(p->id, packet_num, used, flags);
+ trace_multifd_send(p->id, packet_num, used, flags,
+ p->next_packet_size);
ret = qio_channel_write_all(p->c, (void *)p->packet,
p->packet_len, &local_err);
@@ -1088,9 +1119,12 @@ static void *multifd_send_thread(void *opaque)
break;
}
- ret = qio_channel_writev_all(p->c, p->pages->iov, used, &local_err);
- if (ret != 0) {
- break;
+ if (used) {
+ ret = qio_channel_writev_all(p->c, p->pages->iov,
+ used, &local_err);
+ if (ret != 0) {
+ break;
+ }
}
qemu_mutex_lock(&p->mutex);
@@ -1148,7 +1182,7 @@ static void multifd_new_send_channel_async(QIOTask *task, gpointer opaque)
int multifd_save_setup(void)
{
int thread_count;
- uint32_t page_count = migrate_multifd_page_count();
+ uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
uint8_t i;
if (!migrate_use_multifd()) {
@@ -1312,14 +1346,18 @@ static void *multifd_recv_thread(void *opaque)
used = p->pages->used;
flags = p->flags;
- trace_multifd_recv(p->id, p->packet_num, used, flags);
+ trace_multifd_recv(p->id, p->packet_num, used, flags,
+ p->next_packet_size);
p->num_packets++;
p->num_pages += used;
qemu_mutex_unlock(&p->mutex);
- ret = qio_channel_readv_all(p->c, p->pages->iov, used, &local_err);
- if (ret != 0) {
- break;
+ if (used) {
+ ret = qio_channel_readv_all(p->c, p->pages->iov,
+ used, &local_err);
+ if (ret != 0) {
+ break;
+ }
}
if (flags & MULTIFD_FLAG_SYNC) {
@@ -1344,7 +1382,7 @@ static void *multifd_recv_thread(void *opaque)
int multifd_load_setup(void)
{
int thread_count;
- uint32_t page_count = migrate_multifd_page_count();
+ uint32_t page_count = MULTIFD_PACKET_SIZE / qemu_target_page_size();
uint8_t i;
if (!migrate_use_multifd()) {