All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/18] xenpaging changes for 4.0
@ 2010-10-15 14:12 Olaf Hering
  2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
                   ` (19 more replies)
  0 siblings, 20 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel


Here are some changes for xenpaging in the 4.0 branch.

Its just for review and comments.  All changes are also needed for
xen-unstable, I will prepare a patch queue also for this branch.

There are still issues with xenpaging.
My testsetup is a SLES11 SP1 guest with runlevel 6 as default runlevel to
trigger automatic reboot.  After a few iterations, there will be MMIO emulation
errors.  This happens with a startup delay of 15.0 seconds.

Another issue:
If the startup delay is 0.0, and over_allocated in hvmloader mem_alloc is
forced to be active, the ASSERT in p2m_remove_page() triggers. This is because
the passed mfn and the mfn returned by ->get_entry() do not match.  So far I
have no idea where the appearently missing set_gpfn_from_mfn() should go to.
Normally over_allocated is not set because the XENMEM_populate_physmap call
does not fail.

Olaf

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 01/18] xenpaging: Fix-up xenpaging tool code.
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page Olaf Hering
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.tools_xenpaging_cleanup.patch --]
[-- Type: text/plain, Size: 1468 bytes --]

This isn't directly related to EPT checking, but does some general fix-ups
to the xenpaging code (adds some extra frees, etc.)

Already-Signed-off-by: Patrick Colp <pjcolp@cs.ubc.ca>
Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/xenpaging/xenpaging.c |   22 ++++++++++++++++++----
 1 file changed, 18 insertions(+), 4 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -100,7 +100,7 @@ xenpaging_t *xenpaging_init(domid_t doma
     paging->mem_event.ring_page = init_page();
     if ( paging->mem_event.ring_page == NULL )
     {
-        ERROR("Error initialising shared page");
+        ERROR("Error initialising ring page");
         goto err;
     }
 
@@ -198,13 +198,27 @@ xenpaging_t *xenpaging_init(domid_t doma
     return paging;
 
  err:
-    if ( paging->bitmap )
+    if ( paging )
+    {
+        if ( paging->mem_event.shared_page )
+        {
+            munlock(paging->mem_event.shared_page, PAGE_SIZE);
+            free(paging->mem_event.shared_page);
+        }
+
+        if ( paging->mem_event.ring_page )
+        {
+            munlock(paging->mem_event.ring_page, PAGE_SIZE);
+            free(paging->mem_event.ring_page);
+        }
+
         free(paging->bitmap);
-    if ( paging->platform_info )
         free(paging->platform_info);
-    if ( paging )
+        free(paging->domain_info);
         free(paging);
+    }
 
+ err_iface:
     return NULL;
 }

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
  2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 03/18] xenpaging: fix fd leak in xenstore Olaf Hering
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.pageout_policy.patch --]
[-- Type: text/plain, Size: 865 bytes --]

Notify policy about a page that was just paged out to disk.
Up to now the code called the opposite function, which clears the
(xenpaging internal) reference bit, instead of setting it and marking
the page as gone.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>

---
 tools/xenpaging/xenpaging.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -358,8 +358,8 @@ int xenpaging_evict_page(xenpaging_t *pa
         goto out;
     }
 
-    /* Notify policy of page being paged in */
-    policy_notify_paged_in(paging->mem_event.domain_id, victim->gfn);
+    /* Notify policy of page being paged out */
+    policy_notify_paged_out(paging->mem_event.domain_id, victim->gfn);
 
  out:
     return ret;

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 03/18] xenpaging: fix fd leak in xenstore
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
  2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
  2010-10-15 14:12 ` [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles Olaf Hering
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.xs_daemon_close.patch --]
[-- Type: text/plain, Size: 593 bytes --]

Missing from commit 'libxl: Backported stuff from unstable'
Without this change, xs_daemon_open/xs_daemon_close will leak filedescriptors.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/xenstore/xs.c |    2 ++
 1 file changed, 2 insertions(+)

--- xen-4.0.1-testing.orig/tools/xenstore/xs.c
+++ xen-4.0.1-testing/tools/xenstore/xs.c
@@ -285,6 +285,8 @@ void xs_daemon_close(struct xs_handle *h
 	mutex_unlock(&h->request_mutex);
 	mutex_unlock(&h->reply_mutex);
 	mutex_unlock(&h->watch_mutex);
+
+	close_fds_free(h);
 }
 
 static bool read_all(int fd, void *data, unsigned int len)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (2 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 03/18] xenpaging: fix fd leak in xenstore Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds Olaf Hering
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.policy_linear.patch --]
[-- Type: text/plain, Size: 3828 bytes --]

To allow the starting for xenpaging right after 'xm start XYZ', I
specified a pagefile size equal to the guest memory size in the hope to
catch more errors where the paged-out state of a p2mt is not checked.

While doing that, xenpaging got into an endless loop because some pages
cant be paged out right away. Now the policy reports an error if the gfn
number wraps.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>

---
 tools/xenpaging/policy_default.c |   35 ++++++++++++++++++++++++++++-------
 tools/xenpaging/xenpaging.c      |    7 +++++--
 2 files changed, 33 insertions(+), 9 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -30,8 +30,12 @@
 
 
 static unsigned long mru[MRU_SIZE];
-static unsigned int i_mru = 0;
+static unsigned int i_mru;
 static unsigned long *bitmap;
+static unsigned long *unconsumed;
+static unsigned long current_gfn;
+static unsigned long bitmap_size;
+static unsigned long max_pages;
 
 
 int policy_init(xenpaging_t *paging)
@@ -43,6 +47,14 @@ int policy_init(xenpaging_t *paging)
     rc = alloc_bitmap(&bitmap, paging->bitmap_size);
     if ( rc != 0 )
         goto out;
+    /* Allocate bitmap to track unusable pages */
+    rc = alloc_bitmap(&unconsumed, paging->bitmap_size);
+    if ( rc != 0 )
+        goto out;
+
+    /* record bitmap_size */
+    bitmap_size = paging->bitmap_size;
+    max_pages = paging->domain_info->max_pages;
 
     /* Initialise MRU list of paged in pages */
     for ( i = 0; i < MRU_SIZE; i++ )
@@ -51,8 +63,6 @@ int policy_init(xenpaging_t *paging)
     /* Don't page out page 0 */
     set_bit(0, bitmap);
 
-    rc = 0;
-
  out:
     return rc;
 }
@@ -60,17 +70,27 @@ int policy_init(xenpaging_t *paging)
 int policy_choose_victim(xenpaging_t *paging, domid_t domain_id,
                          xenpaging_victim_t *victim)
 {
+    unsigned long wrap = current_gfn;
     ASSERT(victim != NULL);
 
     /* Domain to pick on */
     victim->domain_id = domain_id;
-    
+
     do
     {
-        /* Randomly choose a gfn to evict */
-        victim->gfn = rand() % paging->domain_info->max_pages;
+        current_gfn++;
+        if ( current_gfn >= max_pages )
+            current_gfn = 0;
+        if ( wrap == current_gfn )
+        {
+            victim->gfn = INVALID_MFN;
+            return -ENOSPC;
+        }
     }
-    while ( test_bit(victim->gfn, bitmap) );
+    while ( test_bit(current_gfn, bitmap) || test_bit(current_gfn, unconsumed) );
+
+    set_bit(current_gfn, unconsumed);
+    victim->gfn = current_gfn;
 
     return 0;
 }
