xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: "Jan Beulich" <JBeulich@novell.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] don't save Xen heap pages during domain save
Date: Tue, 15 Jun 2010 12:45:31 +0100	[thread overview]
Message-ID: <4C1783FB0200007800006777@vpn.id2.novell.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 6082 bytes --]

As discussed in the thread starting at
http://lists.xensource.com/archives/html/xen-devel/2010-05/msg01383.html,
don't save Xen heap pages in order to avoid overallocation when the
domain gets restored, as those pages would get (temporarily) backed
with normal RAM pages by the restore code.

This requires making DOMCTL_getpageframeinfo{2,3} usable for HVM guests,
meaning that the input to these must be treated as GMFNs.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- 2010-06-15.orig/tools/libxc/xc_domain_save.c	2010-06-01 13:39:57.000000000 +0200
+++ 2010-06-15/tools/libxc/xc_domain_save.c	2010-06-15 09:32:42.000000000 +0200
@@ -1288,58 +1288,64 @@ int xc_domain_save(xc_interface *xch, in
                 goto out;
             }
 
-            if ( hvm )
+            /* Get page types */
+            if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
             {
-                /* Look for and skip completely empty batches. */
-                for ( j = 0; j < batch; j++ )
-                {
-                    if ( !pfn_err[j] )
-                        break;
-                    pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
-                }
-                if ( j == batch )
-                {
-                    munmap(region_base, batch*PAGE_SIZE);
-                    continue; /* bail on this batch: no valid pages */
-                }
-                for ( ; j < batch; j++ )
-                    if ( pfn_err[j] )
-                        pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
+                PERROR("get_pfn_type_batch failed");
+                goto out;
             }
-            else
+
+            for ( run = j = 0; j < batch; j++ )
             {
-                /* Get page types */
-                if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
-                {
-                    PERROR("get_pfn_type_batch failed");
-                    goto out;
-                }
+                unsigned long gmfn = pfn_batch[j];
 
-                for ( j = 0; j < batch; j++ )
+                if ( !hvm )
+                    gmfn = pfn_to_mfn(gmfn);
+
+                if ( pfn_err[j] )
                 {
-                    unsigned long mfn = pfn_to_mfn(pfn_batch[j]);
-                    
                     if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB )
-                    {
-                        DPRINTF("type fail: page %i mfn %08lx\n", 
-                                j, mfn);
                         continue;
-                    }
-                    
-                    if ( debug )
+                    DPRINTF("map fail: page %i mfn %08lx err %d\n",
+                            j, gmfn, pfn_err[j]);
+                    pfn_type[j] = XEN_DOMCTL_PFINFO_XTAB;
+                    continue;
+                }
+
+                if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB )
+                {
+                    DPRINTF("type fail: page %i mfn %08lx\n", j, gmfn);
+                    continue;
+                }
+
+                /* canonicalise mfn->pfn */
+                pfn_type[j] |= pfn_batch[j];
+                ++run;
+
+                if ( debug )
+                {
+                    if ( hvm )
+                        DPRINTF("%d pfn=%08lx sum=%08lx\n",
+                                iter,
+                                pfn_type[j],
+                                csum_page(region_base + (PAGE_SIZE*j)));
+                    else
                         DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
                                 " sum= %08lx\n",
                                 iter,
-                                pfn_type[j] | pfn_batch[j],
-                                mfn,
-                                mfn_to_pfn(mfn),
+                                pfn_type[j],
+                                gmfn,
+                                mfn_to_pfn(gmfn),
                                 csum_page(region_base + (PAGE_SIZE*j)));
-                    
-                    /* canonicalise mfn->pfn */
-                    pfn_type[j] |= pfn_batch[j];
                 }
             }
 
