Mailing List Archive

[PATCH 5 of 5] xenpaging: improve evict error handling
# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# 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@aepfle.de>

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@lists.xensource.com
http://lists.xensource.com/xen-devel