@@ -78,6 +98,7 @@ int policy_choose_victim(xenpaging_t *pa
 void policy_notify_paged_out(domid_t domain_id, unsigned long gfn)
 {
     set_bit(gfn, bitmap);
+    clear_bit(gfn, unconsumed);
 }
 
 void policy_notify_paged_in(domid_t domain_id, unsigned long gfn)
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -440,7 +440,8 @@ static int evict_victim(xenpaging_t *pag
         ret = policy_choose_victim(paging, domain_id, victim);
         if ( ret != 0 )
         {
-            ERROR("Error choosing victim");
+            if ( ret != -ENOSPC )
+                ERROR("Error choosing victim");
             goto out;
         }
 
@@ -518,7 +519,9 @@ int main(int argc, char *argv[])
     memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
     for ( i = 0; i < num_pages; i++ )
     {
-        evict_victim(paging, domain_id, &victims[i], fd, i);
+        rc = evict_victim(paging, domain_id, &victims[i], fd, i);
+        if ( rc == -ENOSPC )
+            break;
         if ( i % 100 == 0 )
             DPRINTF("%d pages evicted\n", i);
     }

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (3 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.pagefile.patch --]
[-- Type: text/plain, Size: 1392 bytes --]

Open paging file only if xenpaging_init() succeeds. It can fail if the host
does not support the required virtualization features such as EPT or if
xenpaging was already started for this domain_id.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>

---
 tools/xenpaging/xenpaging.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -495,15 +495,6 @@ int main(int argc, char *argv[])
 
     victims = calloc(num_pages, sizeof(xenpaging_victim_t));
 
-    /* Open file */
-    sprintf(filename, "page_cache_%d", domain_id);
-    fd = open(filename, open_flags, open_mode);
-    if ( fd < 0 )
-    {
-        perror("failed to open file");
-        return -1;
-    }
-
     /* Seed random-number generator */
     srand(time(NULL));
 
@@ -515,6 +506,15 @@ int main(int argc, char *argv[])
         goto out;
     }
 
+    /* Open file */
+    sprintf(filename, "page_cache_%d", domain_id);
+    fd = open(filename, open_flags, open_mode);
+    if ( fd < 0 )
+    {
+        perror("failed to open file");
+        return -1;
+    }
+
     /* Evict pages */
     memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
     for ( i = 0; i < num_pages; i++ )

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (4 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-18 16:54   ` Ian Jackson
  2010-10-15 14:12 ` [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache Olaf Hering
                   ` (13 subsequent siblings)
  19 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.xenpaging_init.patch --]
[-- Type: text/plain, Size: 1760 bytes --]

Make sure only one xenpaging binary is active per domain.
Print info when the host lacks the required features for xenpaging.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>

---
 tools/xenpaging/xenpaging.c |   12 +++++++++++-
 xen/arch/x86/mm/mem_event.c |    7 +++++++
 2 files changed, 18 insertions(+), 1 deletion(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -119,7 +119,17 @@ xenpaging_t *xenpaging_init(domid_t doma
                              paging->mem_event.ring_page);
     if ( rc != 0 )
     {
-        ERROR("Error initialising shared page");
+        switch ( errno ) {
+            case EBUSY:
+                ERROR("xenpaging is (or was) active on this domain");
+                break;
+            case ENODEV:
+                ERROR("EPT not supported for this guest");
+                break;
+            default:
+                ERROR("Error initialising shared page");
+                break;
+        }
         goto err;
     }
 
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_event.c
@@ -226,6 +226,13 @@ int mem_event_domctl(struct domain *d, x
             mfn_t ring_mfn;
             mfn_t shared_mfn;
 
+            /* Only one xenpaging at a time. If xenpaging crashed,
+             * the cache is in an undefined state and so is the guest
+             */
+            rc = -EBUSY;
+            if ( d->mem_event.enabled )
+                break;
+
             /* Currently only EPT is supported */
             rc = -ENODEV;
             if ( !(is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled &&

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache.
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (5 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands Olaf Hering
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.mem_paging_tool_qemu_flush_cache.patch --]
[-- Type: text/plain, Size: 1071 bytes --]

Add support for a xenstore dm command to flush qemu's buffer cache.

qemu will just keep mapping pages and not release them, which causes problems
for the memory pager (since the page is mapped, it won't get paged out). When
the pager has trouble finding a page to page out, it asks qemu to flush its
buffer, which releases all the page mappings. This makes it possible to find
pages to swap out agian.

Already-Signed-off-by: Patrick Colp <Patrick.Colp@citrix.com>
Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/ioemu-remote/xenstore.c |    3 +++
 1 file changed, 3 insertions(+)

--- xen-4.0.1-testing.orig/tools/ioemu-remote/xenstore.c
+++ xen-4.0.1-testing/tools/ioemu-remote/xenstore.c
@@ -1021,6 +1021,9 @@ static void xenstore_process_dm_command_
         do_pci_add(par);
         free(par);
 #endif
+    } else if (!strncmp(command, "flush-cache", len)) {
+        fprintf(logfile, "dm-command: flush caches\n");
+        qemu_invalidate_map_cache();
     } else {
         fprintf(logfile, "dm-command: unknown command\"%*s\"\n", len, command);
     }

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (6 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 09/18] xenpaging: populate only paged-out pages Olaf Hering
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.memory_op.patch --]
[-- Type: text/plain, Size: 15538 bytes --]

Fix these two warings:
(XEN) Assertion '__mfn_valid(mfn_x(omfn))' failed at p2m.c:2200
(XEN) memory.c:171:d1 Domain 1 page number 37ff0 invalid

Handle paged-out pages in xc_memory_op, guest_physmap_add_entry and
guest_remove_page. Use new do_xenmem_op_retry helper function.
In addition, export also xen/errno.h to hvmloader to get ENOENT define.


XENMEM_populate_physmap
  populate_physmap
    -> guest_physmap_add_entry

XENMEM_exchange
  memory_exchange
    -> guest_physmap_add_entry

XENMEM_add_to_physmap
  guest_physmap_add_page
    -> guest_physmap_add_entry

__gnttab_map_grant_ref
  create_grant_host_mapping
    create_grant_p2m_mapping
     -> guest_physmap_add_entry

XENMEM_decrease_reservation
  decrease_reservation
   -> guest_remove_page

XENMEM_add_to_physmap
   -> guest_remove_page

XENMEM_add_to_physmap
  -> XENMAPSPACE_gmfn

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/firmware/hvmloader/hvmloader.c |    9 +++-
 tools/firmware/hvmloader/util.c      |   26 +++++++++++-
 tools/include/Makefile               |    1 
 tools/ioemu-remote/hw/vga.c          |    5 +-
 tools/libxc/xc_domain.c              |   71 +++++++++++++++++++++--------------
 xen/arch/x86/mm.c                    |   26 ++++++++++--
 xen/arch/x86/mm/p2m.c                |    7 +++
 xen/common/memory.c                  |   25 +++++++++++-
 8 files changed, 131 insertions(+), 39 deletions(-)

--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/hvmloader.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/hvmloader.c
@@ -29,6 +29,7 @@
 #include "pci_regs.h"
 #include "e820.h"
 #include "option_rom.h"
+#include <xen/errno.h>
 #include <xen/version.h>
 #include <xen/hvm/params.h>
 #include <xen/memory.h>
@@ -306,13 +307,19 @@ static void pci_setup(void)
     while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
     {
         struct xen_add_to_physmap xatp;
+        int rc;
         if ( hvm_info->high_mem_pgend == 0 )
             hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
         xatp.domid = DOMID_SELF;
         xatp.space = XENMAPSPACE_gmfn;
         xatp.idx   = --hvm_info->low_mem_pgend;
         xatp.gpfn  = hvm_info->high_mem_pgend++;
-        if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+        do {
+            rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+            if ( rc == -ENOENT )
+                cpu_relax();
+        } while ( rc == -ENOENT );
+        if ( rc != 0 )
             BUG();
     }
 
--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/util.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/util.c
@@ -23,6 +23,7 @@
 #include "e820.h"
 #include "hypercall.h"
 #include <stdint.h>
+#include <xen/errno.h>
 #include <xen/xen.h>
 #include <xen/memory.h>
 
@@ -323,19 +324,27 @@ void *mem_alloc(uint32_t size, uint32_t
 
     while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
     {
+        int rc;
         reserve += PAGE_SIZE;
         mfn = reserve >> PAGE_SHIFT;
 
         /* Try to allocate a brand new page in the reserved area. */
         if ( !over_allocated )
         {
+            uint8_t delay = 0;
             xmr.domid = DOMID_SELF;
             xmr.mem_flags = 0;
             xmr.extent_order = 0;
             xmr.nr_extents = 1;
             set_xen_guest_handle(xmr.extent_start, &mfn);
-            if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 )
+            do {
+                rc = hypercall_memory_op(XENMEM_populate_physmap, &xmr);
+                if ( rc == 0 )
+                    cpu_relax();
+            } while ( rc == 0 && ++delay );
+            if ( rc == 1 )
                 continue;
+            printf("%s: over_allocated\n", __func__);
             over_allocated = 1;
         }
 
@@ -353,7 +362,12 @@ void *mem_alloc(uint32_t size, uint32_t
         xatp.domid = DOMID_SELF;
         xatp.space = XENMAPSPACE_gmfn;
         xatp.gpfn  = mfn;
-        if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+        do {
+            rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+            if ( rc == -ENOENT )
+                cpu_relax();
+        } while ( rc == -ENOENT );
+        if ( rc != 0 )
             BUG();
     }
 
@@ -595,6 +609,7 @@ uint16_t get_cpu_mhz(void)
     uint64_t cpu_khz;
     uint32_t tsc_to_nsec_mul, version;
     int8_t tsc_shift;
+    int rc;
 
     static uint16_t cpu_mhz;
     if ( cpu_mhz != 0 )
@@ -605,7 +620,12 @@ uint16_t get_cpu_mhz(void)
     xatp.space = XENMAPSPACE_shared_info;
     xatp.idx   = 0;
     xatp.gpfn  = (unsigned long)shared_info >> 12;
-    if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
+    do {
+        rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+        if ( rc == -ENOENT )
+            cpu_relax();
+    } while ( rc == -ENOENT );
+    if ( rc != 0 )
         BUG();
 
     /* Get a consistent snapshot of scale factor (multiplier and shift). */
--- xen-4.0.1-testing.orig/tools/include/Makefile
+++ xen-4.0.1-testing/tools/include/Makefile
@@ -12,6 +12,7 @@ xen/.dir:
 	@rm -rf xen
 	mkdir -p xen/libelf
 	ln -sf ../$(XEN_ROOT)/xen/include/public/COPYING xen
+	ln -sf ../$(XEN_ROOT)/xen/include/xen/errno.h xen
 	ln -sf $(addprefix ../,$(wildcard $(XEN_ROOT)/xen/include/public/*.h)) xen
 	ln -sf $(addprefix ../$(XEN_ROOT)/xen/include/public/,arch-ia64 arch-x86 hvm io xsm) xen
 	ln -sf ../xen-sys/$(XEN_OS) xen/sys
--- xen-4.0.1-testing.orig/tools/ioemu-remote/hw/vga.c
+++ xen-4.0.1-testing/tools/ioemu-remote/hw/vga.c
@@ -2157,9 +2157,10 @@ void set_vram_mapping(void *opaque, unsi
     for (i = 0; i < (end - begin) >> TARGET_PAGE_BITS; i++) {
         xatp.idx = (s->vram_gmfn >> TARGET_PAGE_BITS) + i;
         xatp.gpfn = (begin >> TARGET_PAGE_BITS) + i;
-        rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp);
+        while ((rc = xc_memory_op(xc_handle, XENMEM_add_to_physmap, &xatp)) && errno == ENOENT)
+            usleep(1000);
         if (rc) {
-            fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, rc);
+            fprintf(stderr, "add_to_physmap MFN %"PRI_xen_pfn" to PFN %"PRI_xen_pfn" failed: %d\n", xatp.idx, xatp.gpfn, errno);
             return;
         }
     }
--- xen-4.0.1-testing.orig/tools/libxc/xc_domain.c
+++ xen-4.0.1-testing/tools/libxc/xc_domain.c
@@ -536,6 +536,44 @@ int xc_domain_get_tsc_info(int xc_handle
     return rc;
 }
 
+static int do_xenmem_op_retry(int xc_handle, int cmd, struct xen_memory_reservation *reservation, unsigned long nr_extents, xen_pfn_t *extent_start)
+{
+    int err = 0;
+    unsigned long count = nr_extents;
+    unsigned long delay = 0;
+    unsigned long start = 0;
+
+    fprintf(stderr, "%s: cmd %d count %lx\n",__func__,cmd,count);
+    while ( count && start < nr_extents )
+    {
+        set_xen_guest_handle(reservation->extent_start, extent_start + start);
+        reservation->nr_extents = count;
+
+        err = xc_memory_op(xc_handle, cmd, reservation);
+        if ( err == count )
+        {
+            err = 0;
+            break;
+        }
+
+        if ( err > count || err < 0 || delay > 1000 * 1000)
+        {
+            fprintf(stderr, "%s: %d err %x count %lx start %lx delay %lu/%lu\n",__func__,cmd,err,count,start,delay,delay/666);
+            err = -1;
+            break;
+        }
+
+        if ( err )
+            delay = 0;
+
+        start += err;
+        count -= err;
+        usleep(delay);
+        delay += 666; /* 1500 iterations, 12 seconds */
+    }
+
+    return err;
+}
 
 int xc_domain_memory_increase_reservation(int xc_handle,
                                           uint32_t domid,
@@ -546,26 +584,18 @@ int xc_domain_memory_increase_reservatio
 {
     int err;
     struct xen_memory_reservation reservation = {
-        .nr_extents   = nr_extents,
         .extent_order = extent_order,
         .mem_flags    = mem_flags,
         .domid        = domid
     };
 
-    /* may be NULL */
-    set_xen_guest_handle(reservation.extent_start, extent_start);
-
-    err = xc_memory_op(xc_handle, XENMEM_increase_reservation, &reservation);
-    if ( err == nr_extents )
-        return 0;
-
-    if ( err >= 0 )
+    err = do_xenmem_op_retry(xc_handle, XENMEM_increase_reservation, &reservation, nr_extents, extent_start);
+    if ( err < 0 )
     {
         DPRINTF("Failed allocation for dom %d: "
                 "%ld extents of order %d, mem_flags %x\n",
                 domid, nr_extents, extent_order, mem_flags);
         errno = ENOMEM;
-        err = -1;
     }
 
     return err;
@@ -579,14 +609,11 @@ int xc_domain_memory_decrease_reservatio
 {
     int err;
     struct xen_memory_reservation reservation = {
-        .nr_extents   = nr_extents,
         .extent_order = extent_order,
         .mem_flags    = 0,
         .domid        = domid
     };
 
-    set_xen_guest_handle(reservation.extent_start, extent_start);
-
     if ( extent_start == NULL )
     {
         DPRINTF("decrease_reservation extent_start is NULL!\n");
@@ -594,16 +621,12 @@ int xc_domain_memory_decrease_reservatio
         return -1;
     }
 
-    err = xc_memory_op(xc_handle, XENMEM_decrease_reservation, &reservation);
-    if ( err == nr_extents )
-        return 0;
-
-    if ( err >= 0 )
+    err = do_xenmem_op_retry(xc_handle, XENMEM_decrease_reservation, &reservation, nr_extents, extent_start);
+    if ( err < 0 )
     {
         DPRINTF("Failed deallocation for dom %d: %ld extents of order %d\n",
                 domid, nr_extents, extent_order);
         errno = EINVAL;
-        err = -1;
     }
 
     return err;
@@ -618,23 +641,17 @@ int xc_domain_memory_populate_physmap(in
 {
     int err;
     struct xen_memory_reservation reservation = {
-        .nr_extents   = nr_extents,
         .extent_order = extent_order,
         .mem_flags    = mem_flags,
         .domid        = domid
     };
-    set_xen_guest_handle(reservation.extent_start, extent_start);
-
-    err = xc_memory_op(xc_handle, XENMEM_populate_physmap, &reservation);
-    if ( err == nr_extents )
-        return 0;
 
-    if ( err >= 0 )
+    err = do_xenmem_op_retry(xc_handle, XENMEM_populate_physmap, &reservation, nr_extents, extent_start);
+    if ( err < 0 )
     {
         DPRINTF("Failed allocation for dom %d: %ld extents of order %d\n",
                 domid, nr_extents, extent_order);
         errno = EBUSY;
-        err = -1;
     }
 
     return err;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm.c
+++ xen-4.0.1-testing/xen/arch/x86/mm.c
@@ -3660,6 +3660,8 @@ static int create_grant_p2m_mapping(uint
         p2mt = p2m_grant_map_rw;
     rc = guest_physmap_add_entry(current->domain, addr >> PAGE_SHIFT,
                                  frame, 0, p2mt);
+    if ( rc == -ENOENT )
+        return GNTST_eagain;
     if ( rc )
         return GNTST_general_error;
     else
@@ -4315,17 +4317,25 @@ long arch_memory_op(int op, XEN_GUEST_HA
         case XENMAPSPACE_gmfn:
         {
             p2m_type_t p2mt;
+            unsigned long tmp_mfn;
 
-            xatp.idx = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
+            tmp_mfn = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
+            if ( unlikely(p2m_is_paging(p2mt)) )
+            {
+                if ( p2m_is_paged(p2mt) )
+                    p2m_mem_paging_populate(d, xatp.idx);
+                rcu_unlock_domain(d);
+                return -ENOENT;
+            }
             /* If the page is still shared, exit early */
             if ( p2m_is_shared(p2mt) )
             {
                 rcu_unlock_domain(d);
                 return -ENOMEM;
             }
-            if ( !get_page_from_pagenr(xatp.idx, d) )
+            if ( !get_page_from_pagenr(tmp_mfn, d) )
                 break;
-            mfn = xatp.idx;
+            mfn = tmp_mfn;
             page = mfn_to_page(mfn);
             break;
         }
@@ -4354,8 +4364,16 @@ long arch_memory_op(int op, XEN_GUEST_HA
                 /* Xen heap frames are simply unhooked from this phys slot. */
                 guest_physmap_remove_page(d, xatp.gpfn, prev_mfn, 0);
             else
+            {
                 /* Normal domain memory is freed, to avoid leaking memory. */
-                guest_remove_page(d, xatp.gpfn);
+                rc = guest_remove_page(d, xatp.gpfn);
+                if ( rc == -ENOENT )
+                {
+                    domain_unlock(d);
+                    rcu_unlock_domain(d);
+                    return rc;
+                }
+            }
         }
 
         /* Unmap from old location, if any. */
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
@@ -2186,6 +2186,13 @@ guest_physmap_add_entry(struct domain *d
             P2M_DEBUG("aliased! mfn=%#lx, old gfn=%#lx, new gfn=%#lx\n",
                       mfn + i, ogfn, gfn + i);
             omfn = gfn_to_mfn_query(d, ogfn, &ot);
+            if ( unlikely(p2m_is_paging(ot)) )
+            {
+                p2m_unlock(d->arch.p2m);
+                if ( p2m_is_paged(ot) )
+                    p2m_mem_paging_populate(d, ogfn);
+                return -ENOENT;
+            }
             /* If we get here, we know the local domain owns the page,
                so it can't have been grant mapped in. */
             BUG_ON( p2m_is_grant(ot) );
--- xen-4.0.1-testing.orig/xen/common/memory.c
+++ xen-4.0.1-testing/xen/common/memory.c
@@ -95,6 +95,7 @@ static void populate_physmap(struct memo
     unsigned long i, j;
     xen_pfn_t gpfn, mfn;
     struct domain *d = a->domain;
+    int rc;
 
     if ( !guest_handle_subrange_okay(a->extent_list, a->nr_done,
                                      a->nr_extents-1) )
@@ -134,7 +135,12 @@ static void populate_physmap(struct memo
             }
 
             mfn = page_to_mfn(page);
-            guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+            rc = guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+            if ( rc != 0 )
+            {
+                free_domheap_pages(page, a->extent_order);
+                goto out;
+            }
 
             if ( !paging_mode_translate(d) )
             {
@@ -162,6 +168,12 @@ int guest_remove_page(struct domain *d,
 
 #ifdef CONFIG_X86
     mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt)); 
+    if ( unlikely(p2m_is_paging(p2mt)) )
+    {
+        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(d, gmfn);
+        return -ENOENT;
+    }
 #else
     mfn = gmfn_to_mfn(d, gmfn);
 #endif
@@ -360,6 +372,13 @@ static long memory_exchange(XEN_GUEST_HA
 
                 /* Shared pages cannot be exchanged */
                 mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
+                if ( p2m_is_paging(p2mt) )
+                {
+                    if ( p2m_is_paged(p2mt) )
+                        p2m_mem_paging_populate(d, gmfn);
+                    rc = -ENOENT;
+                    goto fail;
+                }
                 if ( p2m_is_shared(p2mt) )
                 {
                     rc = -ENOMEM;
@@ -456,7 +475,9 @@ static long memory_exchange(XEN_GUEST_HA
                 &gpfn, exch.out.extent_start, (i<<out_chunk_order)+j, 1);
 
             mfn = page_to_mfn(page);
-            guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+            rc = guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+            if ( rc == -ENOENT )
+                goto fail;
 
             if ( !paging_mode_translate(d) )
             {

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 09/18] xenpaging: populate only paged-out pages
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (7 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME Olaf Hering
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.populate_only_if_paged.patch --]
[-- Type: text/plain, Size: 4239 bytes --]

populdate a paged-out page only once to reduce pressure in the ringbuffer.
Several cpus may still request a page at once. xenpaging can handle this.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 xen/arch/x86/hvm/emulate.c       |    3 ++-
 xen/arch/x86/hvm/hvm.c           |   17 ++++++++++-------
 xen/arch/x86/mm/guest_walk.c     |    3 ++-
 xen/arch/x86/mm/hap/guest_walk.c |    6 ++++--
 4 files changed, 18 insertions(+), 11 deletions(-)

--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/emulate.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/emulate.c
@@ -65,7 +65,8 @@ static int hvmemul_do_io(
     ram_mfn = gfn_to_mfn_unshare(current->domain, ram_gfn, &p2mt, 0);
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(curr->domain, ram_gfn);
+        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(curr->domain, ram_gfn);
         return X86EMUL_RETRY;
     }
     if ( p2m_is_shared(p2mt) )
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/hvm.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/hvm.c
@@ -291,7 +291,8 @@ static int hvm_set_ioreq_page(
         return -EINVAL;
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(d, gmfn);
+        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(d, gmfn);
         return -ENOENT;
     }
     if ( p2m_is_shared(p2mt) )
@@ -1324,7 +1325,8 @@ static void *hvm_map_entry(unsigned long
     mfn = mfn_x(gfn_to_mfn_unshare(current->domain, gfn, &p2mt, 0));
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(current->domain, gfn);
+        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(current->domain, gfn);
         return NULL;
     }
     if ( p2m_is_shared(p2mt) )
@@ -1723,7 +1725,8 @@ static enum hvm_copy_result __hvm_copy(
 
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(curr->domain, gfn);
+            if ( p2m_is_paged(p2mt) )
+                p2m_mem_paging_populate(curr->domain, gfn);
             return HVMCOPY_gfn_paged_out;
         }
         if ( p2m_is_shared(p2mt) )
@@ -3032,8 +3035,8 @@ long do_hvm_op(unsigned long op, XEN_GUE
             mfn_t mfn = gfn_to_mfn(d, pfn, &t);
             if ( p2m_is_paging(t) )
             {
-                p2m_mem_paging_populate(d, pfn);
-
+                if ( p2m_is_paged(t) )
+                    p2m_mem_paging_populate(d, pfn);
                 rc = -EINVAL;
                 goto param_fail3;
             }
@@ -3096,8 +3099,8 @@ long do_hvm_op(unsigned long op, XEN_GUE
             mfn = gfn_to_mfn_unshare(d, pfn, &t, 0);
             if ( p2m_is_paging(t) )
             {
-                p2m_mem_paging_populate(d, pfn);
-
+                if ( p2m_is_paged(t) )
+                    p2m_mem_paging_populate(d, pfn);
                 rc = -EINVAL;
                 goto param_fail4;
             }
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/guest_walk.c
@@ -96,7 +96,8 @@ static inline void *map_domain_gfn(struc
     *mfn = gfn_to_mfn_unshare(d, gfn_x(gfn), p2mt, 0);
     if ( p2m_is_paging(*p2mt) )
     {
-        p2m_mem_paging_populate(d, gfn_x(gfn));
+        if ( p2m_is_paged(*p2mt) )
+            p2m_mem_paging_populate(d, gfn_x(gfn));
 
         *rc = _PAGE_PAGED;
         return NULL;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/hap/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/hap/guest_walk.c
@@ -49,7 +49,8 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
     top_mfn = gfn_to_mfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt, 0);
     if ( p2m_is_paging(p2mt) )
     {
-        p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
+        if ( p2m_is_paged(p2mt) )
+            p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
 
         pfec[0] = PFEC_page_paged;
         return INVALID_GFN;
@@ -81,7 +82,8 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
         gfn_to_mfn_unshare(v->domain, gfn_x(gfn), &p2mt, 0);
         if ( p2m_is_paging(p2mt) )
         {
-            p2m_mem_paging_populate(v->domain, gfn_x(gfn));
+            if ( p2m_is_paged(p2mt) )
+                p2m_mem_paging_populate(v->domain, gfn_x(gfn));
 
             pfec[0] = PFEC_page_paged;
             return INVALID_GFN;

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (8 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 09/18] xenpaging: populate only paged-out pages Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 11/18] xenpaging: start xenpaging via config option Olaf Hering
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.MINIMUM_RESTART_TIME.patch --]
[-- Type: text/plain, Size: 596 bytes --]

Allow runlevel 6 as default runlevel.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/python/xen/xend/XendConstants.py |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConstants.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendConstants.py
@@ -92,7 +92,7 @@ DOM_STATES_OLD = [
 SHUTDOWN_TIMEOUT = (60.0 * 5)
 
 """Minimum time between domain restarts in seconds."""
-MINIMUM_RESTART_TIME = 60
+MINIMUM_RESTART_TIME = 5
 
 RESTART_IN_PROGRESS = 'xend/restart_in_progress'
 DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress'

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 11/18] xenpaging: start xenpaging via config option
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (9 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 12/18] xenpaging: add signal handling Olaf Hering
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.autostart.patch --]
[-- Type: text/plain, Size: 9324 bytes --]

Start xenpaging via config option.

TODO: add config option for pagefile directory
TODO: add libxl support
TODO: parse config values like 42K, 42M, 42G, 42%

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/examples/xmexample.hvm            |    3 +
 tools/python/README.XendConfig          |    1 
 tools/python/README.sxpcfg              |    1 
 tools/python/xen/xend/XendConfig.py     |    3 +
 tools/python/xen/xend/XendDomainInfo.py |    6 ++
 tools/python/xen/xend/image.py          |   87 ++++++++++++++++++++++++++++++++
 tools/python/xen/xm/create.py           |    5 +
 tools/python/xen/xm/xenapi_create.py    |    1 
 8 files changed, 107 insertions(+)

--- xen-4.0.1-testing.orig/tools/examples/xmexample.hvm
+++ xen-4.0.1-testing/tools/examples/xmexample.hvm
@@ -127,6 +127,9 @@ disk = [ 'file:/var/lib/xen/images/disk.
 # Device Model to be used
 device_model = 'qemu-dm'
 
+# xenpaging, number of pages
+xenpaging = 42
+
 #-----------------------------------------------------------------------------
 # boot on floppy (a), hard disk (c), Network (n) or CD-ROM (d) 
 # default: hard disk, cd-rom, floppy
--- xen-4.0.1-testing.orig/tools/python/README.XendConfig
+++ xen-4.0.1-testing/tools/python/README.XendConfig
@@ -120,6 +120,7 @@ otherConfig
                                 image.vncdisplay
                                 image.vncunused
                                 image.hvm.device_model
+                                image.hvm.xenpaging
                                 image.hvm.display
                                 image.hvm.xauthority
                                 image.hvm.vncconsole
--- xen-4.0.1-testing.orig/tools/python/README.sxpcfg
+++ xen-4.0.1-testing/tools/python/README.sxpcfg
@@ -51,6 +51,7 @@ image
   - vncunused
   (HVM)
   - device_model
+  - xenpaging
   - display
   - xauthority
   - vncconsole
--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendConfig.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendConfig.py
@@ -145,6 +145,7 @@ XENAPI_PLATFORM_CFG_TYPES = {
     'apic': int,
     'boot': str,
     'device_model': str,
+    'xenpaging': int,
     'loader': str,
     'display' : str,
     'fda': str,
@@ -508,6 +509,8 @@ class XendConfig(dict):
             self['platform']['nomigrate'] = 0
 
         if self.is_hvm():
+            if 'xenpaging' not in self['platform']:
+                self['platform']['xenpaging'] = None
             if 'timer_mode' not in self['platform']:
                 self['platform']['timer_mode'] = 1
             if 'viridian' not in self['platform']:
--- xen-4.0.1-testing.orig/tools/python/xen/xend/XendDomainInfo.py
+++ xen-4.0.1-testing/tools/python/xen/xend/XendDomainInfo.py
@@ -2439,6 +2439,7 @@ class XendDomainInfo:
 
         if self.image:
             self.image.createDeviceModel()
+            self.image.createXenPaging()
 
         #if have pass-through devs, need the virtual pci slots info from qemu
         self.pci_device_configure_boot()
@@ -2451,6 +2452,11 @@ class XendDomainInfo:
                 self.image.destroyDeviceModel()
             except Exception, e:
                 log.exception("Device model destroy failed %s" % str(e))
+            try:
+                log.debug("stopping xenpaging")
+                self.image.destroyXenPaging()
+            except Exception, e:
+                log.exception("stopping xenpaging failed %s" % str(e))
         else:
             log.debug("No device model")
 
--- xen-4.0.1-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.0.1-testing/tools/python/xen/xend/image.py
@@ -122,12 +122,14 @@ class ImageHandler:
         self.vm.permissionsVm("image/cmdline", { 'dom': self.vm.getDomid(), 'read': True } )
 
         self.device_model = vmConfig['platform'].get('device_model')
+        self.xenpaging = vmConfig['platform'].get('xenpaging')
 
         self.display = vmConfig['platform'].get('display')
         self.xauthority = vmConfig['platform'].get('xauthority')
         self.vncconsole = int(vmConfig['platform'].get('vncconsole', 0))
         self.dmargs = self.parseDeviceModelArgs(vmConfig)
         self.pid = None
+        self.xenpaging_pid = None
         rtc_timeoffset = int(vmConfig['platform'].get('rtc_timeoffset', 0))
         if int(vmConfig['platform'].get('localtime', 0)):
             if time.localtime(time.time())[8]:
@@ -392,6 +394,91 @@ class ImageHandler:
         sentinel_fifos_inuse[sentinel_path_fifo] = 1
         self.sentinel_path_fifo = sentinel_path_fifo
 
+    def createXenPaging(self):
+        if self.xenpaging is None:
+            return
+        if self.xenpaging == 0:
+            return
+        if self.xenpaging_pid:
+            return
+        xenpaging_bin = auxbin.pathTo("xenpaging")
+        args = [xenpaging_bin]
+        args = args + ([ "%d" % self.vm.getDomid()])
+        args = args + ([ "%s" % self.xenpaging])
+        env = dict(os.environ)
+        self.xenpaging_logfile = "/var/log/xen/xenpaging-%s.log" %  str(self.vm.info['name_label'])
+        logfile_mode = os.O_WRONLY|os.O_CREAT|os.O_APPEND|os.O_TRUNC
+        null = os.open("/dev/null", os.O_RDONLY)
+        logfd = os.open(self.xenpaging_logfile, logfile_mode, 0644)
+        sys.stderr.flush()
+        contract = osdep.prefork("%s:%d" % (self.vm.getName(), self.vm.getDomid()))
+        xenpaging_pid = os.fork()
+        if xenpaging_pid == 0: #child
+            try:
+                xenpaging_dir = "/var/lib/xen/xenpaging"
+                osdep.postfork(contract)
+                os.dup2(null, 0)
+                os.dup2(logfd, 1)
+                os.dup2(logfd, 2)
+                try:
+                    os.mkdir(xenpaging_dir)
+                except:
+                    log.info("mkdir %s failed" % xenpaging_dir)
+                    pass
+                try:
+                    os.chdir(xenpaging_dir)
+                except:
+                    log.warn("chdir %s failed" % xenpaging_dir)
+                try:
+                    log.info("starting %s" % args)
+                    os.execve(xenpaging_bin, args, env)
+                except Exception, e:
+                    print >>sys.stderr, (
+                        'failed to execute xenpaging: %s: %s' %
+                        xenpaging_bin, utils.exception_string(e))
+                    os._exit(126)
+            except Exception, e:
+                log.warn("staring xenpaging in %s failed" % xenpaging_dir)
+                os._exit(127)
+        else:
+            osdep.postfork(contract, abandon=True)
+            self.xenpaging_pid = xenpaging_pid
+            os.close(null)
+            os.close(logfd)
+
+    def destroyXenPaging(self):
+        if self.xenpaging is None:
+            return
+        if self.xenpaging_pid:
+            try:
+                os.kill(self.xenpaging_pid, signal.SIGHUP)
+            except OSError, exn:
+                log.exception(exn)
+            for i in xrange(100):
+                try:
+                    (p, rv) = os.waitpid(self.xenpaging_pid, os.WNOHANG)
+                    if p == self.xenpaging_pid:
+                        break
+                except OSError:
+                    # This is expected if Xend has been restarted within
+                    # the life of this domain.  In this case, we can kill
+                    # the process, but we can't wait for it because it's
+                    # not our child. We continue this loop, and after it is
+                    # terminated make really sure the process is going away
+                    # (SIGKILL).
+                    pass
+                time.sleep(0.1)
+            else:
+                log.warning("xenpaging %d took more than 10s "
+                            "to terminate: sending SIGKILL" % self.xenpaging_pid)
+                try:
+                    os.kill(self.xenpaging_pid, signal.SIGKILL)
+                    os.waitpid(self.xenpaging_pid, 0)
+                except OSError:
+                    # This happens if the process doesn't exist.
+                    pass
+        self.xenpaging_pid = None
+
     def createDeviceModel(self, restore = False):
         if self.device_model is None:
             return
--- xen-4.0.1-testing.orig/tools/python/xen/xm/create.py
+++ xen-4.0.1-testing/tools/python/xen/xm/create.py
@@ -495,6 +495,10 @@ gopts.var('nfs_root', val="PATH",
           fn=set_value, default=None,
           use="Set the path of the root NFS directory.")
 
+gopts.var('xenpaging', val='NUM',
+          fn=set_int, default=None,
+          use="Number of pages to swap.")
+
 gopts.var('device_model', val='FILE',
           fn=set_value, default=None,
           use="Path to device model program.")
@@ -1080,6 +1084,7 @@ def configure_hvm(config_image, vals):
     args = [ 'acpi', 'apic',
              'boot',
              'cpuid', 'cpuid_check',
+             'xenpaging',
              'device_model', 'display',
              'fda', 'fdb',
              'gfx_passthru', 'guest_os_type',
--- xen-4.0.1-testing.orig/tools/python/xen/xm/xenapi_create.py
+++ xen-4.0.1-testing/tools/python/xen/xm/xenapi_create.py
@@ -1086,6 +1086,7 @@ class sxp2xml:
             'acpi',
             'apic',
             'boot',
+            'xenpaging',
             'device_model',
             'loader',
             'fda',

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 12/18] xenpaging: add signal handling
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (10 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 11/18] xenpaging: start xenpaging via config option Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB Olaf Hering
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.signal_handling.patch --]
[-- Type: text/plain, Size: 4131 bytes --]

Leave paging loop if xenpaging gets a signal.
Remove paging file on exit.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/xenpaging/xenpaging.c |   39 +++++++++++++++++++++++++++++++--------
 1 file changed, 31 insertions(+), 8 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -22,6 +22,7 @@
 
 #include <inttypes.h>
 #include <stdlib.h>
+#include <signal.h>
 #include <xc_private.h>
 
 #include <xen/mem_event.h>
@@ -40,6 +41,11 @@
 #define DPRINTF(...) ((void)0)
 #endif
 
+static int interrupted;
+static void close_handler(int sig)
+{
+    interrupted = sig;
+}
 
 static void *init_page(void)
 {
@@ -244,7 +250,6 @@ int xenpaging_teardown(xenpaging_t *pagi
     if ( rc != 0 )
     {
         ERROR("Error tearing down domain paging in xen");
-        goto err;
     }
 
     /* Unbind VIRQ */
@@ -252,7 +257,6 @@ int xenpaging_teardown(xenpaging_t *pagi
     if ( rc != 0 )
     {
         ERROR("Error unbinding event port");
-        goto err;
     }
     paging->mem_event.port = -1;
 
@@ -261,7 +265,6 @@ int xenpaging_teardown(xenpaging_t *pagi
     if ( rc != 0 )
     {
         ERROR("Error closing event channel");
-        goto err;
     }
     paging->mem_event.xce_handle = -1;
     
@@ -270,7 +273,6 @@ int xenpaging_teardown(xenpaging_t *pagi
     if ( rc != 0 )
     {
         ERROR("Error closing connection to xen");
-        goto err;
     }
     paging->xc_handle = -1;
 
@@ -375,7 +377,7 @@ int xenpaging_evict_page(xenpaging_t *pa
     return ret;
 }
 
-int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp)
+static int xenpaging_resume_page(xenpaging_t *paging, mem_event_response_t *rsp)
 {
     int ret;
 
@@ -455,6 +457,11 @@ static int evict_victim(xenpaging_t *pag
             goto out;
         }
 
+        if ( interrupted )
+        {
+            ret = -EINTR;
+            goto out;
+        }
         ret = xc_mem_paging_nominate(paging->xc_handle,
                                      paging->mem_event.domain_id, victim->gfn);
         if ( ret == 0 )
@@ -479,6 +486,7 @@ static int evict_victim(xenpaging_t *pag
 
 int main(int argc, char *argv[])
 {
+    struct sigaction act;
     domid_t domain_id;
     int num_pages;
     xenpaging_t *paging;
@@ -513,7 +521,7 @@ int main(int argc, char *argv[])
     if ( paging == NULL )
     {
         ERROR("Error initialising paging");
-        goto out;
+        return 1;
     }
 
     /* Open file */
@@ -522,9 +530,18 @@ int main(int argc, char *argv[])
     if ( fd < 0 )
     {
         perror("failed to open file");
-        return -1;
+        return 2;
     }
 
+    /* ensure that if we get a signal, we'll do cleanup, then exit */
+    act.sa_handler = close_handler;
+    act.sa_flags = 0;
+    sigemptyset(&act.sa_mask);
+    sigaction(SIGHUP,  &act, NULL);
+    sigaction(SIGTERM, &act, NULL);
+    sigaction(SIGINT,  &act, NULL);
+    sigaction(SIGALRM, &act, NULL);
+
     /* Evict pages */
     memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
     for ( i = 0; i < num_pages; i++ )
@@ -532,6 +549,8 @@ int main(int argc, char *argv[])
         rc = evict_victim(paging, domain_id, &victims[i], fd, i);
         if ( rc == -ENOSPC )
             break;
+        if ( rc == -EINTR )
+            break;
         if ( i % 100 == 0 )
             DPRINTF("%d pages evicted\n", i);
     }
@@ -539,7 +558,7 @@ int main(int argc, char *argv[])
     DPRINTF("pages evicted\n");
 
     /* Swap pages in and out */
-    while ( 1 )
+    while ( !interrupted )
     {
         /* Wait for Xen to signal that a page needs paged in */
         rc = xc_wait_for_event_or_timeout(paging->mem_event.xce_handle, 100);
@@ -630,8 +649,11 @@ int main(int argc, char *argv[])
             }
         }
     }
+    DPRINTF("xenpaging got signal %d\n", interrupted);
 
  out:
+    unlink(filename);
+    close(fd);
     free(victims);
 
     /* Tear down domain paging */
@@ -642,6 +664,7 @@ int main(int argc, char *argv[])
     if ( rc == 0 )
         rc = rc1;
 
+    DPRINTF("xenpaging exit code %d\n", rc);
     return rc;
 }

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (11 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 12/18] xenpaging: add signal handling Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 14/18] xenpaging: page-in granttable entries Olaf Hering
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.MRU_SIZE.patch --]
[-- Type: text/plain, Size: 559 bytes --]

Increase recently used pages from 4MB to 64MB.
Keeping more pages in memory allows the guest to make more progress if the
paging file spans the entire guest memory.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/xenpaging/policy_default.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -26,7 +26,7 @@
 #include "policy.h"
 
 
-#define MRU_SIZE 1024
+#define MRU_SIZE (1024 * 16)
 
 
 static unsigned long mru[MRU_SIZE];

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 14/18] xenpaging: page-in granttable entries
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (12 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel Olaf Hering
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.get_paged_frame.patch --]
[-- Type: text/plain, Size: 5703 bytes --]

When converting a gfn to mfn, check if the page is paged-out.
If it is, request a page-in and return GNTST_eagain to the caller
to indicate a retry of the hypercall is required.
This fixes granttable errors when xenpaging is enabled in the guest.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>

---
 xen/common/grant_table.c |   94 ++++++++++++++++++++++++++++++-----------------
 1 file changed, 60 insertions(+), 34 deletions(-)

--- xen-4.0.1-testing.orig/xen/common/grant_table.c
+++ xen-4.0.1-testing/xen/common/grant_table.c
@@ -139,6 +139,37 @@ shared_entry_header(struct grant_table *
 #define active_entry(t, e) \
     ((t)->active[(e)/ACGNT_PER_PAGE][(e)%ACGNT_PER_PAGE])
 
+/* Check if the page has been paged out */
+static int __get_paged_frame(unsigned long gfn, unsigned long *frame, int readonly, struct domain *rd)
+{
+    p2m_type_t p2mt;
+    mfn_t mfn;
+    int rc = GNTST_okay;
+
+    if ( readonly )
+        mfn = gfn_to_mfn(rd, gfn, &p2mt);
+    else
+        mfn = gfn_to_mfn_unshare(rd, gfn, &p2mt, 1);
+
+    if ( p2m_is_valid(p2mt) )
+    {
+        *frame = mfn_x(mfn);
+        if ( p2m_is_paging(p2mt) )
+        {
+            if ( p2m_is_paged(p2mt) )
+                p2m_mem_paging_populate(rd, gfn);
+            rc = GNTST_eagain;
+        }
+    }
+    else
+    {
+        *frame = INVALID_MFN;
+        rc = GNTST_bad_page;
+    }
+
+    return rc;
+}
+
 static inline int
 __get_maptrack_handle(
     struct grant_table *t)
@@ -527,14 +558,16 @@ __gnttab_map_grant_ref(
 
         if ( !act->pin )
         {
+            unsigned long gfn;
+            unsigned long frame;
+
+            gfn = sha1 ? sha1->frame : sha2->full_page.frame;
+            rc = __get_paged_frame(gfn, &frame, !!(op->flags & GNTMAP_readonly), rd);
+            if ( rc != GNTST_okay )
+                goto unlock_out;
+            act->gfn = gfn;
             act->domid = ld->domain_id;
-            if ( sha1 )
-                act->gfn = sha1->frame;
-            else
-                act->gfn = sha2->full_page.frame;
-            act->frame = (op->flags & GNTMAP_readonly) ?  
-                            gmfn_to_mfn(rd, act->gfn) :
-                            gfn_to_mfn_private(rd, act->gfn); 
+            act->frame = frame;
             act->start = 0;
             act->length = PAGE_SIZE;
             act->is_sub_page = 0;
@@ -1697,6 +1730,7 @@ __acquire_grant_for_copy(
     domid_t trans_domid;
     grant_ref_t trans_gref;
     struct domain *rrd;
+    unsigned long gfn;
     unsigned long grant_frame;
     unsigned trans_page_off;
     unsigned trans_length;
@@ -1814,9 +1848,11 @@ __acquire_grant_for_copy(
         }
         else if ( sha1 )
         {
-            act->gfn = sha1->frame;
-            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
-                                     gfn_to_mfn_private(rd, act->gfn);
+            gfn = sha1->frame;
+            rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+            if ( rc != GNTST_okay )
+                goto unlock_out;
+            act->gfn = gfn;
             is_sub_page = 0;
             trans_page_off = 0;
             trans_length = PAGE_SIZE;
@@ -1824,9 +1860,11 @@ __acquire_grant_for_copy(
         }
         else if ( !(sha2->hdr.flags & GTF_sub_page) )
         {
-            act->gfn = sha2->full_page.frame;
-            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
-                                     gfn_to_mfn_private(rd, act->gfn);
+            gfn = sha2->full_page.frame;
+            rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+            if ( rc != GNTST_okay )
+                goto unlock_out;
+            act->gfn = gfn;
             is_sub_page = 0;
             trans_page_off = 0;
             trans_length = PAGE_SIZE;
@@ -1834,9 +1872,11 @@ __acquire_grant_for_copy(
         }
         else
         {
-            act->gfn = sha2->sub_page.frame;
-            grant_frame = readonly ? gmfn_to_mfn(rd, act->gfn) :
-                                     gfn_to_mfn_private(rd, act->gfn);
+            gfn = sha2->sub_page.frame;
+            rc = __get_paged_frame(gfn, &grant_frame, readonly, rd);
+            if ( rc != GNTST_okay )
+                goto unlock_out;
+            act->gfn = gfn;
             is_sub_page = 1;
             trans_page_off = sha2->sub_page.page_off;
             trans_length = sha2->sub_page.length;
@@ -1932,16 +1972,9 @@ __gnttab_copy(
     else
     {
 #ifdef CONFIG_X86
-        p2m_type_t p2mt;
-        s_frame = mfn_x(gfn_to_mfn(sd, op->source.u.gmfn, &p2mt));
-        if ( !p2m_is_valid(p2mt) )
-          s_frame = INVALID_MFN;
-        if ( p2m_is_paging(p2mt) )
-        {
-            p2m_mem_paging_populate(sd, op->source.u.gmfn);
-            rc = -ENOENT;
+        rc = __get_paged_frame(op->source.u.gmfn, &s_frame, 1, sd);
+        if ( rc != GNTST_okay )
             goto error_out;
-        }
 #else
         s_frame = gmfn_to_mfn(sd, op->source.u.gmfn);        
 #endif
@@ -1978,16 +2011,9 @@ __gnttab_copy(
     else
     {
 #ifdef CONFIG_X86
-        p2m_type_t p2mt;
-        d_frame = mfn_x(gfn_to_mfn_unshare(dd, op->dest.u.gmfn, &p2mt, 1));
-        if ( !p2m_is_valid(p2mt) )
-          d_frame = INVALID_MFN;
-        if ( p2m_is_paging(p2mt) )
-        {
-            p2m_mem_paging_populate(dd, op->dest.u.gmfn);
-            rc = -ENOENT;
+        rc = __get_paged_frame(op->dest.u.gmfn, &d_frame, 0, dd);
+        if ( rc != GNTST_okay )
             goto error_out;
-        }
 #else
         d_frame = gmfn_to_mfn(dd, op->dest.u.gmfn);
 #endif

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (13 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 14/18] xenpaging: page-in granttable entries Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 16/18] xenpaging: prevent page-out of first 16MB Olaf Hering
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.notify_via_xen_event_channel.patch --]
[-- Type: text/plain, Size: 845 bytes --]

Avoid crash of Xen if a xenpaging enabled guest crashes and there are still
memevents in flight, as reported here:

http://lists.xensource.com/archives/html/xen-devel/2010-08/msg00516.html

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Already-Acked-by: Patrick Colp <pjcolp@cs.ubc.ca>
Already-Acked-by: Keir Fraser <keir.fraser@citrix.com>

---
 xen/common/event_channel.c |    6 ++++++
 1 file changed, 6 insertions(+)

--- xen-4.0.1-testing.orig/xen/common/event_channel.c
+++ xen-4.0.1-testing/xen/common/event_channel.c
@@ -994,6 +994,12 @@ void notify_via_xen_event_channel(struct
 
     spin_lock(&ld->event_lock);
 
+    if ( unlikely(ld->is_dying) )
+    {
+        spin_unlock(&ld->event_lock);
+        return;
+    }
+
     ASSERT(port_is_valid(ld, lport));
     lchn = evtchn_from_port(ld, lport);
     ASSERT(lchn->consumer_is_xen);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 16/18] xenpaging: prevent page-out of first 16MB
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (14 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging Olaf Hering
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.blacklist.patch --]
[-- Type: text/plain, Size: 798 bytes --]

This is more a workaround than a bugfix:
Don't page out first 16MB of memory.
When the BIOS does its initialization process and xenpaging removes pages,
crashes will occour due to lack of support of xenpaging.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/xenpaging/policy_default.c |    5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

--- xen-4.0.1-testing.orig/tools/xenpaging/policy_default.c
+++ xen-4.0.1-testing/tools/xenpaging/policy_default.c
@@ -60,8 +60,9 @@ int policy_init(xenpaging_t *paging)
     for ( i = 0; i < MRU_SIZE; i++ )
         mru[i] = INVALID_MFN;
 
-    /* Don't page out page 0 */
-    set_bit(0, bitmap);
+    /* Don't page out first 16MB */
+    for ( i = 0; i < ((16*1024*1024)/4096); i++ )
+        set_bit(i, bitmap);
 
  out:
     return rc;

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (15 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 16/18] xenpaging: prevent page-out of first 16MB Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.autostart_delay.patch --]
[-- Type: text/plain, Size: 4269 bytes --]

This is a debug helper. Since the xenpaging support is still fragile, run
xenpaging at different stages in the bootprocess. Different delays will trigger
more bugs. This implementation starts without delay for 5 reboots, then
increments the delay by 0.1 seconds It uses xenstore for presistant storage of
delay values

TODO: find the correct place to remove the xenstore directory when the guest is shutdown or crashed

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 tools/python/xen/xend/image.py |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

--- xen-4.0.1-testing.orig/tools/python/xen/xend/image.py
+++ xen-4.0.1-testing/tools/python/xen/xend/image.py
@@ -123,6 +123,18 @@ class ImageHandler:
 
         self.device_model = vmConfig['platform'].get('device_model')
         self.xenpaging = vmConfig['platform'].get('xenpaging')
+        self.xenpaging_delay = xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay" % self.vm.info['name_label'])
+        if self.xenpaging_delay == None:
+            log.warn("XXX creating /local/domain/0/xenpaging/%s % self.vm.info['name_label'])
+            xstransact.Mkdir("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'])
+            xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay', '0.0'))
+            xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_inc', '0.1'))
+            xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_use', '5'))
+            xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_used', '0'))
+        self.xenpaging_delay = float(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay" % self.vm.info['name_label']))
+        self.xenpaging_delay_inc = float(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_inc" % self.vm.info['name_label']))
+        self.xenpaging_delay_use = int(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_use" % self.vm.info['name_label']))
+        self.xenpaging_delay_used = int(xstransact.Read("/local/domain/0/xenpaging/%s/xenpaging_delay_used" % self.vm.info['name_label']))
 
         self.display = vmConfig['platform'].get('display')
         self.xauthority = vmConfig['platform'].get('xauthority')
@@ -401,6 +413,17 @@ class ImageHandler:
             return
         if self.xenpaging_pid:
             return
+        if self.xenpaging_delay_used < self.xenpaging_delay_use:
+            self.xenpaging_delay_used += 1
+        else:
+            self.xenpaging_delay_used = 0
+            self.xenpaging_delay += self.xenpaging_delay_inc
+        log.info("delay_used %s" % self.xenpaging_delay_used)
+        log.info("delay_use %s" % self.xenpaging_delay_use)
+        log.info("delay %s" % self.xenpaging_delay)
+        log.info("delay_inc %s" % self.xenpaging_delay_inc)
+        xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay', self.xenpaging_delay))
+        xstransact.Store("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'], ('xenpaging_delay_used', self.xenpaging_delay_used))
         xenpaging_bin = auxbin.pathTo("xenpaging")
         args = [xenpaging_bin]
         args = args + ([ "%d" % self.vm.getDomid()])
@@ -430,6 +453,9 @@ class ImageHandler:
                 except:
                     log.warn("chdir %s failed" % xenpaging_dir)
                 try:
+                    if self.xenpaging_delay != 0.0:
+                        log.info("delaying xenpaging startup %s seconds ..." % self.xenpaging_delay)
+                        time.sleep(self.xenpaging_delay)
                     log.info("starting %s" % args)
                     os.execve(xenpaging_bin, args, env)
                 except Exception, e:
@@ -449,6 +475,8 @@ class ImageHandler:
     def destroyXenPaging(self):
         if self.xenpaging is None:
             return
+        # FIXME find correct place for guest shutdown or crash
+        #xstransact.Remove("/local/domain/0/xenpaging/%s" % self.vm.info['name_label'])
         if self.xenpaging_pid:
             try:
                 os.kill(self.xenpaging_pid, signal.SIGHUP)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 18/18] xenpaging: random debug statements and partial fixes
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (16 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging Olaf Hering
@ 2010-10-15 14:12 ` Olaf Hering
  2010-10-18 16:56   ` Ian Jackson
  2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
  2010-10-18 11:26 ` Tim Deegan
  19 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-15 14:12 UTC (permalink / raw)
  To: xen-devel

[-- Attachment #1: xenpaging.debug.patch --]
[-- Type: text/plain, Size: 25365 bytes --]

Debug and hacks.

Presented-by: Olaf Hering <olaf@aepfle.de>

---
 tools/firmware/hvmloader/util.c  |    5 ++++-
 tools/libxc/xc_dom_x86.c         |    2 ++
 tools/libxc/xc_domain.c          |    3 +++
 tools/libxc/xc_offline_page.c    |    1 +
 tools/xenpaging/Makefile         |    2 +-
 tools/xenpaging/xenpaging.c      |   26 +++++++++++++++++++++++++-
 tools/xentrace/formats           |    5 +++++
 xen/arch/x86/debug.c             |    2 ++
 xen/arch/x86/hvm/svm/svm.c       |    2 ++
 xen/arch/x86/hvm/vmx/vmx.c       |    4 ++++
 xen/arch/x86/mm.c                |   26 +++++++++++++++++++++++++-
 xen/arch/x86/mm/hap/guest_walk.c |    2 ++
 xen/arch/x86/mm/mem_event.c      |    9 +++++++++
 xen/arch/x86/mm/mem_sharing.c    |    4 ++++
 xen/arch/x86/mm/p2m.c            |    7 +++++++
 xen/arch/x86/mm/shadow/common.c  |    4 ++++
 xen/arch/x86/mm/shadow/multi.c   |    2 ++
 xen/common/grant_table.c         |   27 ++++++++++++++++++++++-----
 xen/common/memory.c              |    3 +++
 xen/include/asm-x86/p2m.h        |    4 ++++
 20 files changed, 131 insertions(+), 9 deletions(-)

--- xen-4.0.1-testing.orig/tools/firmware/hvmloader/util.c
+++ xen-4.0.1-testing/tools/firmware/hvmloader/util.c
@@ -329,7 +329,7 @@ void *mem_alloc(uint32_t size, uint32_t
         mfn = reserve >> PAGE_SHIFT;
 
         /* Try to allocate a brand new page in the reserved area. */
-        if ( !over_allocated )
+        if ( 0 && !over_allocated )
         {
             uint8_t delay = 0;
             xmr.domid = DOMID_SELF;
@@ -339,6 +339,7 @@ void *mem_alloc(uint32_t size, uint32_t
             set_xen_guest_handle(xmr.extent_start, &mfn);
             do {
                 rc = hypercall_memory_op(XENMEM_populate_physmap, &xmr);
+                printf("%s(%u): %x %x\n", __func__,__LINE__,rc, delay);
                 if ( rc == 0 )
                     cpu_relax();
             } while ( rc == 0 && ++delay );
@@ -364,6 +365,7 @@ void *mem_alloc(uint32_t size, uint32_t
         xatp.gpfn  = mfn;
         do {
             rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+            printf("%s(%u): %x\n", __func__,__LINE__,rc);
             if ( rc == -ENOENT )
                 cpu_relax();
         } while ( rc == -ENOENT );
@@ -622,6 +624,7 @@ uint16_t get_cpu_mhz(void)
     xatp.gpfn  = (unsigned long)shared_info >> 12;
     do {
         rc = hypercall_memory_op(XENMEM_add_to_physmap, &xatp);
+        printf("%s(%u): %x\n", __func__,__LINE__,rc);
         if ( rc == -ENOENT )
             cpu_relax();
     } while ( rc == -ENOENT );
--- xen-4.0.1-testing.orig/tools/libxc/xc_dom_x86.c
+++ xen-4.0.1-testing/tools/libxc/xc_dom_x86.c
@@ -812,6 +812,7 @@ int arch_setup_bootlate(struct xc_dom_im
         rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
         if ( rc != 0 )
         {
+            fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
             xc_dom_panic(XC_INTERNAL_ERROR, "%s: mapping shared_info failed "
                          "(pfn=0x%" PRIpfn ", rc=%d)\n",
                          __FUNCTION__, xatp.gpfn, rc);
@@ -828,6 +829,7 @@ int arch_setup_bootlate(struct xc_dom_im
             rc = xc_memory_op(dom->guest_xc, XENMEM_add_to_physmap, &xatp);
             if ( rc != 0 )
             {
+                fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
                 if ( (i > 0) && (errno == EINVAL) )
                 {
                     xc_dom_printf("%s: %d grant tables mapped\n", __FUNCTION__,
--- xen-4.0.1-testing.orig/tools/libxc/xc_domain.c
+++ xen-4.0.1-testing/tools/libxc/xc_domain.c
@@ -564,7 +564,10 @@ static int do_xenmem_op_retry(int xc_han
         }
 
         if ( err )
+        {
+            fprintf(stderr, "%s: delay reset: %d err %x count %lx start %lx delay %lu/%lu\n",__func__,cmd,err,count,start,delay,delay/666);
             delay = 0;
+        }
 
         start += err;
         count -= err;
--- xen-4.0.1-testing.orig/tools/libxc/xc_offline_page.c
+++ xen-4.0.1-testing/tools/libxc/xc_offline_page.c
@@ -517,6 +517,7 @@ static int exchange_page(int xc_handle,
     set_xen_guest_handle(exchange.out.extent_start, &out_mfn);
 
     rc = xc_memory_op(xc_handle, XENMEM_exchange, &exchange);
+    fprintf(stderr, "%s(%u) rc %x errno %x\n", __func__,__LINE__,rc,errno);
 
     if (!rc)
         *new_mfn = out_mfn;
--- xen-4.0.1-testing.orig/tools/xenpaging/Makefile
+++ xen-4.0.1-testing/tools/xenpaging/Makefile
@@ -4,7 +4,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 CFLAGS   += -I $(XEN_XC)
 CFLAGS   += -I ./
 CFLAGS   += $(CFLAGS_libxenctrl) $(CFLAGS_libxenstore)
-LDFLAGS  += $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenstore)
+LDFLAGS  += $(LDFLAGS_libxenctrl) $(LDFLAGS_libxenstore) -lrt
 
 POLICY    = default
 
--- xen-4.0.1-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.0.1-testing/tools/xenpaging/xenpaging.c
@@ -21,6 +21,7 @@
 
 
 #include <inttypes.h>
+#include <time.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <xc_private.h>
@@ -249,6 +250,7 @@ int xenpaging_teardown(xenpaging_t *pagi
     rc = xc_mem_event_disable(paging->xc_handle, paging->mem_event.domain_id);
     if ( rc != 0 )
     {
+        fprintf(stderr, "%s: rc %x errno %x\n", __func__, rc, errno);
         ERROR("Error tearing down domain paging in xen");
     }
 
@@ -370,6 +372,7 @@ int xenpaging_evict_page(xenpaging_t *pa
         goto out;
     }
 
+    fprintf(stderr, "%s(%u) > gfn %lx pageslot %d\n", __func__, __LINE__, victim->gfn, i);
     /* Notify policy of page being paged out */
     policy_notify_paged_out(paging->mem_event.domain_id, victim->gfn);
 
@@ -406,6 +409,8 @@ static int xenpaging_populate_page(
     void *page;
     int ret;
 
+    _gfn = *gfn;
+    fprintf(stderr, "%s(%u) < gfn %lx pageslot %d\n", __func__, __LINE__, _gfn, i);
     /* Tell Xen to allocate a page for the domain */
     ret = xc_mem_paging_prep(paging->xc_handle, paging->mem_event.domain_id,
                              *gfn);
@@ -441,6 +446,17 @@ static int xenpaging_populate_page(
     return ret;
 }
 
+static void time_diff(struct timespec *start, struct timespec *end, struct timespec *diff)
+{
+    if ((end->tv_nsec - start->tv_nsec) < 0) {
+        diff->tv_sec = end->tv_sec - start->tv_sec - 1;
+        diff->tv_nsec = 1000000000 + end->tv_nsec - start->tv_nsec;
+    } else {
+        diff->tv_sec = end->tv_sec - start->tv_sec;
+        diff->tv_nsec = end->tv_nsec - start->tv_nsec;
+    }
+}
+
 static int evict_victim(xenpaging_t *paging, domid_t domain_id,
                         xenpaging_victim_t *victim, int fd, int i)
 {
@@ -501,6 +517,7 @@ int main(int argc, char *argv[])
     mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
     char filename[80];
     int fd;
+    struct timespec ce, cl, cd;
 
     if ( argc != 3 )
     {
@@ -544,6 +561,8 @@ int main(int argc, char *argv[])
 
     /* Evict pages */
     memset(victims, 0, sizeof(xenpaging_victim_t) * num_pages);
+    if (clock_gettime(CLOCK_MONOTONIC, &ce))
+        perror("clock_gettime");
     for ( i = 0; i < num_pages; i++ )
     {
         rc = evict_victim(paging, domain_id, &victims[i], fd, i);
@@ -554,7 +573,10 @@ int main(int argc, char *argv[])
         if ( i % 100 == 0 )
             DPRINTF("%d pages evicted\n", i);
     }
-
+    if (clock_gettime(CLOCK_MONOTONIC, &cl))
+        perror("clock_gettime");
+    time_diff(&ce, &cl, &cd);
+    DPRINTF("%s: c %d.%09d\n", __func__, (int)cd.tv_sec, (int)cd.tv_nsec);
     DPRINTF("pages evicted\n");
 
     /* Swap pages in and out */
@@ -625,8 +647,10 @@ int main(int argc, char *argv[])
             else
             {
                 DPRINTF("page already populated (domain = %d; vcpu = %d;"
+                        " p2mt = %x;"
                         " gfn = %"PRIx64"; paused = %"PRId64")\n",
                         paging->mem_event.domain_id, req.vcpu_id,
+                        req.p2mt,
                         req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
 
                 /* Tell Xen to resume the vcpu */
--- xen-4.0.1-testing.orig/tools/xentrace/formats
+++ xen-4.0.1-testing/tools/xentrace/formats
@@ -5,6 +5,7 @@
 0x0001f003  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  cpu_change        0x%(1)08x
 0x0001f004  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  trace_irq    [ vector = %(1)d, count = %(2)d, tot_cycles = 0x%(3)08x, max_cycles = 0x%(4)08x ]
 
+0x00021002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  continue_running    [ dom:vcpu = 0x%(1)08x ]
 0x00021011  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  running_to_runnable [ dom:vcpu = 0x%(1)08x ]
 0x00021021  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  running_to_blocked  [ dom:vcpu = 0x%(1)08x ]
 0x00021031  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  running_to_offline  [ dom:vcpu = 0x%(1)08x ]
@@ -70,10 +71,14 @@
 0x00082018  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  CLTS
 0x00082019  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  LMSW        [ value = 0x%(1)08x ]
 0x00082119  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  LMSW        [ value = 0x%(2)08x%(1)08x ]
+0x00082020  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  INTR_WINDOW [ value = 0x%(1)08x ]
+0x00082021  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  NPF         [ gpa = 0x%(2)08x%(1)08x mfn = 0x%(4)08x%(3)08x qual = 0x%(5)04x p2mt = 0x%(6)04x ]
 
 0x0010f001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_map      [ domid = %(1)d ]
 0x0010f002  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_unmap    [ domid = %(1)d ]
 0x0010f003  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  page_grant_transfer [ domid = %(1)d ]
+0x0010f004  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  p2m_set_entry [ gfn 0x%(2)08x%(1)08x mfn 0x%(4)08x%(3)08x pmt 0x%(5)08x domain:order 0x%(6)08x ]
+0x0010f005  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  decrease_reservation [ gfn 0x%(2)08x%(1)08x domain:order 0x%(3)08x ]
 
 0x0020f001  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  hypercall  [ eip = 0x%(1)08x, eax = 0x%(2)08x ]
 0x0020f101  CPU%(cpu)d  %(tsc)d (+%(reltsc)8d)  hypercall  [ rip = 0x%(2)08x%(1)08x, eax = 0x%(3)08x ]
--- xen-4.0.1-testing.orig/xen/arch/x86/debug.c
+++ xen-4.0.1-testing/xen/arch/x86/debug.c
@@ -62,6 +62,8 @@ dbg_hvm_va2mfn(dbgva_t vaddr, struct dom
     }
 
     mfn = mfn_x(gfn_to_mfn(dp, gfn, &gfntype)); 
+if ( p2m_is_paging(gfntype) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,gfntype);
     if ( p2m_is_readonly(gfntype) && toaddr )
     {
         DBGP2("kdb:p2m_is_readonly: gfntype:%x\n", gfntype);
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/svm/svm.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/svm/svm.c
@@ -232,6 +232,8 @@ static int svm_vmcb_restore(struct vcpu
         if ( c->cr0 & X86_CR0_PG )
         {
             mfn = mfn_x(gfn_to_mfn(v->domain, c->cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %"PRIx64" p2m %x\n",__func__,c->cr3,p2mt);
             if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
             {
                 gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%"PRIx64"\n",
--- xen-4.0.1-testing.orig/xen/arch/x86/hvm/vmx/vmx.c
+++ xen-4.0.1-testing/xen/arch/x86/hvm/vmx/vmx.c
@@ -496,6 +496,8 @@ static int vmx_restore_cr0_cr3(
         if ( cr0 & X86_CR0_PG )
         {
             mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,cr3,p2mt);
             if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) )
             {
                 gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3);
@@ -1012,6 +1014,8 @@ static void vmx_load_pdptrs(struct vcpu
         goto crash;
 
     mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt));
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,cr3,p2mt);
     if ( !p2m_is_ram(p2mt) )
         goto crash;
 
--- xen-4.0.1-testing.orig/xen/arch/x86/mm.c
+++ xen-4.0.1-testing/xen/arch/x86/mm.c
@@ -3148,7 +3148,8 @@ int do_mmu_update(
 
                 rc = -ENOENT;
                 break;
-            }
+            } else if ( p2m_is_paging(p2mt) )
+                MEM_LOG("gfn %lx p2m %x", gmfn, p2mt);
 
             if ( unlikely(!get_page_from_pagenr(mfn, pt_owner)) )
             {
@@ -3224,6 +3225,8 @@ int do_mmu_update(
                         rc = -ENOENT;
                         break;
                     }
+                    else if ( p2m_is_paging(l2e_p2mt) )
+                        MEM_LOG("gfn %lx p2m %x", l2e_get_pfn(l2e), l2e_p2mt);
                     else if ( p2m_ram_shared == l2e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -3254,6 +3257,8 @@ int do_mmu_update(
                         rc = -ENOENT;
                         break;
                     }
+                    else if ( p2m_is_paging(l3e_p2mt) )
+                        MEM_LOG("gfn %lx p2m %x", l3e_get_pfn(l3e), l3e_p2mt);
                     else if ( p2m_ram_shared == l3e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -3285,6 +3290,8 @@ int do_mmu_update(
                         rc = -ENOENT;
                         break;
                     }
+                    else if ( p2m_is_paging(l4e_p2mt) )
+                        MEM_LOG("gfn %lx p2m %x", l4e_get_pfn(l4e), l4e_p2mt);
                     else if ( p2m_ram_shared == l4e_p2mt )
                     {
                         MEM_LOG("Unexpected attempt to map shared page.\n");
@@ -4322,6 +4329,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
             tmp_mfn = mfn_x(gfn_to_mfn_unshare(d, xatp.idx, &p2mt, 0));
             if ( unlikely(p2m_is_paging(p2mt)) )
             {
+printk("%s(%u) gfn %lx p2m %x\n",__func__,__LINE__,xatp.idx, p2mt);
                 if ( p2m_is_paged(p2mt) )
                     p2m_mem_paging_populate(d, xatp.idx);
                 rcu_unlock_domain(d);
@@ -4337,6 +4345,21 @@ long arch_memory_op(int op, XEN_GUEST_HA
                 break;
             mfn = tmp_mfn;
             page = mfn_to_page(mfn);
+
+            gpfn = get_gpfn_from_mfn(tmp_mfn);
+            ASSERT( gpfn != SHARED_M2P_ENTRY );
+            gfn_to_mfn(d, gpfn, &p2mt);
+            if ( unlikely(p2m_is_paging(p2mt)) )
+            {
+printk("%s(%u) gfn %lx p2m %x\n",__func__,__LINE__, gpfn, p2mt);
+                if ( page )
+                    put_page(page);
+                if ( p2m_is_paged(p2mt) )
+                    p2m_mem_paging_populate(d, gpfn);
+                rcu_unlock_domain(d);
+                return -ENOENT;
+            }
+
             break;
         }
         default:
@@ -4369,6 +4392,7 @@ long arch_memory_op(int op, XEN_GUEST_HA
                 rc = guest_remove_page(d, xatp.gpfn);
                 if ( rc == -ENOENT )
                 {
+                    MEM_LOG("gfn %lx", xatp.gpfn);
                     domain_unlock(d);
                     rcu_unlock_domain(d);
                     return rc;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/hap/guest_walk.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/hap/guest_walk.c
@@ -49,6 +49,7 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
     top_mfn = gfn_to_mfn_unshare(v->domain, cr3 >> PAGE_SHIFT, &p2mt, 0);
     if ( p2m_is_paging(p2mt) )
     {
+printk("%s: gfn %lx p2m %x\n",__func__,cr3 >> PAGE_SHIFT,p2mt);
         if ( p2m_is_paged(p2mt) )
             p2m_mem_paging_populate(v->domain, cr3 >> PAGE_SHIFT);
 
@@ -82,6 +83,7 @@ unsigned long hap_gva_to_gfn(GUEST_PAGIN
         gfn_to_mfn_unshare(v->domain, gfn_x(gfn), &p2mt, 0);
         if ( p2m_is_paging(p2mt) )
         {
+printk("%s: gfn %lx p2m %x\n",__func__,gfn_x(gfn),p2mt);
             if ( p2m_is_paged(p2mt) )
                 p2m_mem_paging_populate(v->domain, gfn_x(gfn));
 
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_event.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_event.c
@@ -68,6 +68,7 @@ int mem_event_enable(struct domain *d, m
     d->mem_event.paused = 0;
     d->mem_event.enabled = 1;
 
+printk("%s %u\n",__func__, d->domain_id);
     return 0;
 
  err_shared:
@@ -82,6 +83,7 @@ int mem_event_enable(struct domain *d, m
 
 int mem_event_disable(struct domain *d)
 {
+printk("%s %u\n",__func__, d->domain_id);
     d->mem_event.enabled = 0;
     d->mem_event.paused = 0;
 
@@ -168,6 +170,9 @@ int mem_event_check_ring(struct domain *
     mem_event_ring_lock(d);
 
     free_requests = RING_FREE_REQUESTS(&d->mem_event.front_ring);
+    if ( free_requests < 3 )
+        gdprintk(XENLOG_INFO, "frq %d\n", free_requests);
+    WARN_ON(free_requests == 0);
     ring_full = free_requests < MEM_EVENT_RING_THRESHOLD;
 
     if ( (current->domain->domain_id == d->domain_id) && ring_full )
@@ -243,6 +248,8 @@ int mem_event_domctl(struct domain *d, x
             guest_get_eff_l1e(v, ring_addr, &l1e);
             gfn = l1e_get_pfn(l1e);
             ring_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
 
             rc = -EINVAL;
             if ( unlikely(!mfn_valid(mfn_x(ring_mfn))) )
@@ -252,6 +259,8 @@ int mem_event_domctl(struct domain *d, x
             guest_get_eff_l1e(v, shared_addr, &l1e);
             gfn = l1e_get_pfn(l1e);
             shared_mfn = gfn_to_mfn(dom_mem_event, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
 
             rc = -EINVAL;
             if ( unlikely(!mfn_valid(mfn_x(shared_mfn))) )
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/mem_sharing.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/mem_sharing.c
@@ -381,6 +381,8 @@ int mem_sharing_debug_gfn(struct domain
     struct page_info *page;
 
     mfn = gfn_to_mfn(d, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
     page = mfn_to_page(mfn);
 
     printk("Debug for domain=%d, gfn=%lx, ", 
@@ -636,6 +638,8 @@ int mem_sharing_unshare_page(struct doma
     struct list_head *le;
 
     mfn = gfn_to_mfn(d, gfn, &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__,gfn,p2mt);
 
     page = mfn_to_page(mfn);
     handle = page->shr_handle;
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/p2m.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/p2m.c
@@ -2005,6 +2005,8 @@ p2m_remove_page(struct domain *d, unsign
         mfn_return = d->arch.p2m->get_entry(d, gfn + i, &t, p2m_query);
         if ( !p2m_is_grant(t) )
             set_gpfn_from_mfn(mfn+i, INVALID_M2P_ENTRY);
+        if (!( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) ))
+        printk("%s(%u) i %lu t %x gfn %lx mfn %lx ret %lx %lu %d\n",__func__,__LINE__,i,t,gfn,mfn,mfn_x(mfn_return), p2m_is_valid(t), mfn + i == mfn_x(mfn_return));
         ASSERT( !p2m_is_valid(t) || mfn + i == mfn_x(mfn_return) );
     }
     set_p2m_entry(d, gfn, _mfn(INVALID_MFN), page_order, p2m_invalid);
@@ -2115,6 +2117,8 @@ guest_physmap_add_entry(struct domain *d
     int pod_count = 0;
     int rc = 0;
 
+    if ( p2m_is_paging(t) )
+        gdprintk(XENLOG_ERR, "d %u gfn %lx mfn %lx o %x p2m %x\n", d->domain_id, gfn, mfn, page_order, t);
     if ( !paging_mode_translate(d) )
     {
         if ( need_iommu(d) && t == p2m_ram_rw )
@@ -2147,6 +2151,8 @@ guest_physmap_add_entry(struct domain *d
     for ( i = 0; i < (1UL << page_order); i++ )
     {
         omfn = gfn_to_mfn_query(d, gfn + i, &ot);
+        if ( p2m_is_paging(ot) )
+            gdprintk(XENLOG_ERR, "d %u gfn %lx omfn %lx o %x i %lx p2m %x\n", d->domain_id, gfn, mfn_x(omfn), page_order, i, ot);
         if ( p2m_is_grant(ot) )
         {
             /* Really shouldn't be unmapping grant maps this way */
@@ -2188,6 +2194,7 @@ guest_physmap_add_entry(struct domain *d
             omfn = gfn_to_mfn_query(d, ogfn, &ot);
             if ( unlikely(p2m_is_paging(ot)) )
             {
+                gdprintk(XENLOG_ERR, "d %u gfn %lx omfn %lx o %x i %lx p2m %x\n", d->domain_id, ogfn, mfn_x(omfn), page_order, i, ot);
                 p2m_unlock(d->arch.p2m);
                 if ( p2m_is_paged(ot) )
                     p2m_mem_paging_populate(d, ogfn);
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/shadow/common.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/shadow/common.c
@@ -3720,6 +3720,8 @@ int shadow_track_dirty_vram(struct domai
             int dirty = 0;
             paddr_t sl1ma = dirty_vram->sl1ma[i];
 
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__,begin_pfn +i,t);
             if (mfn_x(mfn) == INVALID_MFN)
             {
                 dirty = 1;
@@ -3801,6 +3803,8 @@ int shadow_track_dirty_vram(struct domai
                  * write access */
                 for ( i = begin_pfn; i < end_pfn; i++ ) {
                     mfn_t mfn = gfn_to_mfn(d, i, &t);
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__,i,t);
                     if (mfn_x(mfn) != INVALID_MFN)
                         flush_tlb |= sh_remove_write_access(d->vcpu[0], mfn, 1, 0);
                 }
--- xen-4.0.1-testing.orig/xen/arch/x86/mm/shadow/multi.c
+++ xen-4.0.1-testing/xen/arch/x86/mm/shadow/multi.c
@@ -4795,6 +4795,8 @@ static mfn_t emulate_gva_to_mfn(struct v
         mfn = gfn_to_mfn_query(v->domain, _gfn(gfn), &p2mt);
     else
         mfn = gfn_to_mfn(v->domain, _gfn(gfn), &p2mt);
+if ( p2m_is_paging(p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__, gfn,p2mt);
         
     if ( p2m_is_readonly(p2mt) )
         return _mfn(READONLY_GFN);
--- xen-4.0.1-testing.orig/xen/common/grant_table.c
+++ xen-4.0.1-testing/xen/common/grant_table.c
@@ -1447,6 +1447,7 @@ gnttab_transfer(
     struct domain *d = current->domain;
     struct domain *e;
     struct page_info *page;
+    int rc;
     int i;
     struct gnttab_transfer gop;
     unsigned long mfn;
@@ -1465,7 +1466,12 @@ gnttab_transfer(
             return -EFAULT;
         }
 
-        mfn = gfn_to_mfn_private(d, gop.mfn);
+        rc = __get_paged_frame(gop.mfn, &mfn, 0, d);
+        if ( rc == GNTST_eagain )
+        {
+            gop.status = GNTST_eagain;
+            goto copyback;
+        }
 
         /* Check the passed page frame for basic validity. */
         if ( unlikely(!mfn_valid(mfn)) )
@@ -1580,28 +1586,39 @@ gnttab_transfer(
         /* Tell the guest about its new page frame. */
         spin_lock(&e->grant_table->lock);
 
+        gop.status = GNTST_okay;
+
         if ( e->grant_table->gt_version == 1 )
         {
             grant_entry_v1_t *sha = &shared_entry_v1(e->grant_table, gop.ref);
-            guest_physmap_add_page(e, sha->frame, mfn, 0);
+            rc = guest_physmap_add_page(e, sha->frame, mfn, 0);
+            if ( rc == -ENOENT )
+            {
+                gop.status = GNTST_eagain;
+                goto unlock_granttable_and_copyback;
+            }
             sha->frame = mfn;
         }
         else
         {
             grant_entry_v2_t *sha = &shared_entry_v2(e->grant_table, gop.ref);
-            guest_physmap_add_page(e, sha->full_page.frame, mfn, 0);
+            rc = guest_physmap_add_page(e, sha->full_page.frame, mfn, 0);
+            if ( rc == -ENOENT )
+            {
+                gop.status = GNTST_eagain;
+                goto unlock_granttable_and_copyback;
+            }
             sha->full_page.frame = mfn;
         }
         wmb();
         shared_entry_header(e->grant_table, gop.ref)->flags |=
             GTF_transfer_completed;
 
+    unlock_granttable_and_copyback:
         spin_unlock(&e->grant_table->lock);
 
         rcu_unlock_domain(e);
 
-        gop.status = GNTST_okay;
-
     copyback:
         if ( unlikely(__copy_to_guest_offset(uop, i, &gop, 1)) )
         {
--- xen-4.0.1-testing.orig/xen/common/memory.c
+++ xen-4.0.1-testing/xen/common/memory.c
@@ -138,6 +138,7 @@ static void populate_physmap(struct memo
             rc = guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
             if ( rc != 0 )
             {
+                gdprintk(XENLOG_INFO, "%s: rc %x\n", __func__, rc);
                 free_domheap_pages(page, a->extent_order);
                 goto out;
             }
@@ -170,6 +171,7 @@ int guest_remove_page(struct domain *d,
     mfn = mfn_x(gfn_to_mfn(d, gmfn, &p2mt)); 
     if ( unlikely(p2m_is_paging(p2mt)) )
     {
+        gdprintk(XENLOG_INFO, "d %u gfn %lx mfn %lx p2m %x\n", d->domain_id, gmfn, mfn, p2mt);
         if ( p2m_is_paged(p2mt) )
             p2m_mem_paging_populate(d, gmfn);
         return -ENOENT;
@@ -374,6 +376,7 @@ static long memory_exchange(XEN_GUEST_HA
                 mfn = mfn_x(gfn_to_mfn_unshare(d, gmfn + k, &p2mt, 0));
                 if ( p2m_is_paging(p2mt) )
                 {
+                    printk("%s: gfn %lx p2m %x\n",__func__,gmfn+k,p2mt);
                     if ( p2m_is_paged(p2mt) )
                         p2m_mem_paging_populate(d, gmfn);
                     rc = -ENOENT;
--- xen-4.0.1-testing.orig/xen/include/asm-x86/p2m.h
+++ xen-4.0.1-testing/xen/include/asm-x86/p2m.h
@@ -329,6 +329,8 @@ static inline mfn_t gfn_to_mfn_unshare(s
             return mfn;
         }
         mfn = gfn_to_mfn(d, gfn, p2mt);
+if ( p2m_is_paging(*p2mt) )
+printk("%s: gfn %lx p2m %x\n",__func__, gfn,*p2mt);
     }
 #endif
 
@@ -342,6 +344,8 @@ static inline unsigned long gmfn_to_mfn(
     mfn_t mfn;
     p2m_type_t t;
     mfn = gfn_to_mfn(d, gpfn, &t);
+if ( p2m_is_paging(t) )
+printk("%s: gfn %lx p2m %x\n",__func__, gpfn,t);
     if ( p2m_is_valid(t) )
         return mfn_x(mfn);
     return INVALID_MFN;

^ permalink raw reply	[flat|nested] 31+ messages in thread

* RE: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (17 preceding siblings ...)
  2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
@ 2010-10-15 15:05 ` Dan Magenheimer
  2010-10-18 13:03   ` Olaf Hering
  2010-10-22  8:55   ` Olaf Hering
  2010-10-18 11:26 ` Tim Deegan
  19 siblings, 2 replies; 31+ messages in thread
From: Dan Magenheimer @ 2010-10-15 15:05 UTC (permalink / raw)
  To: Olaf Hering, xen-devel

Hi Olaf --

Since you have obviously become an expert user of xenpaging,
any chance you could write brief how-to documentation for it
and maybe add a file to xen.hg/docs/misc?

Thanks,
Dan

> -----Original Message-----
> From: Olaf Hering [mailto:olaf@aepfle.de]
> Sent: Friday, October 15, 2010 8:12 AM
> To: xen-devel@lists.xensource.com
> Subject: [Xen-devel] [PATCH 00/18] xenpaging changes for 4.0
> 
> 
> Here are some changes for xenpaging in the 4.0 branch.
> 
> Its just for review and comments.  All changes are also needed for
> xen-unstable, I will prepare a patch queue also for this branch.
> 
> There are still issues with xenpaging.
> My testsetup is a SLES11 SP1 guest with runlevel 6 as default runlevel
> to
> trigger automatic reboot.  After a few iterations, there will be MMIO
> emulation
> errors.  This happens with a startup delay of 15.0 seconds.
> 
> Another issue:
> If the startup delay is 0.0, and over_allocated in hvmloader mem_alloc
> is
> forced to be active, the ASSERT in p2m_remove_page() triggers. This is
> because
> the passed mfn and the mfn returned by ->get_entry() do not match.  So
> far I
> have no idea where the appearently missing set_gpfn_from_mfn() should
> go to.
> Normally over_allocated is not set because the XENMEM_populate_physmap
> call
> does not fail.
> 
> Olaf
> 
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
                   ` (18 preceding siblings ...)
  2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
@ 2010-10-18 11:26 ` Tim Deegan
  2010-10-18 13:06   ` Olaf Hering
  2010-10-18 16:57   ` Ian Jackson
  19 siblings, 2 replies; 31+ messages in thread
From: Tim Deegan @ 2010-10-18 11:26 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel@lists.xensource.com

Hi Olaf,

Thanks for all your work on this!

These patches look pretty good to me, with a few caveats:
- Is it possible to avoid having quite so many paths return ENOENT?
  In particular, there seemed to be paths where _removing_ a p2m entry
  that's paged out caused an error.  Would it be possible to have some of
  those cases fixed up from the paging code instead?
- The usual way to get patches into the 4.0 tree is to submit them
  againts xen-unstable and then ask for specific patches to be
  backported; I see you're already going that way with most of these.
- I imagine the tools maintainers will encourage you to do your tools
  patches againsl xl/libxl as well. :)

Cheers,

Tim.

At 15:12 +0100 on 15 Oct (1287155522), Olaf Hering wrote:
> Here are some changes for xenpaging in the 4.0 branch.
> 
> Its just for review and comments.  All changes are also needed for
> xen-unstable, I will prepare a patch queue also for this branch.
> 
> There are still issues with xenpaging.
> My testsetup is a SLES11 SP1 guest with runlevel 6 as default runlevel to
> trigger automatic reboot.  After a few iterations, there will be MMIO emulation
> errors.  This happens with a startup delay of 15.0 seconds.
> 
> Another issue:
> If the startup delay is 0.0, and over_allocated in hvmloader mem_alloc is
> forced to be active, the ASSERT in p2m_remove_page() triggers. This is because
> the passed mfn and the mfn returned by ->get_entry() do not match.  So far I
> have no idea where the appearently missing set_gpfn_from_mfn() should go to.
> Normally over_allocated is not set because the XENMEM_populate_physmap call
> does not fail.
> 
> Olaf
> 
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

-- 
Tim Deegan <Tim.Deegan@citrix.com>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd.  (Company #02937203, SL9 0BG)

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
@ 2010-10-18 13:03   ` Olaf Hering
  2010-10-22  8:55   ` Olaf Hering
  1 sibling, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 13:03 UTC (permalink / raw)
  To: Dan Magenheimer; +Cc: xen-devel

On Fri, Oct 15, Dan Magenheimer wrote:

> Hi Olaf --
> 
> Since you have obviously become an expert user of xenpaging,
> any chance you could write brief how-to documentation for it
> and maybe add a file to xen.hg/docs/misc?

Dan,

yes I will write something, which I will send with the next round of
patches for xen-unstable.

Olaf

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-18 11:26 ` Tim Deegan
@ 2010-10-18 13:06   ` Olaf Hering
  2010-10-22  9:04     ` Tim Deegan
  2010-10-18 16:57   ` Ian Jackson
  1 sibling, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 13:06 UTC (permalink / raw)
  To: Tim Deegan; +Cc: xen-devel@lists.xensource.com

On Mon, Oct 18, Tim Deegan wrote:

> These patches look pretty good to me, with a few caveats:
> - Is it possible to avoid having quite so many paths return ENOENT?
>   In particular, there seemed to be paths where _removing_ a p2m entry
>   that's paged out caused an error.  Would it be possible to have some of
>   those cases fixed up from the paging code instead?

I'm not sure if thats possible.
Thats currently beyond my knowledge, sorry.
Any pointer for how to do that are welcome.

> - The usual way to get patches into the 4.0 tree is to submit them
>   againts xen-unstable and then ask for specific patches to be
>   backported; I see you're already going that way with most of these.

Yes, just wanted to send my current state and all of them are also
needed for xen-unstable

> - I imagine the tools maintainers will encourage you to do your tools
>   patches againsl xl/libxl as well. :)

Sure, that will be done as well.


Olaf

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
  2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
@ 2010-10-18 16:54   ` Ian Jackson
  2010-10-18 17:04     ` Olaf Hering
  0 siblings, 1 reply; 31+ messages in thread
From: Ian Jackson @ 2010-10-18 16:54 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> -        ERROR("Error initialising shared page");
> +        switch ( errno ) {
> +            case EBUSY:
> +                ERROR("xenpaging is (or was) active on this domain");
> +                break;
> +            case ENODEV:
> +                ERROR("EPT not supported for this guest");
> +                break;
> +            default:
> +                ERROR("Error initialising shared page");
> +                break;

Surely this should print the actual errno value.

> +            /* Only one xenpaging at a time. If xenpaging crashed,
> +             * the cache is in an undefined state and so is the guest
> +             */
> +            rc = -EBUSY;
> +            if ( d->mem_event.enabled )
> +                break;

Is there any way to recover from this or is the guest just hosed ?

Ian.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 18/18] xenpaging: random debug statements and partial fixes
  2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
@ 2010-10-18 16:56   ` Ian Jackson
  2010-10-18 17:05     ` Olaf Hering
  0 siblings, 1 reply; 31+ messages in thread
From: Ian Jackson @ 2010-10-18 16:56 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 18/18] xenpaging: random debug statements and partial fixes"):
> Debug and hacks.

Are you sure this patch is intended to be in this series ?

Ian.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-18 11:26 ` Tim Deegan
  2010-10-18 13:06   ` Olaf Hering
@ 2010-10-18 16:57   ` Ian Jackson
  1 sibling, 0 replies; 31+ messages in thread
From: Ian Jackson @ 2010-10-18 16:57 UTC (permalink / raw)
  To: Tim Deegan; +Cc: Olaf Hering, xen-devel@lists.xensource.com

Tim Deegan writes ("Re: [Xen-devel] [PATCH 00/18] xenpaging changes for 4.0"):
> - The usual way to get patches into the 4.0 tree is to submit them
>   againts xen-unstable and then ask for specific patches to be
>   backported; I see you're already going that way with most of these.

I would certainly like to try out these changes in xen-unstable
first.

> - I imagine the tools maintainers will encourage you to do your tools
>   patches againsl xl/libxl as well. :)

Yes, in xen-unstable at least.

Ian.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
  2010-10-18 16:54   ` Ian Jackson
@ 2010-10-18 17:04     ` Olaf Hering
  2010-10-19 10:17       ` Ian Jackson
  0 siblings, 1 reply; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 17:04 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Mon, Oct 18, Ian Jackson wrote:

> Olaf Hering writes ("[Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> > -        ERROR("Error initialising shared page");
> > +        switch ( errno ) {
> > +            case EBUSY:
> > +                ERROR("xenpaging is (or was) active on this domain");
> > +                break;
> > +            case ENODEV:
> > +                ERROR("EPT not supported for this guest");
> > +                break;
> > +            default:
> > +                ERROR("Error initialising shared page");
> > +                break;
> 
> Surely this should print the actual errno value.

Ok, can be done.

> > +            /* Only one xenpaging at a time. If xenpaging crashed,
> > +             * the cache is in an undefined state and so is the guest
> > +             */
> > +            rc = -EBUSY;
> > +            if ( d->mem_event.enabled )
> > +                break;
> 
> Is there any way to recover from this or is the guest just hosed ?

If xenpaging dies for some reason, the bitmap which maps the "pageslot"
in the pagefile to the gfn in the guest is gone. There is no way to
recover from this situation. If the paging state should be persistant,
then the maintained bitmaps have to be kept in memory and each page write
has to be fsynced in some way.
Some other way has to be found to prevent two xenpaging runs per
domain_id.

Olaf

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 18/18] xenpaging: random debug statements and partial fixes
  2010-10-18 16:56   ` Ian Jackson
@ 2010-10-18 17:05     ` Olaf Hering
  0 siblings, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-18 17:05 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Mon, Oct 18, Ian Jackson wrote:

> Olaf Hering writes ("[Xen-devel] [PATCH 18/18] xenpaging: random debug statements and partial fixes"):
> > Debug and hacks.
> 
> Are you sure this patch is intended to be in this series ?

Not really, its just my playground.

Olaf

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest
  2010-10-18 17:04     ` Olaf Hering
@ 2010-10-19 10:17       ` Ian Jackson
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Jackson @ 2010-10-19 10:17 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel@lists.xensource.com

Olaf Hering writes ("Re: [Xen-devel] [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest"):
> On Mon, Oct 18, Ian Jackson wrote:
> > Is there any way to recover from this or is the guest just hosed ?
> 
> If xenpaging dies for some reason, the bitmap which maps the "pageslot"
> in the pagefile to the gfn in the guest is gone. There is no way to
> recover from this situation. If the paging state should be persistant,
> then the maintained bitmaps have to be kept in memory and each page write
> has to be fsynced in some way.
> Some other way has to be found to prevent two xenpaging runs per
> domain_id.

OK, I just thought I'd ask.

Ian.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
  2010-10-18 13:03   ` Olaf Hering
@ 2010-10-22  8:55   ` Olaf Hering
  1 sibling, 0 replies; 31+ messages in thread
From: Olaf Hering @ 2010-10-22  8:55 UTC (permalink / raw)
  To: Dan Magenheimer; +Cc: xen-devel

On Fri, Oct 15, Dan Magenheimer wrote:

> Hi Olaf --
> 
> Since you have obviously become an expert user of xenpaging,
> any chance you could write brief how-to documentation for it
> and maybe add a file to xen.hg/docs/misc?

This is a first draft.


Subject: xenpaging: (sparse) documenation

Write up some sparse documentation about xenpaging usage.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

---
 docs/misc/xenpaging.txt |   40 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 40 insertions(+)

--- /dev/null
+++ xen-4.0.1-testing/docs/misc/xenpaging.txt
@@ -0,0 +1,40 @@
+Warning:
+
+The xenpaging code is new and not fully debugged.
+Usage of xenpaging can crash Xen or cause severe data corruption in the
+guest memory and its filesystems!
+
+Description:
+
+xenpaging writes memory pages of a given guest to a file and moves the
+page back to the pool of available memory.  Once the guests wants to
+access the paged-out memory, the page is read from disk and placed into
+memory.  This allows the sum of all running guests to use more memory
+than physically available on the host.
+
+Usage:
+
+Once the guest is running, run xenpaging with the guest_id and the
+number of pages to page-out:
+
+  mkdir /var/lib/xen/xenpaging
+  chdir /var/lib/xen/xenpaging
+  xenpaging <guest_id>  <number_of_pages>
+
+To obtain the guest_id, run 'xm list'.
+xenpaging will write the pagefile to the current directory.
+Example with 128MB pagefile on guest 1:
+
+  xenpaging 1 32768
+
+Caution: stopping xenpaging manually will cause the guest to stall or
+crash because the paged-out memory is not written back into the guest!
+
+
+
+Todo:
+- implement stopping of xenpaging
+- implement/test live migration
+
+
+# vim: tw=72

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 00/18] xenpaging changes for 4.0
  2010-10-18 13:06   ` Olaf Hering
@ 2010-10-22  9:04     ` Tim Deegan
  0 siblings, 0 replies; 31+ messages in thread
From: Tim Deegan @ 2010-10-22  9:04 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel@lists.xensource.com

At 14:06 +0100 on 18 Oct (1287410805), Olaf Hering wrote:
> On Mon, Oct 18, Tim Deegan wrote:
> 
> > These patches look pretty good to me, with a few caveats:
> > - Is it possible to avoid having quite so many paths return ENOENT?
> >   In particular, there seemed to be paths where _removing_ a p2m entry
> >   that's paged out caused an error.  Would it be possible to have some of
> >   those cases fixed up from the paging code instead?
> 
> I'm not sure if thats possible.

OK, having had a look I'm not sure it's possible either. :)  Your
current approach should be OK.

Cheers,

Tim.

-- 
Tim Deegan <Tim.Deegan@citrix.com>
Principal Software Engineer, XenServer Engineering
Citrix Systems UK Ltd.  (Company #02937203, SL9 0BG)

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2010-10-22  9:04 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-15 14:12 [PATCH 00/18] xenpaging changes for 4.0 Olaf Hering
2010-10-15 14:12 ` [PATCH 01/18] xenpaging: Fix-up xenpaging tool code Olaf Hering
2010-10-15 14:12 ` [PATCH 02/18] xenpaging: call pageout policy function in xenpaging_evict_page Olaf Hering
2010-10-15 14:12 ` [PATCH 03/18] xenpaging: fix fd leak in xenstore Olaf Hering
2010-10-15 14:12 ` [PATCH 04/18] xenpaging: break endless loop during inital page-out with large pagefiles Olaf Hering
2010-10-15 14:12 ` [PATCH 05/18] xenpaging: Open paging file only if xenpaging_init() succeeds Olaf Hering
2010-10-15 14:12 ` [PATCH 06/18] xenpaging: allow only one xenpaging binary per guest Olaf Hering
2010-10-18 16:54   ` Ian Jackson
2010-10-18 17:04     ` Olaf Hering
2010-10-19 10:17       ` Ian Jackson
2010-10-15 14:12 ` [PATCH 07/18] xenpaging/qemu-dm: add command to flush buffer cache Olaf Hering
2010-10-15 14:12 ` [PATCH 08/18] xenpaging: handle paged-out pages in XENMEM_* commands Olaf Hering
2010-10-15 14:12 ` [PATCH 09/18] xenpaging: populate only paged-out pages Olaf Hering
2010-10-15 14:12 ` [PATCH 10/18] xenpaging: reduce MINIMUM_RESTART_TIME Olaf Hering
2010-10-15 14:12 ` [PATCH 11/18] xenpaging: start xenpaging via config option Olaf Hering
2010-10-15 14:12 ` [PATCH 12/18] xenpaging: add signal handling Olaf Hering
2010-10-15 14:12 ` [PATCH 13/18] xenpaging: increase recently used pages from 4MB to 64MB Olaf Hering
2010-10-15 14:12 ` [PATCH 14/18] xenpaging: page-in granttable entries Olaf Hering
2010-10-15 14:12 ` [PATCH 15/18] xenpaging: handle dying guest in notify_via_xen_event_channel Olaf Hering
2010-10-15 14:12 ` [PATCH 16/18] xenpaging: prevent page-out of first 16MB Olaf Hering
2010-10-15 14:12 ` [PATCH 17/18] xenpaging: add dynamic startup delay for xenpaging Olaf Hering
2010-10-15 14:12 ` [PATCH 18/18] xenpaging: random debug statements and partial fixes Olaf Hering
2010-10-18 16:56   ` Ian Jackson
2010-10-18 17:05     ` Olaf Hering
2010-10-15 15:05 ` [PATCH 00/18] xenpaging changes for 4.0 Dan Magenheimer
2010-10-18 13:03   ` Olaf Hering
2010-10-22  8:55   ` Olaf Hering
2010-10-18 11:26 ` Tim Deegan
2010-10-18 13:06   ` Olaf Hering
2010-10-22  9:04     ` Tim Deegan
2010-10-18 16:57   ` Ian Jackson

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.