[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 5 of 5] xenpaging: improve evict error handling


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Tue, 06 Dec 2011 18:07:06 +0100
  • Delivery-date: Tue, 06 Dec 2011 17:08:43 +0000
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1323189154 -3600
# Node ID 344e337be85eee244036f7cd158b64fe9d09aa00
# Parent  4e52b9c9309815a4b05c7b970a95e318d59fb71b
xenpaging: improve evict error handling

Adjust return codes in Xen and handle errors in evict_victim() properly.

p2m_mem_paging_nominate() returns -EAGAIN, p2m_mem_paging_evict()
returns -EBUSY.  Other errors indicate guest failures, which
xenpaging_evict_page() can now catch correctly. Also write() failures
are fatal.

Without this change, evict_victim() may spin forever if the guest is
killed because this function does not get a signal.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>

diff -r 4e52b9c93098 -r 344e337be85e tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -576,9 +576,11 @@ static int xenpaging_evict_page(xenpagin
 
     DECLARE_DOMCTL;
 
+    /* Errors are fatal */
+    ret = -1;
+
     /* Map page to get a handle */
     gfn = victim->gfn;
-    ret = -EFAULT;
     page = xc_map_foreign_pages(xch, paging->mem_event.domain_id,
                                 PROT_READ | PROT_WRITE, &gfn, 1);
     if ( page == NULL )
@@ -588,13 +590,15 @@ static int xenpaging_evict_page(xenpagin
     }
 
     /* Nominate the page */
-    ret = xc_mem_paging_nominate(xch, paging->mem_event.domain_id, gfn);
-    if ( ret != 0 )
+    if ( xc_mem_paging_nominate(xch, paging->mem_event.domain_id, gfn) )
+    {
+        if ( errno == EAGAIN )
+            ret = 1;
         goto out;
+    }
 
     /* Copy page */
-    ret = write_page(fd, page, i);
-    if ( ret != 0 )
+    if ( write_page(fd, page, i) )
     {
         PERROR("Error copying page %lx", victim->gfn);
         goto out;
@@ -604,10 +608,10 @@ static int xenpaging_evict_page(xenpagin
     page = NULL;
 
     /* Tell Xen to evict page */
-    ret = xc_mem_paging_evict(xch, paging->mem_event.domain_id,
-                              victim->gfn);
-    if ( ret != 0 )
+    if ( xc_mem_paging_evict(xch, paging->mem_event.domain_id, victim->gfn) )
     {
+        if ( errno == EBUSY )
+            ret = 1;
         PERROR("Error evicting page %lx", victim->gfn);
         goto out;
     }
@@ -619,6 +623,8 @@ static int xenpaging_evict_page(xenpagin
     /* Record number of evicted pages */
     paging->num_paged_out++;
 
+    ret = 0;
+
  out:
     if (page)
         munmap(page, PAGE_SIZE);
@@ -746,7 +752,12 @@ static int evict_victim(xenpaging_t *pag
             goto out;
         }
         ret = xenpaging_evict_page(paging, victim, fd, i);
-        if ( ret && j++ % 1000 == 0 )
+        if ( ret < 0 )
+        {
+            ret = -EINTR;
+            goto out;
+        }
+        if ( ret > 0 && j++ % 1000 == 0 )
         {
             if ( xenpaging_mem_paging_flush_ioemu_cache(paging) )
                 PERROR("Error flushing ioemu cache");
diff -r 4e52b9c93098 -r 344e337be85e xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -735,19 +735,17 @@ int p2m_mem_paging_nominate(struct domai
     p2m_type_t p2mt;
     p2m_access_t a;
     mfn_t mfn;
-    int ret;
+    int ret = -EAGAIN;
 
     p2m_lock(p2m);
 
     mfn = p2m->get_entry(p2m, gfn, &p2mt, &a, p2m_query, NULL);
 
     /* Check if mfn is valid */
-    ret = -EINVAL;
     if ( !mfn_valid(mfn) )
         goto out;
 
     /* Check p2m type */
-    ret = -EAGAIN;
     if ( !p2m_is_pageable(p2mt) )
         goto out;
 
@@ -799,7 +797,7 @@ int p2m_mem_paging_evict(struct domain *
     p2m_access_t a;
     mfn_t mfn;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
-    int ret = -EINVAL;
+    int ret = -EBUSY;
 
     p2m_lock(p2m);
 
@@ -812,7 +810,6 @@ int p2m_mem_paging_evict(struct domain *
     if ( p2mt != p2m_ram_paging_out )
         goto out;
 
-    ret = -EBUSY;
     /* Get the page so it doesn't get modified under Xen's feet */
     page = mfn_to_page(mfn);
     if ( unlikely(!get_page(page, d)) )
diff -r 4e52b9c93098 -r 344e337be85e xen/include/public/mem_event.h
--- a/xen/include/public/mem_event.h
+++ b/xen/include/public/mem_event.h
@@ -49,7 +49,7 @@
 #define MEM_EVENT_REASON_INT3        5    /* int3 was hit: gla/gfn are RIP */
 #define MEM_EVENT_REASON_SINGLESTEP  6    /* single step was invoked: gla/gfn 
are RIP */
 
-#define MEM_EVENT_PAGING_AGE         2UL  /* Number distinguish the mem_paging 
<-> pager interface */
+#define MEM_EVENT_PAGING_AGE         3UL  /* Number distinguish the mem_paging 
<-> pager interface */
 
 typedef struct mem_event_shared_page {
     uint32_t port;

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.