mirror of https://gitee.com/openkylin/qemu.git
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:
commit
752e235464
|
@ -152,7 +152,7 @@ static void primary_vm_do_failover(void)
|
|||
* kick COLO thread which might wait at
|
||||
* 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(),
|
||||
|
@ -205,7 +205,7 @@ void colo_do_failover(void)
|
|||
vm_stop_force_state(RUN_STATE_COLO);
|
||||
}
|
||||
|
||||
switch (get_colo_mode()) {
|
||||
switch (last_colo_mode = get_colo_mode()) {
|
||||
case COLO_MODE_PRIMARY:
|
||||
primary_vm_do_failover();
|
||||
break;
|
||||
|
@ -530,8 +530,7 @@ static void colo_process_checkpoint(MigrationState *s)
|
|||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
last_colo_mode = get_colo_mode();
|
||||
if (last_colo_mode != COLO_MODE_PRIMARY) {
|
||||
if (get_colo_mode() != COLO_MODE_PRIMARY) {
|
||||
error_report("COLO mode must be COLO_MODE_PRIMARY");
|
||||
return;
|
||||
}
|
||||
|
@ -640,6 +639,7 @@ out:
|
|||
*/
|
||||
if (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,
|
||||
MIGRATION_STATUS_COLO);
|
||||
|
||||
last_colo_mode = get_colo_mode();
|
||||
if (last_colo_mode != COLO_MODE_SECONDARY) {
|
||||
if (get_colo_mode() != COLO_MODE_SECONDARY) {
|
||||
error_report("COLO mode must be COLO_MODE_SECONDARY");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -918,11 +917,6 @@ out:
|
|||
/* Hope this not to be too long to loop here */
|
||||
qemu_sem_wait(&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();
|
||||
return NULL;
|
||||
|
|
|
@ -215,8 +215,11 @@ void migration_object_init(void)
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -226,7 +229,7 @@ void migration_shutdown(void)
|
|||
* Cancel the current migration - that will (eventually)
|
||||
* stop the migration using this structure
|
||||
*/
|
||||
migration_cancel();
|
||||
migration_cancel(NULL);
|
||||
object_unref(OBJECT(current_migration));
|
||||
|
||||
/*
|
||||
|
@ -587,8 +590,10 @@ static void process_incoming_migration_co(void *opaque)
|
|||
mis->have_colo_incoming_thread = true;
|
||||
qemu_coroutine_yield();
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
/* Wait checkpoint incoming thread exit before free resource */
|
||||
qemu_thread_join(&mis->colo_incoming_thread);
|
||||
qemu_mutex_lock_iothread();
|
||||
/* We hold the global iothread lock, so it is safe here */
|
||||
colo_release_ram_cache();
|
||||
}
|
||||
|
@ -2268,10 +2273,11 @@ static bool migrate_prepare(MigrationState *s, bool blk, bool blk_inc,
|
|||
|
||||
migrate_init(s);
|
||||
/*
|
||||
* set ram_counters memory to zero for a
|
||||
* set ram_counters compression_counters memory to zero for a
|
||||
* new migration
|
||||
*/
|
||||
memset(&ram_counters, 0, sizeof(ram_counters));
|
||||
memset(&compression_counters, 0, sizeof(compression_counters));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -2334,7 +2340,7 @@ void qmp_migrate(const char *uri, bool has_blk, bool blk,
|
|||
|
||||
void qmp_migrate_cancel(Error **errp)
|
||||
{
|
||||
migration_cancel();
|
||||
migration_cancel(NULL);
|
||||
}
|
||||
|
||||
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_CANCELLING:
|
||||
if (s->vm_was_running) {
|
||||
vm_start();
|
||||
if (!runstate_check(RUN_STATE_SHUTDOWN)) {
|
||||
vm_start();
|
||||
}
|
||||
} else {
|
||||
if (runstate_check(RUN_STATE_FINISH_MIGRATE)) {
|
||||
runstate_set(RUN_STATE_POSTMIGRATE);
|
||||
|
|
|
@ -388,7 +388,7 @@ int foreach_not_ignored_block(RAMBlockIterFunc func, void *opaque);
|
|||
void migration_make_urgent_request(void);
|
||||
void migration_consume_urgent_request(void);
|
||||
bool migration_rate_limit(void);
|
||||
void migration_cancel(void);
|
||||
void migration_cancel(const Error *error);
|
||||
|
||||
void populate_vfio_info(MigrationInfo *info);
|
||||
|
||||
|
|
|
@ -56,6 +56,8 @@
|
|||
#include "multifd.h"
|
||||
#include "sysemu/runstate.h"
|
||||
|
||||
#include "hw/boards.h" /* for machine_dump_guest_core() */
|
||||
|
||||
#if defined(__linux__)
|
||||
#include "qemu/userfaultfd.h"
|
||||
#endif /* defined(__linux__) */
|
||||
|
@ -3542,6 +3544,10 @@ int colo_init_ram_cache(void)
|
|||
}
|
||||
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.
|
||||
*/
|
||||
error_setg(&err, "RAM block '%s' resized during precopy.", rb->idstr);
|
||||
migrate_set_error(migrate_get_current(), err);
|
||||
migration_cancel(err);
|
||||
error_free(err);
|
||||
migration_cancel();
|
||||
}
|
||||
|
||||
switch (ps) {
|
||||
|
|
|
@ -1567,6 +1567,7 @@ static int qemu_savevm_state(QEMUFile *f, Error **errp)
|
|||
|
||||
migrate_init(ms);
|
||||
memset(&ram_counters, 0, sizeof(ram_counters));
|
||||
memset(&compression_counters, 0, sizeof(compression_counters));
|
||||
ms->to_dst_file = f;
|
||||
|
||||
qemu_mutex_unlock_iothread();
|
||||
|
|
|
@ -170,7 +170,7 @@ static bool packet_matches_str(const char *str,
|
|||
return false;
|
||||
}
|
||||
|
||||
return !memcmp(str, buf, strlen(str));
|
||||
return !memcmp(str, buf, packet_len);
|
||||
}
|
||||
|
||||
static void notify_remote_frame(CompareState *s)
|
||||
|
@ -264,7 +264,7 @@ static int packet_enqueue(CompareState *s, int mode, Connection **con)
|
|||
pkt = NULL;
|
||||
return -1;
|
||||
}
|
||||
fill_connection_key(pkt, &key);
|
||||
fill_connection_key(pkt, &key, false);
|
||||
|
||||
conn = connection_get(s->connection_track_table,
|
||||
&key,
|
||||
|
|
31
net/colo.c
31
net/colo.c
|
@ -83,19 +83,26 @@ int parse_packet_early(Packet *pkt)
|
|||
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->dst = pkt->ip->ip_dst;
|
||||
key->src_port = ntohs(tmp_ports >> 16);
|
||||
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;
|
||||
|
||||
switch (key->ip_proto) {
|
||||
|
@ -106,29 +113,15 @@ void fill_connection_key(Packet *pkt, ConnectionKey *key)
|
|||
case IPPROTO_SCTP:
|
||||
case IPPROTO_UDPLITE:
|
||||
tmp_ports = *(uint32_t *)(pkt->transport_header);
|
||||
extract_ip_and_port(tmp_ports, key, pkt);
|
||||
break;
|
||||
case IPPROTO_AH:
|
||||
tmp_ports = *(uint32_t *)(pkt->transport_header + 4);
|
||||
extract_ip_and_port(tmp_ports, key, pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void reverse_connection_key(ConnectionKey *key)
|
||||
{
|
||||
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;
|
||||
extract_ip_and_port(tmp_ports, key, pkt, reverse);
|
||||
}
|
||||
|
||||
Connection *connection_new(ConnectionKey *key)
|
||||
|
|
|
@ -89,9 +89,9 @@ typedef struct Connection {
|
|||
uint32_t connection_key_hash(const void *opaque);
|
||||
int connection_key_equal(const void *opaque1, const void *opaque2);
|
||||
int parse_packet_early(Packet *pkt);
|
||||
void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key, Packet *pkt);
|
||||
void fill_connection_key(Packet *pkt, ConnectionKey *key);
|
||||
void reverse_connection_key(ConnectionKey *key);
|
||||
void extract_ip_and_port(uint32_t tmp_ports, ConnectionKey *key,
|
||||
Packet *pkt, bool reverse);
|
||||
void fill_connection_key(Packet *pkt, ConnectionKey *key, bool reverse);
|
||||
Connection *connection_new(ConnectionKey *key);
|
||||
void connection_destroy(void *opaque);
|
||||
Connection *connection_get(GHashTable *connection_track_table,
|
||||
|
|
|
@ -279,15 +279,7 @@ static ssize_t colo_rewriter_receive_iov(NetFilterState *nf,
|
|||
*/
|
||||
if (pkt && is_tcp_packet(pkt)) {
|
||||
|
||||
fill_connection_key(pkt, &key);
|
||||
|
||||
if (sender == nf->netdev) {
|
||||
/*
|
||||
* We need make tcp TX and RX packet
|
||||
* into one connection.
|
||||
*/
|
||||
reverse_connection_key(&key);
|
||||
}
|
||||
fill_connection_key(pkt, &key, sender == nf->netdev);
|
||||
|
||||
/* After failover we needn't change new TCP packet */
|
||||
if (s->failover_mode &&
|
||||
|
|
Loading…
Reference in New Issue