WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

Re: [Xen-devel] [PATCH] save/restore race

To: "John Levon" <levon@xxxxxxxxxxxxxxxxx>, m+Ian.Pratt@xxxxxxxxxxxx
Subject: Re: [Xen-devel] [PATCH] save/restore race
From: "Srikanth SM" <srikanth.sm@xxxxxxxxx>
Date: Tue, 6 Feb 2007 20:34:21 +0530
Cc: xen-devel@xxxxxxxxxxxxxxxxxxx
Delivery-date: Tue, 06 Feb 2007 07:03:58 -0800
Domainkey-signature: a=rsa-sha1; c=nofws; d=gmail.com; s=beta; h=received:message-id:date:from:to:subject:cc:in-reply-to:mime-version:content-type:references; b=MnkyKZyCy908mWcsjTLjjGNz0MvdmEmJyJkpgw9W3xJFUL3+7OpjKoKwnAj+GtoIZoFG1xK5GB4ZLM5upfaOHp9lOHFmPMhfMQcrkWP1GKRjHNxSUWBcYUYw/3WKShP8KS7+hebG2ZDiSYaed2MaxcA5GVfNTU+Cwn4VCfayc7A=
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
In-reply-to: <20070124031318.GA32700@xxxxxxxxxxxxxxxxxxxxxxx>
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
References: <20070123220145.GA22372@xxxxxxxxxxxxxxxxxxxxxxx> <8A87A9A84C201449A0C56B728ACF491E04F284@xxxxxxxxxxxxxxxxxxxxxxxxxxx> <20070123224856.GA25347@xxxxxxxxxxxxxxxxxxxxxxx> <8A87A9A84C201449A0C56B728ACF491E04F28B@xxxxxxxxxxxxxxxxxxxxxxxxxxx> <20070124021023.GA30953@xxxxxxxxxxxxxxxxxxxxxxx> <8A87A9A84C201449A0C56B728ACF491E04F291@xxxxxxxxxxxxxxxxxxxxxxxxxxx> <20070124031318.GA32700@xxxxxxxxxxxxxxxxxxxxxxx>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
Hi,

I Came across this thread trying to understand live migration better.
I did some experiments and atleast on linux, I could do away with the
waiting for the arch.pfn_to_mfn_frame_list_list to get initialized
after a restore.  I believe it will work with other OSes as
well. I request your comments regarding this.

Please see if the below patch (against xen-unstable) can be used.

What I did was, simple-minded though: Instead of the guest building
p2m frame-list-list and the frame-list _after_ a restore, we build it from
dom0 _during_ restore.
- In save, canonicalise the pfn_to_mfn_frame_list_list mfn along
 with the entries in that page and store them in state file. (Note
 that we are anyway saving canonicalised p2m_frame_list pages)

- In restore, uncanonicalise pfn_to_mfn_frame_list_list pfn, and
 the entries of the page and copy it to appropriate place in guest memory.
 Also copy p2m_frame_list entries to appropriate place in guest memory.

However, what I do not know is the exact reason why this
initialization of pfn_to_mfn_frame_list_list and pfn_to_mfn_frame_list
is being done by the guest domain after unpausing
currently. Could you please clarify this?

Thanks and regards
Srikanth
Patch for inline viewing:


# HG changeset patch
# User srao@srikanth
# Node ID 6443c0465741c05ffef24f5ca7c7fd3907089d04
# Parent  8bc64a3a505413e4d3bd7def06539ef088f2ca0c
Avoid waiting for pfn-to-mfn-frame-list-list etc., to get initialized
when doing a save after restore.

Signed-off-by: Srikanth S. M. <srikanth_sm@xxxxxxxxxxxx>

diff -r 8bc64a3a5054 -r 6443c0465741
linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c
--- a/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Mon Feb
5 16:40:19 2007
+++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_reboot.c    Tue Feb
6 14:42:34 2007
@@ -87,10 +87,7 @@

static void post_suspend(int suspend_cancelled)
{
-       int i, j, k, fpp;
        extern unsigned long max_pfn;
-       extern unsigned long *pfn_to_mfn_frame_list_list;
-       extern unsigned long *pfn_to_mfn_frame_list[];

        if (suspend_cancelled) {
                xen_start_info->store_mfn =
@@ -105,20 +102,7 @@

        memset(empty_zero_page, 0, PAGE_SIZE);

-       fpp = PAGE_SIZE/sizeof(unsigned long);
-       for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
-               if ((j % fpp) == 0) {
-                       k++;
-                       pfn_to_mfn_frame_list_list[k] =
-                               virt_to_mfn(pfn_to_mfn_frame_list[k]);
-                       j = 0;
-               }
-               pfn_to_mfn_frame_list[k][j] =
-                       virt_to_mfn(&phys_to_machine_mapping[i]);
-       }
        HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
-       HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
-               virt_to_mfn(pfn_to_mfn_frame_list_list);
}

#else /* !(defined(__i386__) || defined(__x86_64__)) */
diff -r 8bc64a3a5054 -r 6443c0465741 tools/libxc/xc_linux_restore.c
--- a/tools/libxc/xc_linux_restore.c    Mon Feb  5 16:40:19 2007
+++ b/tools/libxc/xc_linux_restore.c    Tue Feb  6 14:42:34 2007
@@ -172,6 +172,9 @@
    /* A copy of the pfn-to-mfn table frame list. */
    xen_pfn_t *p2m_frame_list = NULL;

+    /* A temporary mapping of pfn-to-mfn table frame list */
+    xen_pfn_t *live_p2m_fl = NULL;
+
    /* A temporary mapping of the guest's start_info page. */
    start_info_t *start_info;

@@ -816,11 +819,41 @@
    for ( i = 0; i < MAX_VIRT_CPUS; i++ )
        shared_info->vcpu_info[i].evtchn_pending_sel = 0;

-    /* Copy saved contents of shared-info page. No checking needed. */
+    /*
+     * Uncanonicalise fll pfn. Copy saved contents of shared-info page.
+     * No checking needed.
+     */
+    shared_info->arch.pfn_to_mfn_frame_list_list =
+       p2m[shared_info->arch.pfn_to_mfn_frame_list_list];
    page = xc_map_foreign_range(
        xc_handle, dom, PAGE_SIZE, PROT_WRITE, shared_info_frame);
    memcpy(page, shared_info, PAGE_SIZE);
    munmap(page, PAGE_SIZE);
+
+    /* Update fll page. Uncanonicalise entries in fll */
+    page = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_WRITE,
+                               shared_info->arch.pfn_to_mfn_frame_list_list);
+    if (page == NULL) {
+       ERROR("Cant map fll page");
+       goto out;
+    }
+    if (!read_exact(io_fd, page, PAGE_SIZE)) {
+       ERROR("Cant read fll page");
+       goto out;
+    }
+    for (i = 0; i < P2M_FLL_ENTRIES; i++) {
+       xen_pfn_t *p = page;
+       p[i] = p2m[p[i]];
+    }
+
+    /* Map pfn-to-mfn frame list pages */
+    live_p2m_fl = xc_map_foreign_batch(xc_handle, dom, PROT_WRITE,
+                                     page, P2M_FLL_ENTRIES);
+    munmap(page, PAGE_SIZE);
+    if (live_p2m_fl == NULL) {
+       ERROR("Cant map p2m frame-list pages");
+       goto out;
+    }

    /* Uncanonicalise the pfn-to-mfn table frame-number list. */
    for (i = 0; i < P2M_FL_ENTRIES; i++) {
@@ -832,6 +865,13 @@

        p2m_frame_list[i] = p2m[pfn];
    }
