Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 00 of 15] tools/xenpaging fixes for xen-unstable
The following changes contains non-controversial changes from the series of changes for xenpaging I sent out on 2011-10-03. Please review and apply. Olaf Config.mk | 2 config/StdGNU.mk | 2 tools/libxc/xc_bitops.h | 6 + tools/libxl/libxl.h | 1 tools/libxl/libxl_paths.c | 5 tools/xenpaging/Makefile | 6 - tools/xenpaging/file_ops.c | 30 +---- tools/xenpaging/policy_default.c | 23 +++ tools/xenpaging/xenpaging.c | 232 ++++++++++++++++++++++----------------- tools/xenpaging/xenpaging.h | 5 10 files changed, 180 insertions(+), 132 deletions(-) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 01 of 15] xenpaging: remove filename from comment
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188557 -7200 # Node ID c59f8ec51fff75eeef896752e154cd6f9ea1685d # Parent 6c583d35d76dda2236c81d9437ff9d57ab02c006 xenpaging: remove filename from comment Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 6c583d35d76d -r c59f8ec51fff tools/xenpaging/file_ops.c --- a/tools/xenpaging/file_ops.c +++ b/tools/xenpaging/file_ops.c @@ -1,5 +1,4 @@ /****************************************************************************** - * tools/xenpaging/file_ops.c * * Common file operations. * diff -r 6c583d35d76d -r c59f8ec51fff tools/xenpaging/policy_default.c --- a/tools/xenpaging/policy_default.c +++ b/tools/xenpaging/policy_default.c @@ -1,5 +1,4 @@ /****************************************************************************** - * tools/xenpaging/policy.c * * Xen domain paging default policy. * diff -r 6c583d35d76d -r c59f8ec51fff tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -1,5 +1,4 @@ /****************************************************************************** - * tools/xenpaging/xenpaging.c * * Domain paging. * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 02 of 15] xenpaging: remove obsolete comment in resume path
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188602 -7200 # Node ID 8e680d6bc0413942dcb97d708aec381da0b6fd69 # Parent c59f8ec51fff75eeef896752e154cd6f9ea1685d xenpaging: remove obsolete comment in resume path Remove stale comment. If a page was populated several times the vcpu is paused and xenpaging has to unpause it again. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r c59f8ec51fff -r 8e680d6bc041 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -744,7 +744,6 @@ int main(int argc, char *argv[]) !!(req.flags & MEM_EVENT_FLAG_EVICT_FAIL) ); /* Tell Xen to resume the vcpu */ - /* XXX: Maybe just check if the vcpu was paused? */ if ( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED ) { /* Prepare the response */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 03 of 15] xenpaging: use PERROR to print errno
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188767 -7200 # Node ID e51e5e2a835157df92faf3038abc457714d5e096 # Parent 8e680d6bc0413942dcb97d708aec381da0b6fd69 xenpaging: use PERROR to print errno v3: - adjust arguments for xc_mem_paging_enable() failures v2: - move changes to file_op() to different patch Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 8e680d6bc041 -r e51e5e2a8351 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -90,7 +90,7 @@ static int xenpaging_wait_for_event_or_t if (errno == EINTR) return 0; - ERROR("Poll exited with an error"); + PERROR("Poll exited with an error"); return -errno; } @@ -121,7 +121,7 @@ static int xenpaging_wait_for_event_or_t port = xc_evtchn_pending(xce); if ( port == -1 ) { - ERROR("Failed to read port from event channel"); + PERROR("Failed to read port from event channel"); rc = -1; goto err; } @@ -129,7 +129,7 @@ static int xenpaging_wait_for_event_or_t rc = xc_evtchn_unmask(xce, port); if ( rc < 0 ) { - ERROR("Failed to unmask event channel port"); + PERROR("Failed to unmask event channel port"); } } err: @@ -185,7 +185,7 @@ static xenpaging_t *xenpaging_init(domid paging->xs_handle = xs_open(0); if ( paging->xs_handle == NULL ) { - ERROR("Error initialising xenstore connection"); + PERROR("Error initialising xenstore connection"); goto err; } @@ -193,7 +193,7 @@ static xenpaging_t *xenpaging_init(domid snprintf(watch_token, sizeof(watch_token), "%u", domain_id); if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false ) { - ERROR("Could not bind to shutdown watch\n"); + PERROR("Could not bind to shutdown watch\n"); goto err; } @@ -214,7 +214,7 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.shared_page = init_page(); if ( paging->mem_event.shared_page == NULL ) { - ERROR("Error initialising shared page"); + PERROR("Error initialising shared page"); goto err; } @@ -222,7 +222,7 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.ring_page = init_page(); if ( paging->mem_event.ring_page == NULL ) { - ERROR("Error initialising ring page"); + PERROR("Error initialising ring page"); goto err; } @@ -249,7 +249,7 @@ static xenpaging_t *xenpaging_init(domid ERROR("xenpaging not supported in a PoD guest"); break; default: - ERROR("Error initialising shared page: %s", strerror(errno)); + PERROR("Error initialising shared page"); break; } goto err; @@ -259,7 +259,7 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.xce_handle = xc_evtchn_open(NULL, 0); if ( paging->mem_event.xce_handle == NULL ) { - ERROR("Failed to open event channel"); + PERROR("Failed to open event channel"); goto err; } @@ -269,7 +269,7 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.shared_page->port); if ( rc < 0 ) { - ERROR("Failed to bind event channel"); + PERROR("Failed to bind event channel"); goto err; } @@ -279,7 +279,7 @@ static xenpaging_t *xenpaging_init(domid paging->domain_info = malloc(sizeof(xc_domaininfo_t)); if ( paging->domain_info == NULL ) { - ERROR("Error allocating memory for domain info"); + PERROR("Error allocating memory for domain info"); goto err; } @@ -287,7 +287,7 @@ static xenpaging_t *xenpaging_init(domid paging->domain_info); if ( rc != 1 ) { - ERROR("Error getting domain info"); + PERROR("Error getting domain info"); goto err; } @@ -295,7 +295,7 @@ static xenpaging_t *xenpaging_init(domid paging->bitmap = bitmap_alloc(paging->domain_info->max_pages); if ( !paging->bitmap ) { - ERROR("Error allocating bitmap"); + PERROR("Error allocating bitmap"); goto err; } DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages); @@ -311,7 +311,7 @@ static xenpaging_t *xenpaging_init(domid rc = policy_init(paging); if ( rc != 0 ) { - ERROR("Error initialising policy"); + PERROR("Error initialising policy"); goto err; } @@ -358,14 +358,14 @@ static int xenpaging_teardown(xenpaging_ rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id); if ( rc != 0 ) { - ERROR("Error tearing down domain paging in xen"); + PERROR("Error tearing down domain paging in xen"); } /* Unbind VIRQ */ rc = xc_evtchn_unbind(paging->mem_event.xce_handle, paging->mem_event.port); if ( rc != 0 ) { - ERROR("Error unbinding event port"); + PERROR("Error unbinding event port"); } paging->mem_event.port = -1; @@ -373,7 +373,7 @@ static int xenpaging_teardown(xenpaging_ rc = xc_evtchn_close(paging->mem_event.xce_handle); if ( rc != 0 ) { - ERROR("Error closing event channel"); + PERROR("Error closing event channel"); } paging->mem_event.xce_handle = NULL; @@ -384,7 +384,7 @@ static int xenpaging_teardown(xenpaging_ rc = xc_interface_close(xch); if ( rc != 0 ) { - ERROR("Error closing connection to xen"); + PERROR("Error closing connection to xen"); } return 0; @@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin PROT_READ | PROT_WRITE, &gfn, 1); if ( page == NULL ) { - ERROR("Error mapping page"); + PERROR("Error mapping page"); goto out; } @@ -452,8 +452,8 @@ static int xenpaging_evict_page(xenpagin ret = write_page(fd, page, i); if ( ret != 0 ) { + PERROR("Error copying page"); munmap(page, PAGE_SIZE); - ERROR("Error copying page"); goto out; } @@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin victim->gfn); if ( ret != 0 ) { - ERROR("Error evicting page"); + PERROR("Error evicting page"); goto out; } @@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa sleep(1); continue; } - ERROR("Error preparing for page in"); + PERROR("Error preparing for page in"); goto out_map; } } @@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa PROT_READ | PROT_WRITE, &gfn, 1); if ( page == NULL ) { - ERROR("Error mapping page: page is null"); + PERROR("Error mapping page: page is null"); goto out_map; } @@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa ret = read_page(fd, page, i); if ( ret != 0 ) { - ERROR("Error reading page"); + PERROR("Error reading page"); goto out; } @@ -579,7 +579,7 @@ static int evict_victim(xenpaging_t *pag { if ( j++ % 1000 == 0 ) if ( xenpaging_mem_paging_flush_ioemu_cache(paging) ) - ERROR("Error flushing ioemu cache"); + PERROR("Error flushing ioemu cache"); } } while ( ret ); @@ -670,7 +670,7 @@ int main(int argc, char *argv[]) rc = xenpaging_wait_for_event_or_timeout(paging); if ( rc < 0 ) { - ERROR("Error getting event"); + PERROR("Error getting event"); goto out; } else if ( rc != 0 ) @@ -710,7 +710,7 @@ int main(int argc, char *argv[]) rc = xenpaging_populate_page(paging, req.gfn, fd, i); if ( rc != 0 ) { - ERROR("Error populating page"); + PERROR("Error populating page"); goto out; } } @@ -723,7 +723,7 @@ int main(int argc, char *argv[]) rc = xenpaging_resume_page(paging, &rsp, 1); if ( rc != 0 ) { - ERROR("Error resuming page"); + PERROR("Error resuming page"); goto out; } @@ -754,7 +754,7 @@ int main(int argc, char *argv[]) rc = xenpaging_resume_page(paging, &rsp, 0); if ( rc != 0 ) { - ERROR("Error resuming"); + PERROR("Error resuming"); goto out; } } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 04 of 15] xenpaging: simplify file_op
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188795 -7200 # Node ID 71002bff018b95da0db016e18c3a3145cc83fc77 # Parent e51e5e2a835157df92faf3038abc457714d5e096 xenpaging: simplify file_op Use -1 as return value and let caller read errno. Remove const casts from buffer pointers, the page is writeable. Use wrapper for write() which matches the read() prototype. Remove unused stdarg.h inclusion. Remove unused macro. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r e51e5e2a8351 -r 71002bff018b tools/xenpaging/file_ops.c --- a/tools/xenpaging/file_ops.c +++ b/tools/xenpaging/file_ops.c @@ -21,55 +21,44 @@ #include <unistd.h> -#include <stdarg.h> #include <xc_private.h> - -#define page_offset(_pfn) (((off_t)(_pfn)) << PAGE_SHIFT) - - static int file_op(int fd, void *page, int i, - ssize_t (*fn)(int, const void *, size_t)) + ssize_t (*fn)(int, void *, size_t)) { off_t seek_ret; - int total; + int total = 0; int bytes; - int ret; seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET); + if ( seek_ret == (off_t)-1 ) + return -1; - total = 0; while ( total < PAGE_SIZE ) { bytes = fn(fd, page + total, PAGE_SIZE - total); if ( bytes <= 0 ) - { - ret = -errno; - goto err; - } + return -1; total += bytes; } return 0; - - err: - return ret; } -static ssize_t my_read(int fd, const void *buf, size_t count) +static ssize_t my_write(int fd, void *buf, size_t count) { - return read(fd, (void *)buf, count); + return write(fd, buf, count); } int read_page(int fd, void *page, int i) { - return file_op(fd, page, i, &my_read); + return file_op(fd, page, i, &read); } int write_page(int fd, void *page, int i) { - return file_op(fd, page, i, &write); + return file_op(fd, page, i, &my_write); } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 05 of 15] xenpaging: print gfn in failure case
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188898 -7200 # Node ID a58e98af3f0b9d92cbe4bbb523f8bbec33e2b358 # Parent 71002bff018b95da0db016e18c3a3145cc83fc77 xenpaging: print gfn in failure case Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 71002bff018b -r a58e98af3f0b tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -444,7 +444,7 @@ static int xenpaging_evict_page(xenpagin PROT_READ | PROT_WRITE, &gfn, 1); if ( page == NULL ) { - PERROR("Error mapping page"); + PERROR("Error mapping page %lx", victim->gfn); goto out; } @@ -452,7 +452,7 @@ static int xenpaging_evict_page(xenpagin ret = write_page(fd, page, i); if ( ret != 0 ) { - PERROR("Error copying page"); + PERROR("Error copying page %lx", victim->gfn); munmap(page, PAGE_SIZE); goto out; } @@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin victim->gfn); if ( ret != 0 ) { - PERROR("Error evicting page"); + PERROR("Error evicting page %lx", victim->gfn); goto out; } @@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa sleep(1); continue; } - PERROR("Error preparing for page in"); + PERROR("Error preparing %"PRI_xen_pfn" for page-in", gfn); goto out_map; } } @@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa PROT_READ | PROT_WRITE, &gfn, 1); if ( page == NULL ) { - PERROR("Error mapping page: page is null"); + PERROR("Error mapping page %"PRI_xen_pfn": page is null", gfn); goto out_map; } @@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa ret = read_page(fd, page, i); if ( ret != 0 ) { - PERROR("Error reading page"); + PERROR("Error reading page %"PRI_xen_pfn"", gfn); goto out; } @@ -710,7 +710,7 @@ int main(int argc, char *argv[]) rc = xenpaging_populate_page(paging, req.gfn, fd, i); if ( rc != 0 ) { - PERROR("Error populating page"); + PERROR("Error populating page %"PRIx64"", req.gfn); goto out; } } @@ -723,7 +723,7 @@ int main(int argc, char *argv[]) rc = xenpaging_resume_page(paging, &rsp, 1); if ( rc != 0 ) { - PERROR("Error resuming page"); + PERROR("Error resuming page %"PRIx64"", req.gfn); goto out; } @@ -754,7 +754,7 @@ int main(int argc, char *argv[]) rc = xenpaging_resume_page(paging, &rsp, 0); if ( rc != 0 ) { - PERROR("Error resuming"); + PERROR("Error resuming page %"PRIx64"", req.gfn); goto out; } } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 06 of 15] xenpaging: update xenpaging_init
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188918 -7200 # Node ID 04de2e7001dd59e66a1ebed830df5813198a1543 # Parent a58e98af3f0b9d92cbe4bbb523f8bbec33e2b358 xenpaging: update xenpaging_init Move comment about xc_handle to the right place. Allocate paging early and use calloc. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r a58e98af3f0b -r 04de2e7001dd tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -169,18 +169,21 @@ static xenpaging_t *xenpaging_init(domid char *p; int rc; + /* Allocate memory */ + paging = calloc(1, sizeof(xenpaging_t)); + if ( !paging ) + goto err; + if ( getenv("XENPAGING_DEBUG") ) dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0); - xch = xc_interface_open(dbg, NULL, 0); + + /* Open connection to xen */ + paging->xc_handle = xch = xc_interface_open(dbg, NULL, 0); if ( !xch ) - goto err_iface; + goto err; DPRINTF("xenpaging init\n"); - /* Allocate memory */ - paging = malloc(sizeof(xenpaging_t)); - memset(paging, 0, sizeof(xenpaging_t)); - /* Open connection to xenstore */ paging->xs_handle = xs_open(0); if ( paging->xs_handle == NULL ) @@ -204,9 +207,6 @@ static xenpaging_t *xenpaging_init(domid DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size); } - /* Open connection to xen */ - paging->xc_handle = xch; - /* Set domain id */ paging->mem_event.domain_id = domain_id; @@ -322,7 +322,8 @@ static xenpaging_t *xenpaging_init(domid { if ( paging->xs_handle ) xs_close(paging->xs_handle); - xc_interface_close(xch); + if ( xch ) + xc_interface_close(xch); if ( paging->mem_event.shared_page ) { munlock(paging->mem_event.shared_page, PAGE_SIZE); @@ -340,7 +341,6 @@ static xenpaging_t *xenpaging_init(domid free(paging); } - err_iface: return NULL; } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 07 of 15] xenpaging: remove xc_dominfo_t from paging_t
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188936 -7200 # Node ID 8ab7b6fc34334faf5900e26cf3fcece33dc38337 # Parent 04de2e7001dd59e66a1ebed830df5813198a1543 xenpaging: remove xc_dominfo_t from paging_t Remove xc_dominfo_t from paging_t, record only max_pages. This value is used to setup internal data structures. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 04de2e7001dd -r 8ab7b6fc3433 tools/xenpaging/policy_default.c --- a/tools/xenpaging/policy_default.c +++ b/tools/xenpaging/policy_default.c @@ -41,17 +41,17 @@ int policy_init(xenpaging_t *paging) int i; int rc = -ENOMEM; + max_pages = paging->max_pages; + /* Allocate bitmap for pages not to page out */ - bitmap = bitmap_alloc(paging->domain_info->max_pages); + bitmap = bitmap_alloc(max_pages); if ( !bitmap ) goto out; /* Allocate bitmap to track unusable pages */ - unconsumed = bitmap_alloc(paging->domain_info->max_pages); + unconsumed = bitmap_alloc(max_pages); if ( !unconsumed ) goto out; - max_pages = paging->domain_info->max_pages; - /* Initialise MRU list of paged in pages */ if ( paging->policy_mru_size > 0 ) mru_size = paging->policy_mru_size; diff -r 04de2e7001dd -r 8ab7b6fc3433 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -164,6 +164,7 @@ static void *init_page(void) static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages) { xenpaging_t *paging; + xc_domaininfo_t domain_info; xc_interface *xch; xentoollog_logger *dbg = NULL; char *p; @@ -275,34 +276,29 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.port = rc; - /* Get domaininfo */ - paging->domain_info = malloc(sizeof(xc_domaininfo_t)); - if ( paging->domain_info == NULL ) - { - PERROR("Error allocating memory for domain info"); - goto err; - } - rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, - paging->domain_info); + &domain_info); if ( rc != 1 ) { PERROR("Error getting domain info"); goto err; } + /* Record number of max_pages */ + paging->max_pages = domain_info.max_pages; + /* Allocate bitmap for tracking pages that have been paged out */ - paging->bitmap = bitmap_alloc(paging->domain_info->max_pages); + paging->bitmap = bitmap_alloc(paging->max_pages); if ( !paging->bitmap ) { PERROR("Error allocating bitmap"); goto err; } - DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages); + DPRINTF("max_pages = %d\n", paging->max_pages); - if ( num_pages < 0 || num_pages > paging->domain_info->max_pages ) + if ( num_pages < 0 || num_pages > paging->max_pages ) { - num_pages = paging->domain_info->max_pages; + num_pages = paging->max_pages; DPRINTF("setting num_pages to %d\n", num_pages); } paging->num_pages = num_pages; @@ -337,7 +333,6 @@ static xenpaging_t *xenpaging_init(domid } free(paging->bitmap); - free(paging->domain_info); free(paging); } @@ -765,7 +760,7 @@ int main(int argc, char *argv[]) if ( interrupted == SIGTERM || interrupted == SIGINT ) { int num = 0; - for ( i = 0; i < paging->domain_info->max_pages; i++ ) + for ( i = 0; i < paging->max_pages; i++ ) { if ( test_bit(i, paging->bitmap) ) { @@ -781,7 +776,7 @@ int main(int argc, char *argv[]) */ if ( num ) page_in_trigger(); - else if ( i == paging->domain_info->max_pages ) + else if ( i == paging->max_pages ) break; } else diff -r 04de2e7001dd -r 8ab7b6fc3433 tools/xenpaging/xenpaging.h --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -44,11 +44,11 @@ typedef struct xenpaging { xc_interface *xc_handle; struct xs_handle *xs_handle; - xc_domaininfo_t *domain_info; - unsigned long *bitmap; mem_event_t mem_event; + /* number of pages for which data structures were allocated */ + int max_pages; int num_pages; int policy_mru_size; unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 08 of 15] xenpaging: track the number of paged-out pages
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319188945 -7200 # Node ID 75e0b7374cbda66c91ab910103adcb1088a867e4 # Parent 8ab7b6fc34334faf5900e26cf3fcece33dc38337 xenpaging: track the number of paged-out pages This change is required by subsequent changes. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 8ab7b6fc3433 -r 75e0b7374cbd tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -467,6 +467,9 @@ static int xenpaging_evict_page(xenpagin /* Notify policy of page being paged out */ policy_notify_paged_out(victim->gfn); + /* Record number of evicted pages */ + paging->num_paged_out++; + out: return ret; } @@ -480,8 +483,13 @@ static int xenpaging_resume_page(xenpagi /* Notify policy of page being paged in */ if ( notify_policy ) + { policy_notify_paged_in(rsp->gfn); + /* Record number of resumed pages */ + paging->num_paged_out--; + } + /* Tell Xen page is ready */ ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id, rsp->gfn); diff -r 8ab7b6fc3433 -r 75e0b7374cbd tools/xenpaging/xenpaging.h --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -49,6 +49,7 @@ typedef struct xenpaging { mem_event_t mem_event; /* number of pages for which data structures were allocated */ int max_pages; + int num_paged_out; int num_pages; int policy_mru_size; unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 09 of 15] xenpaging: move page add/resume loops into its own function
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189007 -7200 # Node ID 6eb58c8bee87080c5e683a7b118aed7b87d675db # Parent 75e0b7374cbda66c91ab910103adcb1088a867e4 xenpaging: move page add/resume loops into its own function. Move page resume loop into its own function. Move page eviction loop into its own function. Allocate all possible slots in a paging file to allow growing and shrinking of the number of paged-out pages. Adjust other places to iterate over all slots. This change is required by subsequent patches. v2: - check if victims allocation succeeded Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 75e0b7374cbd -r 6eb58c8bee87 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -553,6 +553,27 @@ static int xenpaging_populate_page(xenpa return ret; } +/* Trigger a page-in for a batch of pages */ +static void resume_pages(xenpaging_t *paging, int num_pages) +{ + xc_interface *xch = paging->xc_handle; + int i, num = 0; + + for ( i = 0; i < paging->max_pages && num < num_pages; i++ ) + { + if ( test_bit(i, paging->bitmap) ) + { + paging->pagein_queue[num] = i; + num++; + if ( num == XENPAGING_PAGEIN_QUEUE_SIZE ) + break; + } + } + /* num may be less than num_pages, caller has to try again */ + if ( num ) + page_in_trigger(); +} + static int evict_victim(xenpaging_t *paging, xenpaging_victim_t *victim, int fd, int i) { @@ -596,6 +617,30 @@ static int evict_victim(xenpaging_t *pag return ret; } +/* Evict a batch of pages and write them to a free slot in the paging file */ +static int evict_pages(xenpaging_t *paging, int fd, xenpaging_victim_t *victims, int num_pages) +{ + xc_interface *xch = paging->xc_handle; + int rc, slot, num = 0; + + for ( slot = 0; slot < paging->max_pages && num < num_pages; slot++ ) + { + /* Slot is allocated */ + if ( victims[slot].gfn != INVALID_MFN ) + continue; + + rc = evict_victim(paging, &victims[slot], fd, slot); + if ( rc == -ENOSPC ) + break; + if ( rc == -EINTR ) + break; + if ( num && num % 100 == 0 ) + DPRINTF("%d pages evicted\n", num); + num++; + } + return num; +} + int main(int argc, char *argv[]) { struct sigaction act; @@ -638,7 +683,14 @@ int main(int argc, char *argv[]) return 2; } - victims = calloc(paging->num_pages, sizeof(xenpaging_victim_t)); + /* Allocate upper limit of pages to allow growing and shrinking */ + victims = calloc(paging->max_pages, sizeof(xenpaging_victim_t)); + if ( !victims ) + goto out; + + /* Mark all slots as unallocated */ + for ( i = 0; i < paging->max_pages; i++ ) + victims[i].gfn = INVALID_MFN; /* ensure that if we get a signal, we''ll do cleanup, then exit */ act.sa_handler = close_handler; @@ -652,18 +704,7 @@ int main(int argc, char *argv[]) /* listen for page-in events to stop pager */ create_page_in_thread(paging); - /* Evict pages */ - for ( i = 0; i < paging->num_pages; i++ ) - { - rc = evict_victim(paging, &victims[i], fd, i); - if ( rc == -ENOSPC ) - break; - if ( rc == -EINTR ) - break; - if ( i % 100 == 0 ) - DPRINTF("%d pages evicted\n", i); - } - + i = evict_pages(paging, fd, victims, paging->num_pages); DPRINTF("%d pages evicted. Done.\n", i); /* Swap pages in and out */ @@ -689,13 +730,13 @@ int main(int argc, char *argv[]) if ( test_and_clear_bit(req.gfn, paging->bitmap) ) { /* Find where in the paging file to read from */ - for ( i = 0; i < paging->num_pages; i++ ) + for ( i = 0; i < paging->max_pages; i++ ) { if ( victims[i].gfn == req.gfn ) break; } - if ( i >= paging->num_pages ) + if ( i >= paging->max_pages ) { DPRINTF("Couldn''t find page %"PRIx64"\n", req.gfn); goto out; @@ -767,25 +808,12 @@ int main(int argc, char *argv[]) /* Write all pages back into the guest */ if ( interrupted == SIGTERM || interrupted == SIGINT ) { - int num = 0; - for ( i = 0; i < paging->max_pages; i++ ) - { - if ( test_bit(i, paging->bitmap) ) - { - paging->pagein_queue[num] = i; - num++; - if ( num == XENPAGING_PAGEIN_QUEUE_SIZE ) - break; - } - } - /* - * One more round if there are still pages to process. - * If no more pages to process, exit loop. - */ - if ( num ) - page_in_trigger(); - else if ( i == paging->max_pages ) + /* If no more pages to process, exit loop. */ + if ( !paging->num_paged_out ) break; + + /* One more round if there are still pages to process. */ + resume_pages(paging, paging->num_paged_out); } else { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189021 -7200 # Node ID 0b7d7a2bd6673f358faf0183b79b29e6a2f036a5 # Parent 6eb58c8bee87080c5e683a7b118aed7b87d675db xenpaging: compare both token and path when checking for @releaseDomain event Subsequent patches will use xenstored to store the numbers of pages xenpaging is suppose to page-out. A domain_id value could be misinterpreted as number of pages. Compare both path and token to recognize the @releaseDomain event. Also add debug output to show received watch event. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 6eb58c8bee87 -r 0b7d7a2bd667 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -101,7 +101,8 @@ static int xenpaging_wait_for_event_or_t vec = xs_read_watch(paging->xs_handle, &num); if ( vec ) { - if ( strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 ) + DPRINTF("path ''%s'' token ''%s''\n", vec[XS_WATCH_PATH], vec[XS_WATCH_TOKEN]); + if ( strcmp(vec[XS_WATCH_PATH], "@releaseDomain") == 0 && strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 ) { /* If our guest disappeared, set interrupt flag and fall through */ if ( xs_is_domain_introduced(paging->xs_handle, paging->mem_event.domain_id) == false ) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 11 of 15] xenpaging: improve mainloop exit handling
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189039 -7200 # Node ID 1f9a27425952493878a54c82e0518b47560161af # Parent 0b7d7a2bd6673f358faf0183b79b29e6a2f036a5 xenpaging: improve mainloop exit handling Remove the if/else logic to exit from the in case a signal arrives. Update comments. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 0b7d7a2bd667 -r 1f9a27425952 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -806,7 +806,7 @@ int main(int argc, char *argv[]) } } - /* Write all pages back into the guest */ + /* If interrupted, write all pages back into the guest */ if ( interrupted == SIGTERM || interrupted == SIGINT ) { /* If no more pages to process, exit loop. */ @@ -815,13 +815,15 @@ int main(int argc, char *argv[]) /* One more round if there are still pages to process. */ resume_pages(paging, paging->num_paged_out); + + /* Resume main loop */ + continue; } - else - { - /* Exit on any other signal */ - if ( interrupted ) - break; - } + + /* Exit main loop on any other signal */ + if ( interrupted ) + break; + } DPRINTF("xenpaging got signal %d\n", interrupted); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 12 of 15] libxc: add bitmap_clear function
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189046 -7200 # Node ID 2a4c2be433b27cec227ef8441937b2088d2ec24b # Parent 1f9a27425952493878a54c82e0518b47560161af libxc: add bitmap_clear function Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 1f9a27425952 -r 2a4c2be433b2 tools/libxc/xc_bitops.h --- a/tools/libxc/xc_bitops.h +++ b/tools/libxc/xc_bitops.h @@ -4,6 +4,7 @@ /* bitmap operations for single threaded access */ #include <stdlib.h> +#include <string.h> #define BITS_PER_LONG (sizeof(unsigned long) * 8) #define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6) @@ -25,6 +26,11 @@ static inline unsigned long *bitmap_allo return calloc(1, bitmap_size(nr_bits)); } +static inline void bitmap_clear(unsigned long *addr, int nr_bits) +{ + memset(addr, 0, bitmap_size(nr_bits)); +} + static inline int test_bit(int nr, volatile unsigned long *addr) { return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 13 of 15] xenpaging: retry unpageable gfns
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189129 -7200 # Node ID 713701a53968823b8122f5a2a15b5e053143f2ed # Parent 2a4c2be433b27cec227ef8441937b2088d2ec24b xenpaging: retry unpageable gfns Nomination of gfns can fail, but may succeed later. Thats the case for a guest that starts ballooned. v2: - print debug when clearing uncosumed happens Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 2a4c2be433b2 -r 713701a53968 tools/xenpaging/policy_default.c --- a/tools/xenpaging/policy_default.c +++ b/tools/xenpaging/policy_default.c @@ -32,6 +32,7 @@ static unsigned int i_mru; static unsigned int mru_size; static unsigned long *bitmap; static unsigned long *unconsumed; +static unsigned int unconsumed_cleared; static unsigned long current_gfn; static unsigned long max_pages; @@ -87,8 +88,21 @@ int policy_choose_victim(xenpaging_t *pa current_gfn++; if ( current_gfn >= max_pages ) current_gfn = 0; + /* Could not nominate any gfn */ if ( wrap == current_gfn ) { + /* Count wrap arounds */ + unconsumed_cleared++; + /* Force retry every few seconds (depends on poll() timeout) */ + if ( unconsumed_cleared > 123) + { + /* Force retry of unconsumed gfns */ + bitmap_clear(unconsumed, max_pages); + unconsumed_cleared = 0; + DPRINTF("clearing unconsumed, wrap %lx", wrap); + /* One more round before returning ENOSPC */ + continue; + } victim->gfn = INVALID_MFN; return -ENOSPC; } _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 14 of 15] xenpaging: install into LIBEXEC dir
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189132 -7200 # Node ID 2b3dee863a39538071200443ca03609a49ca663b # Parent 713701a53968823b8122f5a2a15b5e053143f2ed xenpaging: install into LIBEXEC dir In preparation of upcoming libxl integration, move xenpaging binary from /usr/sbin/ to /usr/lib/xen/bin/ Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 713701a53968 -r 2b3dee863a39 tools/xenpaging/Makefile --- a/tools/xenpaging/Makefile +++ b/tools/xenpaging/Makefile @@ -24,8 +24,8 @@ xenpaging: $(OBJS) install: all $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging - $(INSTALL_DIR) $(DESTDIR)$(SBINDIR) - $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(SBINDIR) + $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC) + $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC) clean: rm -f *.o *~ $(DEPS) xen TAGS $(IBINS) $(LIB) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-21 09:31 UTC
[Xen-devel] [PATCH 15 of 15] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1319189153 -7200 # Node ID d3d27b9334496ff1f7ced83e1efa3f3a354e5998 # Parent 2b3dee863a39538071200443ca03609a49ca663b xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 2b3dee863a39 -r d3d27b933449 Config.mk --- a/Config.mk +++ b/Config.mk @@ -142,7 +142,7 @@ define buildmakevars2file-closure $(foreach var, \ SBINDIR BINDIR LIBEXEC LIBDIR SHAREDIR PRIVATE_BINDIR \ XENFIRMWAREDIR XEN_CONFIG_DIR XEN_SCRIPT_DIR XEN_LOCK_DIR \ - XEN_RUN_DIR, \ + XEN_RUN_DIR XEN_PAGING_DIR, \ echo "$(var)=\"$($(var))\"" >>$(1).tmp;) \ $(call move-if-changed,$(1).tmp,$(1)) endef diff -r 2b3dee863a39 -r d3d27b933449 config/StdGNU.mk --- a/config/StdGNU.mk +++ b/config/StdGNU.mk @@ -53,10 +53,12 @@ ifeq ($(PREFIX),/usr) CONFIG_DIR = /etc XEN_LOCK_DIR = /var/lock XEN_RUN_DIR = /var/run/xen +XEN_PAGING_DIR = /var/lib/xen/xenpaging else CONFIG_DIR = $(PREFIX)/etc XEN_LOCK_DIR = $(PREFIX)/var/lock XEN_RUN_DIR = $(PREFIX)/var/run/xen +XEN_PAGING_DIR = $(PREFIX)/var/lib/xen/xenpaging endif SYSCONFIG_DIR = $(CONFIG_DIR)/$(CONFIG_LEAF_DIR) diff -r 2b3dee863a39 -r d3d27b933449 tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -538,6 +538,7 @@ const char *libxl_xen_config_dir_path(vo const char *libxl_xen_script_dir_path(void); const char *libxl_lock_dir_path(void); const char *libxl_run_dir_path(void); +const char *libxl_xenpaging_dir_path(void); #endif /* LIBXL_H */ diff -r 2b3dee863a39 -r d3d27b933449 tools/libxl/libxl_paths.c --- a/tools/libxl/libxl_paths.c +++ b/tools/libxl/libxl_paths.c @@ -70,6 +70,11 @@ const char *libxl_run_dir_path(void) return XEN_RUN_DIR; } +const char *libxl_xenpaging_dir_path(void) +{ + return XEN_PAGING_DIR; +} + /* * Local variables: * mode: C diff -r 2b3dee863a39 -r d3d27b933449 tools/xenpaging/Makefile --- a/tools/xenpaging/Makefile +++ b/tools/xenpaging/Makefile @@ -23,7 +23,7 @@ xenpaging: $(OBJS) $(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) install: all - $(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging + $(INSTALL_DIR) $(DESTDIR)$(XEN_PAGING_DIR) $(INSTALL_DIR) $(DESTDIR)$(LIBEXEC) $(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Oct-25 17:40 UTC
Re: [Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event
Olaf Hering writes ("[Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event"):> xenpaging: compare both token and path when checking for @releaseDomain event > > Subsequent patches will use xenstored to store the numbers of pages > xenpaging is suppose to page-out. A domain_id value could be > misinterpreted as number of pages. Compare both path and token to > recognize the @releaseDomain event.I''m not sure I understand. What are you currently using as the token ? The token as well as the path should be sufficient to be able to tell what the event is, so this patch makes me suspicious ... Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-25 18:02 UTC
Re: [Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event
On Tue, Oct 25, Ian Jackson wrote:> Olaf Hering writes ("[Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event"): > > xenpaging: compare both token and path when checking for @releaseDomain event > > > > Subsequent patches will use xenstored to store the numbers of pages > > xenpaging is suppose to page-out. A domain_id value could be > > misinterpreted as number of pages. Compare both path and token to > > recognize the @releaseDomain event. > > I''m not sure I understand. What are you currently using as the > token ? The token as well as the path should be sufficient to be able > to tell what the event is, so this patch makes me suspicious ...I was under the impression there could be identical tokens for different paths, and that the actual value of the watched path is part of XS_WATCH_TOKEN. So this patch tries to make the detection of the @releaseDomain event more robust. But since the token seems to be unique (docs/misc/xenstore.txt has no further description of ''token''), only the DPRINTF part of my patch should be kept. Please drop this change, I will add the DPRINTF in a separate patch. Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Oct-25 18:13 UTC
Re: [Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event
Olaf Hering writes ("Re: [Xen-devel] [PATCH 10 of 15] xenpaging: compare both token and path when checking for @releaseDomain event"):> I was under the impression there could be identical tokens for different > paths,Yes, but you control the token. The token you get back in your watch event is whatever you gave to xs_watch.> and that the actual value of the watched path is part of > XS_WATCH_TOKEN."XS_WATCH_TOKEN" is just an array index into the return value of xs_read_watch. It has the value 1 which means that ret = xs_read_watch(...) returns the token in ret[1]. The path comes back in ret[0]. (The use of "xs_watch_type" as the name for this enum is unfortunate.)> But since the token seems to be unique (docs/misc/xenstore.txt has no > further description of ''token''), only the DPRINTF part of my patch > should be kept.The token is whatever you specified when you set up the watch. I haven''t checked in xenpagingd what that value is in this case. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel