All of lore.kernel.org
 help / color / mirror / Atom feed
From: Olaf Hering <olaf@aepfle.de>
To: xen-devel@lists.xen.org,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Wei Liu <wei.liu2@citrix.com>
Subject: Re: [PATCH v6 3/3] tools/libxc: use superpages during restore of HVM guest
Date: Tue, 29 Aug 2017 11:58:24 +0200	[thread overview]
Message-ID: <20170829095823.GA9803@aepfle.de> (raw)
In-Reply-To: <20170826103332.24570-4-olaf@aepfle.de>


[-- Attachment #1.1: Type: text/plain, Size: 5795 bytes --]

On Sat, Aug 26, Olaf Hering wrote:

> +static int x86_hvm_populate_pfns(struct xc_sr_context *ctx, unsigned count,

> +    /*
> +     * Scan the entire superpage because several batches will fit into
> +     * a superpage, and it is unknown which pfn triggered the allocation.
> +     */
> +    order = SUPERPAGE_1GB_SHIFT;
> +    pfn = min_pfn = (min_pfn >> order) << order;

Scanning an entire superpage again and again looked expensive, but with
the debug change below it turned out that the loop which peeks at each
single bit in populated_pfns is likely not a bootleneck.

Migrating a domU with a simple workload that touches pages to mark them
dirty will set the min_pfn/max_pfn to a large range anyway after the
first iteration. This large range may also happen with an idle domU. A
small domU takes 78 seconds to migrate, and just the freeing part takes
1.4 seconds. Similar for a large domain, the loop takes 1% of the time.

     78 seconds, 1.4 seconds, 2119 calls  (8GB, 12*512M memdirty)
    695 seconds, 7.6 seconds, 18076 calls (72GB, 12*5G memdirty)

Olaf

    track time spent if decrease_reservation is needed

diff --git a/tools/libxc/xc_sr_common.h b/tools/libxc/xc_sr_common.h
index 0fa0fbea4d..5ec8b6fee6 100644
--- a/tools/libxc/xc_sr_common.h
+++ b/tools/libxc/xc_sr_common.h
@@ -353,6 +353,9 @@ struct xc_sr_context
                     struct xc_sr_bitmap attempted_1g;
                     struct xc_sr_bitmap attempted_2m;
                     struct xc_sr_bitmap allocated_pfns;
+
+                    unsigned long tv_nsec;
+                    unsigned long iterations;
                 } restore;
             };
         } x86_hvm;
diff --git a/tools/libxc/xc_sr_restore.c b/tools/libxc/xc_sr_restore.c
index 8cd9289d1a..f6aad329e2 100644
--- a/tools/libxc/xc_sr_restore.c
+++ b/tools/libxc/xc_sr_restore.c
@@ -769,6 +769,7 @@ int xc_domain_restore(xc_interface *xch, int io_fd, uint32_t dom,
     {
         ctx.restore.ops = restore_ops_x86_hvm;
         if ( restore(&ctx) )
+            ;
             return -1;
     }
     else
diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c
index 2b0eca0c7c..11758b3f7d 100644
--- a/tools/libxc/xc_sr_restore_x86_hvm.c
+++ b/tools/libxc/xc_sr_restore_x86_hvm.c
@@ -1,5 +1,6 @@
 #include <assert.h>
 #include <arpa/inet.h>
+#include <time.h>
 
 #include "xc_sr_common_x86.h"
 
@@ -248,6 +249,12 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx)
 
 static int x86_hvm_cleanup(struct xc_sr_context *ctx)
 {
+    xc_interface *xch = ctx->xch;
+    errno = 0;
+    PERROR("tv_nsec %lu.%lu iterations %lu",
+            ctx->x86_hvm.restore.tv_nsec / 1000000000UL,
+            ctx->x86_hvm.restore.tv_nsec % 1000000000UL,
+            ctx->x86_hvm.restore.iterations);
     free(ctx->x86_hvm.restore.context);
     xc_sr_bitmap_free(&ctx->x86_hvm.restore.attempted_1g);
     xc_sr_bitmap_free(&ctx->x86_hvm.restore.attempted_2m);
@@ -440,6 +447,28 @@ static int x86_hvm_allocate_pfn(struct xc_sr_context *ctx, xen_pfn_t pfn)
     return rc;
 }
 
+static void diff_timespec(struct xc_sr_context *ctx, const struct timespec *old, const struct timespec *new, struct timespec *diff)
+{
+    xc_interface *xch = ctx->xch;
+    if (new->tv_sec == old->tv_sec && new->tv_nsec == old->tv_nsec)
+        PERROR("%s: time did not move: %ld/%ld == %ld/%ld", __func__, old->tv_sec, old->tv_nsec, new->tv_sec, new->tv_nsec);
+    if ( (new->tv_sec < old->tv_sec) || (new->tv_sec == old->tv_sec && new->tv_nsec < old->tv_nsec) )
+    {
+        PERROR("%s: time went backwards: %ld/%ld -> %ld/%ld", __func__, old->tv_sec, old->tv_nsec, new->tv_sec, new->tv_nsec);
+        diff->tv_sec = diff->tv_nsec = 0;
+        return;
+    }
+    if ((new->tv_nsec - old->tv_nsec) < 0) {
+        diff->tv_sec = new->tv_sec - old->tv_sec - 1;
+        diff->tv_nsec = new->tv_nsec - old->tv_nsec + 1000000000UL;
+    } else {
+        diff->tv_sec = new->tv_sec - old->tv_sec;
+        diff->tv_nsec = new->tv_nsec - old->tv_nsec;
+    }
+    if (diff->tv_sec < 0)
+        PERROR("%s: time diff broken. old: %ld/%ld new: %ld/%ld diff: %ld/%ld ", __func__, old->tv_sec, old->tv_nsec, new->tv_sec, new->tv_nsec, diff->tv_sec, diff->tv_nsec);
+}
+
 static int x86_hvm_populate_pfns(struct xc_sr_context *ctx, unsigned count,
                                  const xen_pfn_t *original_pfns,
                                  const uint32_t *types)
@@ -448,6 +477,7 @@ static int x86_hvm_populate_pfns(struct xc_sr_context *ctx, unsigned count,
     xen_pfn_t pfn, min_pfn = original_pfns[0], max_pfn = original_pfns[0];
     unsigned i, freed = 0, order;
     int rc = -1;
+    struct timespec a, b, d;
 
     for ( i = 0; i < count; ++i )
     {
@@ -474,6 +504,8 @@ static int x86_hvm_populate_pfns(struct xc_sr_context *ctx, unsigned count,
         }
     }
 
+    if (clock_gettime(CLOCK_MONOTONIC, &a))
+        PERROR("clock_gettime start");
     /*
      * Scan the entire superpage because several batches will fit into
      * a superpage, and it is unknown which pfn triggered the allocation.
@@ -504,10 +536,17 @@ static int x86_hvm_populate_pfns(struct xc_sr_context *ctx, unsigned count,
         }
         pfn++;
     }
-    if ( freed )
+    if ( 0 && freed )
         DPRINTF("freed %u between %" PRI_xen_pfn " %" PRI_xen_pfn "\n",
                 freed, min_pfn, max_pfn);
 
+    if (clock_gettime(CLOCK_MONOTONIC, &b))
+        PERROR("clock_gettime end");
+
+    diff_timespec(ctx, &a, &b, &d);
+    ctx->x86_hvm.restore.tv_nsec += d.tv_nsec + (1000000000UL * d.tv_sec);
+    ctx->x86_hvm.restore.iterations++;
+
     rc = 0;
 
  err:

[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

[-- Attachment #2: Type: text/plain, Size: 127 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  reply	other threads:[~2017-08-29  9:58 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-26 10:33 [PATCH v6 0/3] tools/libxc: use superpages Olaf Hering
2017-08-26 10:33 ` [PATCH v6 1/3] tools/libxc: move SUPERPAGE macros to common header Olaf Hering
2017-08-26 10:33 ` [PATCH v6 2/3] tools/libxc: add API for bitmap access for restore Olaf Hering
2017-08-26 10:33 ` [PATCH v6 3/3] tools/libxc: use superpages during restore of HVM guest Olaf Hering
2017-08-29  9:58   ` Olaf Hering [this message]
2017-08-30 13:48   ` Wei Liu
2017-08-30 14:27     ` Olaf Hering
2017-08-30 15:14       ` Wei Liu
2017-08-30 15:53         ` Olaf Hering

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=20170829095823.GA9803@aepfle.de \
    --to=olaf@aepfle.de \
    --cc=andrew.cooper3@citrix.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /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.