+
+    /*
+     * Copy the p2m_frame_list (local copy)
+     * to the live-p2m-frame-list
+     */
+    memcpy(live_p2m_fl, p2m_frame_list, P2M_FL_ENTRIES * sizeof (xen_pfn_t));
+    munmap(live_p2m_fl, P2M_FLL_ENTRIES * PAGE_SIZE);

    /* Copy the P2M we've constructed to the 'live' P2M */
    if (!(live_p2m = xc_map_foreign_batch(xc_handle, dom, PROT_WRITE,
diff -r 8bc64a3a5054 -r 6443c0465741 tools/libxc/xc_linux_save.c
--- a/tools/libxc/xc_linux_save.c       Mon Feb  5 16:40:19 2007
+++ b/tools/libxc/xc_linux_save.c       Tue Feb  6 14:42:34 2007
@@ -426,34 +426,6 @@
}

/*
-** Map the top-level page of MFNs from the guest. The guest might not have
-** finished resuming from a previous restore operation, so we wait a while for
-** it to update the MFN to a reasonable value.
-*/
-static void *map_frame_list_list(int xc_handle, uint32_t dom,
-                                 shared_info_t *shinfo)
-{
-    int count = 100;
-    void *p;
-
-    while (count-- && shinfo->arch.pfn_to_mfn_frame_list_list == 0)
-        usleep(10000);
-
-    if (shinfo->arch.pfn_to_mfn_frame_list_list == 0) {
-        ERROR("Timed out waiting for frame list updated.");
-        return NULL;
-    }
-
-    p = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
-                             shinfo->arch.pfn_to_mfn_frame_list_list);
-
-    if (p == NULL)
-        ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
-
-    return p;
-}
-
-/*
** During transfer (or in the state file), all page-table pages must be
** converted into a 'canonical' form where references to actual mfns
** are replaced with references to the corresponding pfns.
@@ -616,7 +588,6 @@
}


-
int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
                  uint32_t max_factor, uint32_t flags, int (*suspend)(int))
{
@@ -714,12 +685,14 @@
    }

    max_pfn = live_shinfo->arch.max_pfn;
-
-    live_p2m_frame_list_list = map_frame_list_list(xc_handle, dom,
-                                                   live_shinfo);
-
-    if (!live_p2m_frame_list_list)
-        goto out;
+    live_p2m_frame_list_list =
+        xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ,
+                             live_shinfo->arch.pfn_to_mfn_frame_list_list);
+
+    if (!live_p2m_frame_list_list) {
+        ERROR("Couldn't map p2m_frame_list_list (errno %d)", errno);
+        goto out;
+    }

    live_p2m_frame_list =
        xc_map_foreign_batch(xc_handle, dom, PROT_READ,
@@ -1225,14 +1198,32 @@
        xen_pfn_to_cr3(mfn_to_pfn(xen_cr3_to_pfn(ctxt.ctrlreg[3])));

    /*
-     * Reset the MFN to be a known-invalid value. See map_frame_list_list().
+     * Canonicalise fll mfn
     */
    memcpy(page, live_shinfo, PAGE_SIZE);
-    ((shared_info_t *)page)->arch.pfn_to_mfn_frame_list_list = 0;
+    if (!translate_mfn_to_pfn(
+            &((shared_info_t *)page)->arch.pfn_to_mfn_frame_list_list)) {
+        ERROR("Cant canonicalise fll mfn");
+        goto out;
+    }

    if (!write_exact(io_fd, &ctxt, sizeof(ctxt)) ||
        !write_exact(io_fd, page, PAGE_SIZE)) {
        ERROR("Error when writing to state file (1) (errno %d)", errno);
+        goto out;
+    }
+
+    /* canonicalise fll entries and send fll page */
+    memcpy(page, live_p2m_frame_list_list, PAGE_SIZE);
+    for (i = 0; i < P2M_FLL_ENTRIES; i++) {
+        if (!translate_mfn_to_pfn(&((xen_pfn_t *)page)[i])) {
+            ERROR("Cant canonicalise fll entry %d", i);
+            goto out;
+        }
+    }
+
+    if (!write_exact(io_fd, page, PAGE_SIZE)) {
+        ERROR("Cant write fll page to state file");
        goto out;
    }




> 30 seconds is quite a time to wait... Wouldn't a second be more
> appropriate?
>
> While you're at it, I'd be grateful if you could move the shared_info
> assignment in linux's post_suspend() and setup_arch() [i386 and x86_64]
> below the list building code.
Sure. Patch below is for 3.0.4 but should essentially apply to
xen-unstable too.

thanks
john

Attachment: save_restore.patch
Description: Text Data

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
<Prev in Thread] Current Thread [Next in Thread>