aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-11-04 00:47:37 -0400
committerRichard Henderson <richard.henderson@linaro.org>2021-11-04 00:47:37 -0400
commit752e235464d62d31f14a9790b4b24e396c86bb0e (patch)
tree50a3142b43bbf9d14d4a3210ef303458876efc9d
parentb1fd92137e4d485adeec8e9f292f928ff335b76c (diff)
parent64153ca613d0a50d1301eae4bd895aade001fcca (diff)
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>
-rw-r--r--migration/colo.c16
-rw-r--r--migration/migration.c18
-rw-r--r--migration/migration.h2
-rw-r--r--migration/ram.c9
-rw-r--r--migration/savevm.c1
-rw-r--r--net/colo-compare.c4
-rw-r--r--net/colo.c31
-rw-r--r--net/colo.h6
-rw-r--r--net/filter-rewriter.c10
9 files changed, 45 insertions, 52 deletions
diff --git a/migration/colo.c b/migration/colo.c
index 79fa1f6619..e3b1f136f4 100644
--- a/migration/colo.c
+++ b/migration/colo.c
@@ -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;
diff --git a/migration/migration.c b/migration/migration.c
index 53b9a8af96..abaf6f9e3d 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -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);
diff --git a/migration/migration.h b/migration/migration.h
index 7a5aa8c2fd..8130b703eb 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -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);
diff --git a/migration/ram.c b/migration/ram.c
index 680a5158aa..847af461f2 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -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) {
diff --git a/migration/savevm.c b/migration/savevm.c
index 7b7b64bd13..d59e976d50 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -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();
diff --git a/net/colo-compare.c b/net/colo-compare.c
index b100e7b51f..b8876d7fd9 100644
--- a/net/colo-compare.c
+++ b/net/colo-compare.c
@@ -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,
diff --git a/net/colo.c b/net/colo.c
index 3a3e6e89a0..1f8162f59f 100644
--- a/net/colo.c
+++ b/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)
diff --git a/net/colo.h b/net/colo.h
index d91cd245c4..8b3e8d5a83 100644
--- a/net/colo.h
+++ b/net/colo.h
@@ -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,
diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c
index cb3a96cde1..bf05023dc3 100644
--- a/net/filter-rewriter.c
+++ b/net/filter-rewriter.c
@@ -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 &&