Migration Pull request

Hi
 
 This are the pending migration patches on the list:
 - Provide an error message for migration_cancel by Laurent
 - Don't dump colo cache when a guest core is requested by Lukas
 - Initialise Compression_conters for new migration by Yuxiating
   On top of that I added another missing initialization
 - Colo optimizations and crash improvements by Rao.
 
 Please, apply.
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEGJn/jt6/WMzuA0uC9IfvGFhy1yMFAmGCTC8ACgkQ9IfvGFhy
 1yMz3A//YNORIjbnvV9zhJPIBWBXf9vo/Cdzh8RshI7QyuW/a61poM3/yxwErTRG
 IFJagmwVvCm7lXqvNBY2XDLkS0DURZmCC6HiUTnomgCOSpLgpLwkJTYqsQRVel4Q
 Ow1CuEhmIa/XWKxvhUS2KfQx3iy4pK+5Z+DmamW/VnakqoviGvLkwvgALAA6bP0l
 1Ddbg6i9BRLJM5Jeo1UJRmDJfldJTr4k962lrX4VRBKqxv/PQRLuVkALXfBCjmY8
 uqiPPfDlVx7XE2ralyMmP5qgvJT88jGeNDcpuCWAKxh3OsKwPtm3qWXkEvP7uuDj
 6FfWulUT7QNduU1DWnmQUwvz1lRX16EhjDDgRyvgVv1Vn21z+8C751bLlLR0M+rt
 Ip2PZfv3cgOLhUpyY3+jf0uTGFVb9q4kYijvAOoOcFPuLbL1u1N+ljDz5vB/OzuR
 qxIajFq9uvR9uBP8JL8WIkDQa5laPdwPyLhuMMvNfmUsUoSlgV1r8hwqUfLUr6SN
 vaCUWHAwmik8BiLAurlahsxoc76v6tRga6OTYJxOon7MrKcxab0BO5ndTfMRLncN
 cffxdh1R6D1jb4uYR0f5+HI0nl86IlS2ReE+pd1mPA3xyv3ZyUzP4txJkV8k/eHs
 6hVG6ia5MJLcvlfZyNatAgmK4Y3L98+JiaBIkUoLibu2tu/DsEg=
 =msYG
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/juanquintela/tags/migration-20211102-pull-request' into staging

Migration Pull request

Hi

This are the pending migration patches on the list:
- Provide an error message for migration_cancel by Laurent
- Don't dump colo cache when a guest core is requested by Lukas
- Initialise Compression_conters for new migration by Yuxiating
  On top of that I added another missing initialization
- Colo optimizations and crash improvements by Rao.

Please, apply.

# gpg: Signature made Wed 03 Nov 2021 04:45:35 AM EDT
# gpg:                using RSA key 1899FF8EDEBF58CCEE034B82F487EF185872D723
# gpg: Good signature from "Juan Quintela <quintela@redhat.com>" [full]
# gpg:                 aka "Juan Quintela <quintela@trasno.org>" [full]

* remotes/juanquintela/tags/migration-20211102-pull-request:
  Optimized the function of fill_connection_key.
  colo: Don't dump colo cache if dump-guest-core=off
  Changed the last-mode to none of first start COLO
  Removed the qemu_fclose() in colo_process_incoming_thread
  colo: fixed 'Segmentation fault' when the simplex mode PVM poweroff
  Fixed SVM hang when do failover before PVM crash
  Fixed qemu crash when guest power off in COLO mode
  Some minor optimizations for COLO
  migration: Zero migration compression counters
  migration: initialise compression_counters for a new migration
  migration: provide an error message to migration_cancel()

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2021-11-04 00:47:37 -04:00
commit 752e235464
9 changed files with 45 additions and 52 deletions

View File

@ -152,7 +152,7 @@ static void primary_vm_do_failover(void)
* kick COLO thread which might wait at * kick COLO thread which might wait at
* qemu_sem_wait(&s->colo_checkpoint_sem). * qemu_sem_wait(&s->colo_checkpoint_sem).
*/ */
colo_checkpoint_notify(migrate_get_current()); colo_checkpoint_notify(s);
/* /*
* Wake up COLO thread which may blocked in recv() or send(), * Wake up COLO thread which may blocked in recv() or send(),
@ -205,7 +205,7 @@ void colo_do_failover(void)
vm_stop_force_state(RUN_STATE_COLO); vm_stop_force_state(RUN_STATE_COLO);
} }
switch (get_colo_mode()) { switch (last_colo_mode = get_colo_mode()) {
case COLO_MODE_PRIMARY: case COLO_MODE_PRIMARY:
primary_vm_do_failover(); primary_vm_do_failover();
break; break;
@ -530,8 +530,7 @@ static void colo_process_checkpoint(MigrationState *s)
Error *local_err = NULL; Error *local_err = NULL;
int ret; int ret;
last_colo_mode = get_colo_mode(); if (get_colo_mode() != COLO_MODE_PRIMARY) {
if (last_colo_mode != COLO_MODE_PRIMARY) {
error_report("COLO mode must be COLO_MODE_PRIMARY"); error_report("COLO mode must be COLO_MODE_PRIMARY");
return; return;
} }
@ -640,6 +639,7 @@ out:
*/ */
if (s->rp_state.from_dst_file) { if (s->rp_state.from_dst_file) {
qemu_fclose(s->rp_state.from_dst_file); qemu_fclose(s->rp_state.from_dst_file);
s->rp_state.from_dst_file = NULL;
} }
} }
@ -829,8 +829,7 @@ void *colo_process_incoming_thread(void *opaque)
migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE, migrate_set_state(&mis->state, MIGRATION_STATUS_ACTIVE,
MIGRATION_STATUS_COLO); MIGRATION_STATUS_COLO);
last_colo_mode = get_colo_mode(); if (get_colo_mode() != COLO_MODE_SECONDARY) {
if (last_colo_mode != COLO_MODE_SECONDARY) {
error_report("COLO mode must be COLO_MODE_SECONDARY"); error_report("COLO mode must be COLO_MODE_SECONDARY");
return NULL; return NULL;
} }
@ -918,11 +917,6 @@ out:
/* Hope this not to be too long to loop here */ /* Hope this not to be too long to loop here */
qemu_sem_wait(&mis->colo_incoming_sem); qemu_sem_wait(&mis->colo_incoming_sem);
qemu_sem_destroy(&mis->colo_incoming_sem); qemu_sem_destroy(&mis->colo_incoming_sem);
/* Must be called after failover BH is completed */
if (mis->to_src_file) {
qemu_fclose(mis->to_src_file);
mis->to_src_file = NULL;
}
rcu_unregister_thread(); rcu_unregister_thread();
return NULL; return NULL;

View File