+            if ( !run )
+            {
+                munmap(region_base, batch*PAGE_SIZE);
+                continue; /* bail on this batch: no valid pages */
+            }
+
             if ( wrexact(io_fd, &batch, sizeof(unsigned int)) )
             {
                 PERROR("Error when writing to state file (2)");
--- 2010-06-15.orig/xen/arch/x86/domctl.c	2010-03-02 09:11:28.000000000 +0100
+++ 2010-06-15/xen/arch/x86/domctl.c	2010-06-15 09:32:42.000000000 +0200
@@ -207,11 +207,12 @@ long arch_do_domctl(
 
                 for ( j = 0; j < k; j++ )
                 {
-                    unsigned long type = 0, mfn = arr[j];
+                    unsigned long type = 0, mfn = gmfn_to_mfn(d, arr[j]);
 
                     page = mfn_to_page(mfn);
 
-                    if ( unlikely(!mfn_valid(mfn)) )
+                    if ( unlikely(!mfn_valid(mfn)) ||
+                         unlikely(is_xen_heap_mfn(mfn)) )
                         type = XEN_DOMCTL_PFINFO_XTAB;
                     else if ( xsm_getpageframeinfo(page) != 0 )
                         ;
@@ -306,14 +307,15 @@ long arch_do_domctl(
             for ( j = 0; j < k; j++ )
             {      
                 struct page_info *page;
-                unsigned long mfn = arr32[j];
+                unsigned long mfn = gmfn_to_mfn(d, arr32[j]);
 
                 page = mfn_to_page(mfn);
 
                 if ( domctl->cmd == XEN_DOMCTL_getpageframeinfo3)
                     arr32[j] = 0;
 
-                if ( unlikely(!mfn_valid(mfn)) )
+                if ( unlikely(!mfn_valid(mfn)) ||
+                     unlikely(is_xen_heap_mfn(mfn)) )
                     arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
                 else if ( xsm_getpageframeinfo(page) != 0 )
                     continue;



[-- Attachment #2: dont-save-xen-heap-pages.patch --]
[-- Type: text/plain, Size: 6078 bytes --]

As discussed in the thread starting at
http://lists.xensource.com/archives/html/xen-devel/2010-05/msg01383.html,
don't save Xen heap pages in order to avoid overallocation when the
domain gets restored, as those pages would get (temporarily) backed
with normal RAM pages by the restore code.

This requires making DOMCTL_getpageframeinfo{2,3} usable for HVM guests,
meaning that the input to these must be treated as GMFNs.

Signed-off-by: Jan Beulich <jbeulich@novell.com>

--- 2010-06-15.orig/tools/libxc/xc_domain_save.c	2010-06-01 13:39:57.000000000 +0200
+++ 2010-06-15/tools/libxc/xc_domain_save.c	2010-06-15 09:32:42.000000000 +0200
@@ -1288,58 +1288,64 @@ int xc_domain_save(xc_interface *xch, in
                 goto out;
             }
 
-            if ( hvm )
+            /* Get page types */
+            if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
             {
-                /* Look for and skip completely empty batches. */
-                for ( j = 0; j < batch; j++ )
-                {
-                    if ( !pfn_err[j] )
-                        break;
-                    pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
-                }
-                if ( j == batch )
-                {
-                    munmap(region_base, batch*PAGE_SIZE);
-                    continue; /* bail on this batch: no valid pages */
-                }
-                for ( ; j < batch; j++ )
-                    if ( pfn_err[j] )
-                        pfn_type[j] |= XEN_DOMCTL_PFINFO_XTAB;
+                PERROR("get_pfn_type_batch failed");
+                goto out;
             }
-            else
+
+            for ( run = j = 0; j < batch; j++ )
             {
-                /* Get page types */
-                if ( xc_get_pfn_type_batch(xch, dom, batch, pfn_type) )
-                {
-                    PERROR("get_pfn_type_batch failed");
-                    goto out;
-                }
+                unsigned long gmfn = pfn_batch[j];
 
-                for ( j = 0; j < batch; j++ )
+                if ( !hvm )
+                    gmfn = pfn_to_mfn(gmfn);
+
+                if ( pfn_err[j] )
                 {
-                    unsigned long mfn = pfn_to_mfn(pfn_batch[j]);
-                    
                     if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB )
-                    {
-                        DPRINTF("type fail: page %i mfn %08lx\n", 
-                                j, mfn);
                         continue;
-                    }
-                    
-                    if ( debug )
+                    DPRINTF("map fail: page %i mfn %08lx err %d\n",
+                            j, gmfn, pfn_err[j]);
+                    pfn_type[j] = XEN_DOMCTL_PFINFO_XTAB;
+                    continue;
+                }
+
+                if ( pfn_type[j] == XEN_DOMCTL_PFINFO_XTAB )
+                {
+                    DPRINTF("type fail: page %i mfn %08lx\n", j, gmfn);
+                    continue;
+                }
+
+                /* canonicalise mfn->pfn */
+                pfn_type[j] |= pfn_batch[j];
+                ++run;
+
+                if ( debug )
+                {
+                    if ( hvm )
+                        DPRINTF("%d pfn=%08lx sum=%08lx\n",
+                                iter,
+                                pfn_type[j],
+                                csum_page(region_base + (PAGE_SIZE*j)));
+                    else
                         DPRINTF("%d pfn= %08lx mfn= %08lx [mfn]= %08lx"
                                 " sum= %08lx\n",
                                 iter,
-                                pfn_type[j] | pfn_batch[j],
-                                mfn,
-                                mfn_to_pfn(mfn),
+                                pfn_type[j],
+                                gmfn,
+                                mfn_to_pfn(gmfn),
                                 csum_page(region_base + (PAGE_SIZE*j)));
-                    
-                    /* canonicalise mfn->pfn */
-                    pfn_type[j] |= pfn_batch[j];
                 }
             }
 
+            if ( !run )
+            {
+                munmap(region_base, batch*PAGE_SIZE);
+                continue; /* bail on this batch: no valid pages */
+            }
+
             if ( wrexact(io_fd, &batch, sizeof(unsigned int)) )
             {
                 PERROR("Error when writing to state file (2)");
--- 2010-06-15.orig/xen/arch/x86/domctl.c	2010-03-02 09:11:28.000000000 +0100
+++ 2010-06-15/xen/arch/x86/domctl.c	2010-06-15 09:32:42.000000000 +0200
@@ -207,11 +207,12 @@ long arch_do_domctl(
 
                 for ( j = 0; j < k; j++ )
                 {
-                    unsigned long type = 0, mfn = arr[j];
+                    unsigned long type = 0, mfn = gmfn_to_mfn(d, arr[j]);
 
                     page = mfn_to_page(mfn);
 
-                    if ( unlikely(!mfn_valid(mfn)) )
+                    if ( unlikely(!mfn_valid(mfn)) ||
+                         unlikely(is_xen_heap_mfn(mfn)) )
                         type = XEN_DOMCTL_PFINFO_XTAB;
                     else if ( xsm_getpageframeinfo(page) != 0 )
                         ;
@@ -306,14 +307,15 @@ long arch_do_domctl(
             for ( j = 0; j < k; j++ )
             {      
                 struct page_info *page;
-                unsigned long mfn = arr32[j];
+                unsigned long mfn = gmfn_to_mfn(d, arr32[j]);
 
                 page = mfn_to_page(mfn);
 
                 if ( domctl->cmd == XEN_DOMCTL_getpageframeinfo3)
                     arr32[j] = 0;
 
-                if ( unlikely(!mfn_valid(mfn)) )
+                if ( unlikely(!mfn_valid(mfn)) ||
+                     unlikely(is_xen_heap_mfn(mfn)) )
                     arr32[j] |= XEN_DOMCTL_PFINFO_XTAB;
                 else if ( xsm_getpageframeinfo(page) != 0 )
                     continue;

[-- Attachment #3: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

             reply	other threads:[~2010-06-15 11:45 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-06-15 11:45 Jan Beulich [this message]
2010-06-15 12:22 ` [PATCH] don't save Xen heap pages during domain save Keir Fraser
2010-06-15 12:39   ` Jan Beulich

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=4C1783FB0200007800006777@vpn.id2.novell.com \
    --to=jbeulich@novell.com \
    --cc=xen-devel@lists.xensource.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).