aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenpaging
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2012-02-20 21:18:44 +0100
committerOlaf Hering <olaf@aepfle.de>2012-02-20 21:18:44 +0100
commit45d78d49f2ffce2d7ec0a887807eb012a078bc61 (patch)
tree04150a233c229f96d135ad28c0186252dfe4e311 /tools/xenpaging
parent03be4100fb3cbbad1c0d1704b0b8dd81f63f63fb (diff)
downloadxen-45d78d49f2ffce2d7ec0a887807eb012a078bc61.tar.gz
xen-45d78d49f2ffce2d7ec0a887807eb012a078bc61.tar.bz2
xen-45d78d49f2ffce2d7ec0a887807eb012a078bc61.zip
xenpaging: unify error handling
Update functions to return -1 on error, 0 on success. Simplify init_page() and make sure errno is assigned. Adjust PERROR/ERROR usage, use PERROR early because it overwrites errno. Adjust xenpaging_populate_page() to handle gfn as unsigned long. Update xenpaging exit code handling. xenpaging_teardown cant possible fail. Adjust mainloop to indicate possible errors to final exit. Signed-off-by: Olaf Hering <olaf@aepfle.de> Committed-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/xenpaging')
-rw-r--r--tools/xenpaging/xenpaging.c123
1 files changed, 60 insertions, 63 deletions
diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c
index 5dff4ff5f2..f61de023c0 100644
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -98,7 +98,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
return 0;
PERROR("Poll exited with an error");
- return -errno;
+ return -1;
}
/* First check for guest shutdown */
@@ -116,6 +116,7 @@ static int xenpaging_wait_for_event_or_timeout(struct xenpaging *paging)
{
xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
interrupted = SIGQUIT;
+ /* No further poll result processing */
rc = 0;
}
}
@@ -183,26 +184,20 @@ static int xenpaging_get_tot_pages(struct xenpaging *paging)
static void *init_page(void)
{
void *buffer;
- int ret;
/* Allocated page memory */
- ret = posix_memalign(&buffer, PAGE_SIZE, PAGE_SIZE);
- if ( ret != 0 )
- goto out_alloc;
+ errno = posix_memalign(&buffer, PAGE_SIZE, PAGE_SIZE);
+ if ( errno != 0 )
+ return NULL;
/* Lock buffer in memory so it can't be paged out */
- ret = mlock(buffer, PAGE_SIZE);
- if ( ret != 0 )
- goto out_lock;
+ if ( mlock(buffer, PAGE_SIZE) < 0 )
+ {
+ free(buffer);
+ buffer = NULL;
+ }
return buffer;
-
- out_init:
- munlock(buffer, PAGE_SIZE);
- out_lock:
- free(buffer);
- out_alloc:
- return NULL;
}
static void usage(void)
@@ -449,7 +444,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
paging_buffer = init_page();
if ( !paging_buffer )
{
- ERROR("Creating page aligned load buffer");
+ PERROR("Creating page aligned load buffer");
goto err;
}
@@ -485,18 +480,14 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[])
return NULL;
}
-static int xenpaging_teardown(struct xenpaging *paging)
+static void xenpaging_teardown(struct xenpaging *paging)
{
int rc;
- xc_interface *xch;
-
- if ( paging == NULL )
- return 0;
+ xc_interface *xch = paging->xc_handle;
xs_unwatch(paging->xs_handle, watch_target_tot_pages, "");
xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
- xch = paging->xc_handle;
paging->xc_handle = NULL;
/* Tear down domain paging in Xen */
rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
@@ -528,13 +519,8 @@ static int xenpaging_teardown(struct xenpaging *paging)
rc = xc_interface_close(xch);
if ( rc != 0 )
{
- PERROR("Error closing connection to xen");
+ ERROR("Error closing connection to xen");
}
-
- return 0;
-
- err:
- return -1;
}
static void get_request(struct mem_event *mem_event, mem_event_request_t *req)
@@ -684,21 +670,19 @@ static int xenpaging_resume_page(struct xenpaging *paging, mem_event_response_t
return ret;
}
-static int xenpaging_populate_page(struct xenpaging *paging,
- xen_pfn_t gfn, int fd, int i)
+static int xenpaging_populate_page(struct xenpaging *paging, unsigned long gfn, int fd, int i)
{
xc_interface *xch = paging->xc_handle;
- void *page;
int ret;
unsigned char oom = 0;
- DPRINTF("populate_page < gfn %"PRI_xen_pfn" pageslot %d\n", gfn, i);
+ DPRINTF("populate_page < gfn %lx pageslot %d\n", gfn, i);
/* Read page */
ret = read_page(fd, paging_buffer, i);
if ( ret != 0 )
{
- ERROR("Error reading page");
+ PERROR("Error reading page");
goto out;
}
@@ -707,17 +691,18 @@ static int xenpaging_populate_page(struct xenpaging *paging,
/* Tell Xen to allocate a page for the domain */
ret = xc_mem_paging_load(xch, paging->mem_event.domain_id, gfn,
paging_buffer);
- if ( ret != 0 )
+ if ( ret < 0 )
{
if ( errno == ENOMEM )
{
if ( oom++ == 0 )
- DPRINTF("ENOMEM while preparing gfn %"PRI_xen_pfn"\n", gfn);
+ DPRINTF("ENOMEM while preparing gfn %lx\n", gfn);
sleep(1);
continue;
}
- PERROR("Error loading %"PRI_xen_pfn" during page-in", gfn);
- goto out;
+ PERROR("Error loading %lx during page-in", gfn);
+ ret = -1;
+ break;
}
}
while ( ret && !interrupted );
@@ -748,6 +733,11 @@ static void resume_pages(struct xenpaging *paging, int num_pages)
page_in_trigger();
}
+/* Evict one gfn and write it to the given slot
+ * Returns < 0 on fatal error
+ * Returns 0 on successful evict
+ * Returns > 0 if no gfn can be evicted
+ */
static int evict_victim(struct xenpaging *paging, int fd, int slot)
{
xc_interface *xch = paging->xc_handle;
@@ -771,13 +761,13 @@ static int evict_victim(struct xenpaging *paging, int fd, int slot)
xenpaging_mem_paging_flush_ioemu_cache(paging);
num_paged_out = paging->num_paged_out;
}
- ret = -ENOSPC;
+ ret = ENOSPC;
goto out;
}
if ( interrupted )
{
- ret = -EINTR;
+ ret = EINTR;
goto out;
}
@@ -788,7 +778,7 @@ static int evict_victim(struct xenpaging *paging, int fd, int slot)
while ( ret );
if ( test_and_set_bit(gfn, paging->bitmap) )
- ERROR("Page has been evicted before");
+ ERROR("Page %lx has been evicted before", gfn);
ret = 0;
@@ -796,7 +786,11 @@ static int evict_victim(struct xenpaging *paging, int fd, int slot)
return ret;
}
-/* Evict a batch of pages and write them to a free slot in the paging file */
+/* Evict a batch of pages and write them to a free slot in the paging file
+ * Returns < 0 on fatal error
+ * Returns 0 if no gfn can be evicted
+ * Returns > 0 on successful evict
+ */
static int evict_pages(struct xenpaging *paging, int fd, int num_pages)
{
xc_interface *xch = paging->xc_handle;
@@ -809,12 +803,12 @@ static int evict_pages(struct xenpaging *paging, int fd, int num_pages)
continue;
rc = evict_victim(paging, fd, slot);
- if ( rc == -ENOSPC )
- break;
- if ( rc == -EINTR )
+ if ( rc )
+ {
+ num = rc < 0 ? -1 : num;
break;
- if ( num && num % 100 == 0 )
- DPRINTF("%d pages evicted\n", num);
+ }
+
num++;
}
return num;
@@ -829,8 +823,7 @@ int main(int argc, char *argv[])
int num, prev_num = 0;
int slot;
int tot_pages;
- int rc = -1;
- int rc1;
+ int rc;
xc_interface *xch;
int open_flags = O_CREAT | O_TRUNC | O_RDWR;
@@ -875,7 +868,7 @@ int main(int argc, char *argv[])
rc = xenpaging_wait_for_event_or_timeout(paging);
if ( rc < 0 )
{
- PERROR("Error getting event");
+ ERROR("Error getting event");
goto out;
}
else if ( rc != 0 )
@@ -885,6 +878,9 @@ int main(int argc, char *argv[])
while ( RING_HAS_UNCONSUMED_REQUESTS(&paging->mem_event.back_ring) )
{
+ /* Indicate possible error */
+ rc = 1;
+
get_request(&paging->mem_event, &req);
if ( req.gfn > paging->max_pages )
@@ -915,10 +911,9 @@ int main(int argc, char *argv[])
else
{
/* Populate the page */
- rc = xenpaging_populate_page(paging, req.gfn, fd, slot);
- if ( rc != 0 )
+ if ( xenpaging_populate_page(paging, req.gfn, fd, slot) < 0 )
{
- PERROR("Error populating page %"PRIx64"", req.gfn);
+ ERROR("Error populating page %"PRIx64"", req.gfn);
goto out;
}
}
@@ -928,8 +923,7 @@ int main(int argc, char *argv[])
rsp.vcpu_id = req.vcpu_id;
rsp.flags = req.flags;
- rc = xenpaging_resume_page(paging, &rsp, 1);
- if ( rc != 0 )
+ if ( xenpaging_resume_page(paging, &rsp, 1) < 0 )
{
PERROR("Error resuming page %"PRIx64"", req.gfn);
goto out;
@@ -955,8 +949,7 @@ int main(int argc, char *argv[])
rsp.vcpu_id = req.vcpu_id;
rsp.flags = req.flags;
- rc = xenpaging_resume_page(paging, &rsp, 0);
- if ( rc != 0 )
+ if ( xenpaging_resume_page(paging, &rsp, 0) < 0 )
{
PERROR("Error resuming page %"PRIx64"", req.gfn);
goto out;
@@ -983,6 +976,9 @@ int main(int argc, char *argv[])
if ( interrupted )
break;
+ /* Indicate possible error */
+ rc = 1;
+
/* Check if the target has been reached already */
tot_pages = xenpaging_get_tot_pages(paging);
if ( tot_pages < 0 )
@@ -1009,7 +1005,8 @@ int main(int argc, char *argv[])
paging->use_poll_timeout = 0;
num = 42;
}
- evict_pages(paging, fd, num);
+ if ( evict_pages(paging, fd, num) < 0 )
+ goto out;
}
/* Resume some pages if target not reached */
else if ( tot_pages < paging->target_tot_pages && paging->num_paged_out )
@@ -1029,6 +1026,10 @@ int main(int argc, char *argv[])
}
}
+
+ /* No error */
+ rc = 0;
+
DPRINTF("xenpaging got signal %d\n", interrupted);
out:
@@ -1036,13 +1037,9 @@ int main(int argc, char *argv[])
unlink_pagefile();
/* Tear down domain paging */
- rc1 = xenpaging_teardown(paging);
- if ( rc1 != 0 )
- fprintf(stderr, "Error tearing down paging");
+ xenpaging_teardown(paging);
- if ( rc == 0 )
- rc = rc1;
- return rc;
+ return rc ? 2 : 0;
}