@ -215,8 +215,11 @@ void migration_object_init(void)
dirty_bitmap_mig_init(); dirty_bitmap_mig_init();
} }
void migration_cancel(void) void migration_cancel(const Error *error)
{ {
if (error) {
migrate_set_error(current_migration, error);
}
migrate_fd_cancel(current_migration); migrate_fd_cancel(current_migration);
} }
@ -226,7 +229,7 @@ void migration_shutdown(void)
* Cancel the current migration - that will (eventually) * Cancel the current migration - that will (eventually)
* stop the migration using this structure * stop the migration using this structure
*/ */
migration_cancel(); migration_cancel(NULL);
object_unref(OBJECT(current_migration)); object_unref(OBJECT(current_migration));
/* /*
@ -587,8 +590,10 @@ static void process_incoming_migration_co(void *opaque)
mis->have_colo_incoming_thread = true; mis->have_colo_incoming_thread = true;
qemu_coroutine_yield(); qemu_coroutine_yield();
qemu_mutex_unlock_iothread();
/* Wait checkpoint incoming thread exit before free resource */ /* Wait checkpoint incoming thread exit before free resource */
qemu_thread_join(&mis->colo_incoming_thread); qemu_thread_join(&mis->colo_incoming_thread);
qemu_mutex_lock_iothread();
/* We hold the global iothread lock, so it is safe here */ /* We hold the global iothread lock, so it is safe here */
colo_release_ram_cache(); colo_release_ram_cache();
} }
@ -2268,10 +2273,11 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
migrate_init(s); migrate_init(s);
/* /*
* set ram_counters memory to zero for a * set ram_counters compression_counters memory to zero for a
* new migration * new migration
*/ */
memset(&ram_counters, 0, sizeof(ram_counters)); memset(&ram_counters, 0, sizeof(ram_counters));
memset(&compression_counters, 0, sizeof(compression_counters));
return true; return true;
} }
@ -2334,7 +2340,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
void qmp_migrate_cancel(Error **errp) void qmp_migrate_cancel(Error **errp)
{ {
migration_cancel(); migration_cancel(NULL);
} }
void qmp_migrate_continue(MigrationStatus state, Error **errp) void qmp_migrate_continue(MigrationStatus state, Error **errp)
@ -3622,7 +3628,9 @@ static void migration_iteration_finish(MigrationState *s)
case MIGRATION_STATUS_CANCELLED: case MIGRATION_STATUS_CANCELLED:
case MIGRATION_STATUS_CANCELLING: case MIGRATION_STATUS_CANCELLING:
if (s->vm_was_running) { if (s->vm_was_running) {
vm_start(); if (!runstate_check(RUN_STATE_SHUTDOWN)) {
vm_start();
}
} else { } else {
if (runstate_check(RUN_STATE_FINISH_MIGRATE)) { if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
runstate_set(RUN_STATE_POSTMIGRATE); runstate_set(RUN_STATE_POSTMIGRATE);

View File

@ -388,7 +388,7 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
void migration_make_urgent_request(void); void migration_make_urgent_request(void);
void migration_consume_urgent_request(void); void migration_consume_urgent_request(void);
bool migration_rate_limit(void); bool migration_rate_limit(void);
void migration_cancel(void); void migration_cancel(const Error *error);
void populate_vfio_info(MigrationInfo *info); void populate_vfio_info(MigrationInfo *info);

View File

@ -56,6 +56,8 @@
#include "multifd.h" #include "multifd.h"
#include "sysemu/runstate.h" #include "sysemu/runstate.h"
#include "hw/boards.h" /* for machine_dump_guest_core() */
#if defined(__linux__) #if defined(__linux__)
#include "qemu/userfaultfd.h" #include "qemu/userfaultfd.h"
#endif /* defined(__linux__) */ #endif /* defined(__linux__) */
@ -3542,6 +3544,10 @@ int colo_init_ram_cache(void)
} }
return -errno; return -errno;
} }
if (!machine_dump_guest_core(current_machine)) {
qemu_madvise(block->colo_cache, block->used_length,
QEMU_MADV_DONTDUMP);
}
} }
} }
@ -4323,9 +4329,8 @@ static void ram_mig_ram_block_resized(RAMBlockNotifier *n, void *host,
* Abort and indicate a proper reason. * Abort and indicate a proper reason.
*/ */
error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr); error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr);
migrate_set_error(migrate_get_current(), err); migration_cancel(err);
error_free(err); error_free(err);
migration_cancel();
} }
switch (ps) { switch (ps) {

View File

@ -1567,6 +1567,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
migrate_init(ms); migrate_init(ms);
memset(&ram_counters, 0, sizeof(ram_counters)); memset(&ram_counters, 0, sizeof(ram_counters));
memset(&compression_counters, 0, sizeof(compression_counters));
ms->to_dst_file = f; ms->to_dst_file = f;
qemu_mutex_unlock_iothread(); qemu_mutex_unlock_iothread();

View File

@ -170,7 +170,7 @@ static bool packet_matches_str(const char *str,
return false; return false;
} }
return !memcmp(str, buf, strlen(str)); return !memcmp(str, buf, packet_len);
} }
static void notify_remote_frame(CompareState *s) static void notify_remote_frame(CompareState *s)
@ -264,7 +264,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
pkt = NULL; pkt = NULL;
return -1; return -1;
} }
fill_connection_key(pkt, &key); fill_connection_key(pkt, &key, false);
conn = connection_get(s->connection_track_table, conn = connection_get(s->connection_track_table,
&key, &key,

View File

@ -83,19 +83,26 @@ int parse_packet_early(Packet *pkt)
return 0; return 0;
} }
void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, Packet *pkt) void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key,
Packet *pkt, bool reverse)
{ {
if (reverse) {
key->src = pkt->ip->ip_dst;
key->dst = pkt->ip->ip_src;
key->src_port = ntohs(tmp_ports & 0xffff);
key->dst_port = ntohs(tmp_ports >> 16);
} else {
key->src = pkt->ip->ip_src; key->src = pkt->ip->ip_src;
key->dst = pkt->ip->ip_dst; key->dst = pkt->ip->ip_dst;
key->src_port = ntohs(tmp_ports >> 16); key->src_port = ntohs(tmp_ports >> 16);
key->dst_port = ntohs(tmp_ports & 0xffff); key->dst_port = ntohs(tmp_ports & 0xffff);
}
} }
void fill_connection_key(Packet *pkt, ConnectionKey *key) void fill_connection_key(Packet *pkt, ConnectionKey *key, bool reverse)
{ {
uint32_t tmp_ports; uint32_t tmp_ports = 0;
memset(key, 0, sizeof(*key));
key->ip_proto = pkt->ip->ip_p; key->ip_proto = pkt->ip->ip_p;
switch (key->ip_proto) { switch (key->ip_proto) {
@ -106,29 +113,15 @@ void fill_connection_key(Packet *pkt, ConnectionKey *key)
case IPPROTO_SCTP: case IPPROTO_SCTP:
case IPPROTO_UDPLITE: case IPPROTO_UDPLITE:
tmp_ports = *(uint32_t *)(pkt->transport_header); tmp_ports = *(uint32_t *)(pkt->transport_header);
extract_ip_and_port(tmp_ports, key, pkt);
break; break;
case IPPROTO_AH: case IPPROTO_AH:
tmp_ports = *(uint32_t *)(pkt->transport_header + 4); tmp_ports = *(uint32_t *)(pkt->transport_header + 4);
extract_ip_and_port(tmp_ports, key, pkt);
break; break;
default: default:
break; break;
} }
}
void reverse_connection_key(ConnectionKey *key) extract_ip_and_port(tmp_ports, key, pkt, reverse);
{
struct in_addr tmp_ip;
uint16_t tmp_port;
tmp_ip = key->src;
key->src = key->dst;
key->dst = tmp_ip;
tmp_port = key->src_port;
key->src_port = key->dst_port;
key->dst_port = tmp_port;
} }
Connection *connection_new(ConnectionKey *key) Connection *connection_new(ConnectionKey *key)

