From: Peter Xu <peterx@redhat.com>
To: qemu-devel@nongnu.org
Cc: Laurent Vivier <lvivier@redhat.com>,
Juan Quintela <quintela@redhat.com>,
"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
peterx@redhat.com
Subject: [Qemu-devel] [PATCH v2 09/13] migration: cleanup stats update into function
Date: Wed, 3 Jan 2018 20:20:13 +0800 [thread overview]
Message-ID: <20180103122017.14794-10-peterx@redhat.com> (raw)
In-Reply-To: <20180103122017.14794-1-peterx@redhat.com>
We have quite a few lines in migration_thread() that calculates some
statistics for the migration interations. Isolate it into a single
function to improve readability.
Signed-off-by: Peter Xu <peterx@redhat.com>
---
migration/migration.c | 86 ++++++++++++++++++++++++++++++---------------------
migration/migration.h | 11 +++++++
2 files changed, 61 insertions(+), 36 deletions(-)
diff --git a/migration/migration.c b/migration/migration.c
index 4dd21f8636..de872801e6 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -1273,6 +1273,8 @@ MigrationState *migrate_init(void)
s->start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
s->total_time = 0;
s->vm_was_running = false;
+ s->iteration_initial_bytes = 0;
+ s->threshold_size = 0;
return s;
}
@@ -2170,6 +2172,43 @@ static void migration_calculate_complete(MigrationState *s)
}
}
+static void migration_update_counters(MigrationState *s,
+ int64_t current_time)
+{
+ uint64_t transferred, time_spent;
+ int64_t threshold_size;
+ double bandwidth;
+
+ if (current_time < s->iteration_start_time + BUFFER_DELAY) {
+ return;
+ }
+
+ transferred = qemu_ftell(s->to_dst_file) - s->iteration_initial_bytes;
+ time_spent = current_time - s->iteration_start_time;
+ bandwidth = (double)transferred / time_spent;
+ threshold_size = bandwidth * s->parameters.downtime_limit;
+
+ s->mbps = (((double) transferred * 8.0) /
+ ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
+
+ /*
+ * if we haven't sent anything, we don't want to
+ * recalculate. 10000 is a small enough number for our purposes
+ */
+ if (ram_counters.dirty_pages_rate && transferred > 10000) {
+ s->expected_downtime = ram_counters.dirty_pages_rate *
+ qemu_target_page_size() / bandwidth;
+ }
+
+ qemu_file_reset_rate_limit(s->to_dst_file);
+
+ s->iteration_start_time = current_time;
+ s->iteration_initial_bytes = qemu_ftell(s->to_dst_file);
+
+ trace_migrate_transferred(transferred, time_spent,
+ bandwidth, threshold_size);
+}
+
/*
* Master migration thread on the source VM.
* It drives the migration and pumps the data down the outgoing channel.
@@ -2177,22 +2216,15 @@ static void migration_calculate_complete(MigrationState *s)
static void *migration_thread(void *opaque)
{
MigrationState *s = opaque;
- /* Used by the bandwidth calcs, updated later */
- int64_t initial_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
int64_t setup_start = qemu_clock_get_ms(QEMU_CLOCK_HOST);
- int64_t initial_bytes = 0;
- /*
- * The final stage happens when the remaining data is smaller than
- * this threshold; it's calculated from the requested downtime and
- * measured bandwidth
- */
- int64_t threshold_size = 0;
bool entered_postcopy = false;
/* The active state we expect to be in; ACTIVE or POSTCOPY_ACTIVE */
enum MigrationStatus current_active_state = MIGRATION_STATUS_ACTIVE;
rcu_register_thread();
+ s->iteration_start_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
+
qemu_savevm_state_header(s->to_dst_file);
/*
@@ -2232,17 +2264,17 @@ static void *migration_thread(void *opaque)
if (!qemu_file_rate_limit(s->to_dst_file)) {
uint64_t pend_post, pend_nonpost;
- qemu_savevm_state_pending(s->to_dst_file, threshold_size,
+ qemu_savevm_state_pending(s->to_dst_file, s->threshold_size,
&pend_nonpost, &pend_post);
pending_size = pend_nonpost + pend_post;
- trace_migrate_pending(pending_size, threshold_size,
+ trace_migrate_pending(pending_size, s->threshold_size,
pend_post, pend_nonpost);
- if (pending_size && pending_size >= threshold_size) {
+ if (pending_size && pending_size >= s->threshold_size) {
/* Still a significant amount to transfer */
if (migrate_postcopy() &&
s->state != MIGRATION_STATUS_POSTCOPY_ACTIVE &&
- pend_nonpost <= threshold_size &&
+ pend_nonpost <= s->threshold_size &&
atomic_read(&s->start_postcopy)) {
if (!postcopy_start(s)) {
@@ -2267,33 +2299,15 @@ static void *migration_thread(void *opaque)
trace_migration_thread_file_err();
break;
}
+
current_time = qemu_clock_get_ms(QEMU_CLOCK_REALTIME);
- if (current_time >= initial_time + BUFFER_DELAY) {
- uint64_t transferred_bytes = qemu_ftell(s->to_dst_file) -
- initial_bytes;
- uint64_t time_spent = current_time - initial_time;
- double bandwidth = (double)transferred_bytes / time_spent;
- threshold_size = bandwidth * s->parameters.downtime_limit;
-
- s->mbps = (((double) transferred_bytes * 8.0) /
- ((double) time_spent / 1000.0)) / 1000.0 / 1000.0;
-
- trace_migrate_transferred(transferred_bytes, time_spent,
- bandwidth, threshold_size);
- /* if we haven't sent anything, we don't want to recalculate
- 10000 is a small enough number for our purposes */
- if (ram_counters.dirty_pages_rate && transferred_bytes > 10000) {
- s->expected_downtime = ram_counters.dirty_pages_rate *
- qemu_target_page_size() / bandwidth;
- }
- qemu_file_reset_rate_limit(s->to_dst_file);
- initial_time = current_time;
- initial_bytes = qemu_ftell(s->to_dst_file);
- }
+ migration_update_counters(s, current_time);
+
if (qemu_file_rate_limit(s->to_dst_file)) {
/* usleep expects microseconds */
- g_usleep((initial_time + BUFFER_DELAY - current_time)*1000);
+ g_usleep((s->iteration_start_time + BUFFER_DELAY -
+ current_time) * 1000);
}
}
diff --git a/migration/migration.h b/migration/migration.h
index 867383f18d..786d971ce2 100644
--- a/migration/migration.h
+++ b/migration/migration.h
@@ -90,6 +90,17 @@ struct MigrationState
QEMUBH *cleanup_bh;
QEMUFile *to_dst_file;
+ /* bytes already send at the beggining of current interation */
+ uint64_t iteration_initial_bytes;
+ /* time at the start of current iteration */
+ int64_t iteration_start_time;
+ /*
+ * The final stage happens when the remaining data is smaller than
+ * this threshold; it's calculated from the requested downtime and
+ * measured bandwidth
+ */
+ int64_t threshold_size;
+
/* params from 'migrate-set-parameters' */
MigrationParameters parameters;
--
2.14.3
next prev parent reply other threads:[~2018-01-03 12:20 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-03 12:20 [Qemu-devel] [PATCH v2 00/13] migration: cleanup migration_thread() Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 01/13] migration: assert colo instead of check Peter Xu
2018-01-03 12:23 ` Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 02/13] migration: qemu_savevm_state_cleanup() in cleanup Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 03/13] migration: remove "enable_colo" var Peter Xu
2018-01-03 12:24 ` Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 04/13] migration: split use of MigrationState.total_time Peter Xu
2018-01-03 12:25 ` Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 05/13] migration: move vm_old_running into global state Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 06/13] migration: introduce downtime_start Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 07/13] migration: introduce migrate_calculate_complete Peter Xu
2018-01-03 12:26 ` Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 08/13] migration: use switch at the end of migration Peter Xu
2018-01-03 12:27 ` Juan Quintela
2018-01-03 12:20 ` Peter Xu [this message]
2018-01-03 12:28 ` [Qemu-devel] [PATCH v2 09/13] migration: cleanup stats update into function Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 10/13] migration: major cleanup for migrate iterations Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 11/13] migration: put the finish part into a new function Peter Xu
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 12/13] migration: remove some block_cleanup_parameters() Peter Xu
2018-01-03 12:29 ` Juan Quintela
2018-01-03 12:20 ` [Qemu-devel] [PATCH v2 13/13] migration: remove notify in fd_error Peter Xu
2018-01-03 12:31 ` Juan Quintela
2018-01-04 2:18 ` Peter Xu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180103122017.14794-10-peterx@redhat.com \
--to=peterx@redhat.com \
--cc=dgilbert@redhat.com \
--cc=lvivier@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=quintela@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.