117 lines
3.4 KiB
Diff
117 lines
3.4 KiB
Diff
From: Olaf Hering <olaf@aepfle.de>
|
|
Date: Fri, 23 Oct 2020 15:39:59 +0200
|
|
Subject: libxc sr save show_transfer_rate
|
|
|
|
tools: show migration transfer rate in send_dirty_pages
|
|
|
|
Show how fast domU pages are transferred in each iteration.
|
|
|
|
The relevant data is how fast the pfns travel, not so much how much
|
|
protocol overhead exists. So the reported MiB/sec is just for pfns.
|
|
|
|
Signed-off-by: Olaf Hering <olaf@aepfle.de>
|
|
|
|
v02:
|
|
- rearrange MiB_sec calculation (jgross)
|
|
---
|
|
tools/libs/guest/xg_sr_common.h | 2 ++
|
|
tools/libs/guest/xg_sr_save.c | 46 +++++++++++++++++++++++++++++++++
|
|
2 files changed, 48 insertions(+)
|
|
|
|
--- a/tools/libs/guest/xg_sr_common.h
|
|
+++ b/tools/libs/guest/xg_sr_common.h
|
|
@@ -238,6 +238,8 @@ struct xc_sr_context
|
|
bool debug;
|
|
|
|
unsigned long p2m_size;
|
|
+ size_t pages_sent;
|
|
+ size_t overhead_sent;
|
|
|
|
struct precopy_stats stats;
|
|
|
|
--- a/tools/libs/guest/xg_sr_save.c
|
|
+++ b/tools/libs/guest/xg_sr_save.c
|
|
@@ -1,5 +1,6 @@
|
|
#include <assert.h>
|
|
#include <arpa/inet.h>
|
|
+#include <time.h>
|
|
|
|
#include "xg_sr_common.h"
|
|
|
|
@@ -238,6 +239,8 @@ static int write_batch(struct xc_sr_cont
|
|
iov[3].iov_len = nr_pfns * sizeof(*rec_pfns);
|
|
|
|
iovcnt = 4;
|
|
+ ctx->save.pages_sent += nr_pages;
|
|
+ ctx->save.overhead_sent += sizeof(rec) + sizeof(hdr) + nr_pfns * sizeof(*rec_pfns);
|
|
|
|
if ( nr_pages )
|
|
{
|
|
@@ -356,6 +359,42 @@ static int suspend_domain(struct xc_sr_c
|
|
return 0;
|
|
}
|
|
|
|
+static void show_transfer_rate(struct xc_sr_context *ctx, struct timespec *start)
|
|
+{
|
|
+ xc_interface *xch = ctx->xch;
|
|
+ struct timespec end = {}, diff = {};
|
|
+ size_t ms, MiB_sec;
|
|
+
|
|
+ if (!ctx->save.pages_sent)
|
|
+ return;
|
|
+
|
|
+ if ( clock_gettime(CLOCK_MONOTONIC, &end) )
|
|
+ PERROR("clock_gettime");
|
|
+
|
|
+ if ( (end.tv_nsec - start->tv_nsec) < 0 )
|
|
+ {
|
|
+ diff.tv_sec = end.tv_sec - start->tv_sec - 1;
|
|
+ diff.tv_nsec = end.tv_nsec - start->tv_nsec + (1000U*1000U*1000U);
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ diff.tv_sec = end.tv_sec - start->tv_sec;
|
|
+ diff.tv_nsec = end.tv_nsec - start->tv_nsec;
|
|
+ }
|
|
+
|
|
+ ms = (diff.tv_nsec / (1000U*1000U));
|
|
+ ms += (diff.tv_sec * 1000U);
|
|
+ if (!ms)
|
|
+ ms = 1;
|
|
+
|
|
+ MiB_sec = (ctx->save.pages_sent * PAGE_SIZE * 1000U) / ms / (1024U*1024U);
|
|
+
|
|
+ errno = 0;
|
|
+ IPRINTF("%s: %zu bytes + %zu pages in %ld.%09ld sec, %zu MiB/sec", __func__,
|
|
+ ctx->save.overhead_sent, ctx->save.pages_sent,
|
|
+ diff.tv_sec, diff.tv_nsec, MiB_sec);
|
|
+}
|
|
+
|
|
/*
|
|
* Send a subset of pages in the guests p2m, according to the dirty bitmap.
|
|
* Used for each subsequent iteration of the live migration loop.
|
|
@@ -369,9 +408,15 @@ static int send_dirty_pages(struct xc_sr
|
|
xen_pfn_t p;
|
|
unsigned long written;
|
|
int rc;
|
|
+ struct timespec start = {};
|
|
DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap,
|
|
&ctx->save.dirty_bitmap_hbuf);
|
|
|
|
+ ctx->save.pages_sent = 0;
|
|
+ ctx->save.overhead_sent = 0;
|
|
+ if ( clock_gettime(CLOCK_MONOTONIC, &start) )
|
|
+ PERROR("clock_gettime");
|
|
+
|
|
for ( p = 0, written = 0; p < ctx->save.p2m_size; ++p )
|
|
{
|
|
if ( !test_bit(p, dirty_bitmap) )
|
|
@@ -395,6 +440,7 @@ static int send_dirty_pages(struct xc_sr
|
|
if ( written > entries )
|
|
DPRINTF("Bitmap contained more entries than expected...");
|
|
|
|
+ show_transfer_rate(ctx, &start);
|
|
xc_report_progress_step(xch, entries, entries);
|
|
|
|
return ctx->save.ops.check_vm_state(ctx);
|