View File

@ -89,9 +89,9 @@ typedef struct Connection {
uint32_t connection_key_hash(const void *opaque); uint32_t connection_key_hash(const void *opaque);
int connection_key_equal(const void *opaque1, const void *opaque2); int connection_key_equal(const void *opaque1, const void *opaque2);
int parse_packet_early(Packet *pkt); int parse_packet_early(Packet *pkt);
void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, Packet *pkt); void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key,
void fill_connection_key(Packet *pkt, ConnectionKey *key); Packet *pkt, bool reverse);
void reverse_connection_key(ConnectionKey *key); void fill_connection_key(Packet *pkt, ConnectionKey *key, bool reverse);
Connection *connection_new(ConnectionKey *key); Connection *connection_new(ConnectionKey *key);
void connection_destroy(void *opaque); void connection_destroy(void *opaque);
Connection *connection_get(GHashTable *connection_track_table, Connection *connection_get(GHashTable *connection_track_table,

View File

@ -279,15 +279,7 @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
*/ */
if (pkt && is_tcp_packet(pkt)) { if (pkt && is_tcp_packet(pkt)) {
fill_connection_key(pkt, &key); fill_connection_key(pkt, &key, sender == nf->netdev);
if (sender == nf->netdev) {
/*
* We need make tcp TX and RX packet
* into one connection.
*/
reverse_connection_key(&key);
}
/* After failover we needn't change new TCP packet */ /* After failover we needn't change new TCP packet */
if (s->failover_mode && if (s->failover_mode &&