Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 00 of 24] xenpaging fixes for xen-unstable
The following series adds support for xenpaging to libxl and the xl command. A few code cleanup changes are also part of this series. The logic of xenpaging was reversed. It does now monitor the guests tot_pages value and work toward that number by either paging out more pages, or write pages back into the guest. Three new configuration file options specific for xenpaging were added: totmem=<int> xenpaging_file=<string> xenpaging_extra=[ ''string'', ''string'' ] A new xl command ''mem-tot_pages'' instructs xenpaging to adjust its pagefile size, and it instructs the xl monitor process to actually start xenpaging if totmem= was not specified in the config file. Please review and apply. Olaf Config.mk | 2 config/StdGNU.mk | 2 tools/libxc/xc_bitops.h | 6 tools/libxl/libxl.c | 121 +++++++++ tools/libxl/libxl.h | 5 tools/libxl/libxl_create.c | 146 +++++++++++ tools/libxl/libxl_device.c | 84 ------ tools/libxl/libxl_dm.c | 65 +---- tools/libxl/libxl_dom.c | 8 tools/libxl/libxl_exec.c | 142 +++++++++++ tools/libxl/libxl_internal.h | 33 ++ tools/libxl/libxl_paths.c | 5 tools/libxl/libxl_types.idl | 4 tools/libxl/xl.h | 1 tools/libxl/xl_cmdimpl.c | 71 +++++ tools/libxl/xl_cmdtable.c | 5 tools/xenpaging/Makefile | 6 tools/xenpaging/file_ops.c | 6 tools/xenpaging/policy_default.c | 23 + tools/xenpaging/xenpaging.c | 479 ++++++++++++++++++++++++++++----------- tools/xenpaging/xenpaging.h | 8 21 files changed, 934 insertions(+), 288 deletions(-) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 01 of 24] xenpaging: remove filename from comment
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653595 -7200 # Node ID f2c4a25eec9ce1fcba0efb26ef21711929cca47c # Parent e78cd03b0308c3ba5737ba9821bf7272f45549ca xenpaging: remove filename from comment Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r e78cd03b0308 -r f2c4a25eec9c 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 e78cd03b0308 -r f2c4a25eec9c 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 e78cd03b0308 -r f2c4a25eec9c 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-03 15:54 UTC
[Xen-devel] [PATCH 02 of 24] xenpaging: remove obsolete comment in resume path
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653596 -7200 # Node ID 21b7c9a6545ac1ec9d91fce83d46aab0b5808b05 # Parent f2c4a25eec9ce1fcba0efb26ef21711929cca47c 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 f2c4a25eec9c -r 21b7c9a6545a tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -742,7 +742,6 @@ int main(int argc, char *argv[]) req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED); /* 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-03 15:54 UTC
[Xen-devel] [PATCH 03 of 24] xenpaging: use PERROR to print errno
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653597 -7200 # Node ID ee4c4c7699e0de2b6bddce1e816d35f36ffb0470 # Parent 21b7c9a6545ac1ec9d91fce83d46aab0b5808b05 xenpaging: use PERROR to print errno Also catch lseek() errors in file_op(). Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/file_ops.c --- a/tools/xenpaging/file_ops.c +++ b/tools/xenpaging/file_ops.c @@ -37,6 +37,11 @@ static int file_op(int fd, void *page, i int ret; seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET); + if (seek_ret == -1) + { + ret = -errno; + goto err; + } total = 0; while ( total < PAGE_SIZE ) diff -r 21b7c9a6545a -r ee4c4c7699e0 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; } @@ -240,13 +240,13 @@ static xenpaging_t *xenpaging_init(domid { switch ( errno ) { case EBUSY: - ERROR("xenpaging is (or was) active on this domain"); + PERROR("xenpaging is (or was) active on this domain"); break; case ENODEV: - ERROR("EPT not supported for this guest"); + PERROR("EPT not supported for this guest"); break; default: - ERROR("Error initialising shared page: %s", strerror(errno)); + PERROR("Error initialising shared page: %s", strerror(errno)); break; } goto err; @@ -256,7 +256,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; } @@ -266,7 +266,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; } @@ -276,7 +276,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; } @@ -284,7 +284,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; } @@ -292,7 +292,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); @@ -308,7 +308,7 @@ static xenpaging_t *xenpaging_init(domid rc = policy_init(paging); if ( rc != 0 ) { - ERROR("Error initialising policy"); + PERROR("Error initialising policy"); goto err; } @@ -355,14 +355,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; @@ -370,7 +370,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; @@ -381,7 +381,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; @@ -441,7 +441,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; } @@ -449,8 +449,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; } @@ -752,7 +752,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-03 15:54 UTC
[Xen-devel] [PATCH 04 of 24] xenpaging: update xenpaging_init
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653599 -7200 # Node ID cef74f38274df3bf619f9b4f80d2843dd033fea5 # Parent ee4c4c7699e0de2b6bddce1e816d35f36ffb0470 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 ee4c4c7699e0 -r cef74f38274d 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; @@ -319,7 +319,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); @@ -337,7 +338,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-03 15:54 UTC
[Xen-devel] [PATCH 05 of 24] xenpaging: remove xc_dominfo_t from paging_t
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653600 -7200 # Node ID 003ad7aa543db226db53760549a172dcff236672 # Parent cef74f38274df3bf619f9b4f80d2843dd033fea5 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 cef74f38274d -r 003ad7aa543d 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 cef74f38274d -r 003ad7aa543d 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; @@ -272,34 +273,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; @@ -334,7 +330,6 @@ static xenpaging_t *xenpaging_init(domid } free(paging->bitmap); - free(paging->domain_info); free(paging); } @@ -763,7 +758,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) ) { @@ -779,7 +774,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 cef74f38274d -r 003ad7aa543d 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-03 15:54 UTC
[Xen-devel] [PATCH 06 of 24] xenpaging: track the number of paged-out pages
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653601 -7200 # Node ID 363c2f3df22b27d56297fa96f8d1706e224a323e # Parent 003ad7aa543db226db53760549a172dcff236672 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 003ad7aa543d -r 363c2f3df22b 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 003ad7aa543d -r 363c2f3df22b 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-03 15:54 UTC
[Xen-devel] [PATCH 07 of 24] xenpaging: move page add/resume loops into its own function
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653603 -7200 # Node ID 02453d6279baad46b1388267639892feaf6d56af # Parent 363c2f3df22b27d56297fa96f8d1706e224a323e 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 363c2f3df22b -r 02453d6279ba 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; @@ -765,25 +806,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-03 15:54 UTC
[Xen-devel] [PATCH 08 of 24] xenpaging: compare both token and path when checking for @releaseDomain event
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653604 -7200 # Node ID 87cc0a717a5edc87411295ad0d5cf0b3366da0d3 # Parent 02453d6279baad46b1388267639892feaf6d56af 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 02453d6279ba -r 87cc0a717a5e 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-03 15:54 UTC
[Xen-devel] [PATCH 09 of 24] xenpaging: improve mainloop exit handling
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653605 -7200 # Node ID 5d2d87fb19e4749ca11d9d002ee5b44271594cb3 # Parent 87cc0a717a5edc87411295ad0d5cf0b3366da0d3 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 87cc0a717a5e -r 5d2d87fb19e4 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -804,7 +804,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. */ @@ -813,13 +813,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-03 15:54 UTC
[Xen-devel] [PATCH 10 of 24] libxc: add bitmap_clear function
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653607 -7200 # Node ID b85b2fa9a485cdd815eb9eb3e3a7794b462fa814 # Parent 5d2d87fb19e4749ca11d9d002ee5b44271594cb3 libxc: add bitmap_clear function Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 5d2d87fb19e4 -r b85b2fa9a485 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-03 15:54 UTC
[Xen-devel] [PATCH 11 of 24] xenpaging: retry unpageable gfns
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653608 -7200 # Node ID 3924c1ef71ee975b4556ca7766b730dfa3e12295 # Parent b85b2fa9a485cdd815eb9eb3e3a7794b462fa814 xenpaging: retry unpageable gfns Nomination of gfns can fail, but may succeed later. Thats the case for a guest that starts ballooned. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r b85b2fa9a485 -r 3924c1ef71ee 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,20 @@ 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; + /* 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-03 15:54 UTC
[Xen-devel] [PATCH 12 of 24] libxl: rename libxl__device_model_starting
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653609 -7200 # Node ID ea8738e045595a235fc05384d3f4d7c74537cd0a # Parent 3924c1ef71ee975b4556ca7766b730dfa3e12295 libxl: rename libxl__device_model_starting Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -434,7 +434,7 @@ static int do_domain_create(libxl__gc *g uint32_t *domid_out, int restore_fd) { libxl_ctx *ctx = libxl__gc_owner(gc); - libxl__device_model_starting *dm_starting = 0; + libxl__spawner_starting *dm_starting = 0; libxl_device_model_info *dm_info = &d_config->dm_info; libxl__domain_build_state state; uint32_t domid; diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -518,7 +518,7 @@ static char ** libxl__build_device_model static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) { - libxl__device_model_starting *starting = for_spawn; + libxl__spawner_starting *starting = for_spawn; struct xs_handle *xsh; char *path = NULL, *pid = NULL; int len; @@ -619,7 +619,7 @@ static int libxl__create_stubdom(libxl__ libxl_device_nic *vifs, int num_vifs, libxl_device_vfb *vfb, libxl_device_vkb *vkb, - libxl__device_model_starting **starting_r) + libxl__spawner_starting **starting_r) { libxl_ctx *ctx = libxl__gc_owner(gc); int i, num_console = STUBDOM_SPECIAL_CONSOLES, ret; @@ -631,7 +631,7 @@ static int libxl__create_stubdom(libxl__ char **args; struct xs_permissions perm[2]; xs_transaction_t t; - libxl__device_model_starting *dm_starting = 0; + libxl__spawner_starting *dm_starting = 0; libxl_device_model_info xenpv_dm_info; if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) { @@ -784,7 +784,7 @@ retry_transaction: libxl_domain_unpause(ctx, domid); if (starting_r) { - *starting_r = calloc(1, sizeof(libxl__device_model_starting)); + *starting_r = calloc(1, sizeof(libxl__spawner_starting)); (*starting_r)->domid = info->domid; (*starting_r)->dom_path = libxl__xs_get_dompath(gc, info->domid); (*starting_r)->for_spawn = NULL; @@ -802,14 +802,14 @@ int libxl__create_device_model(libxl__gc libxl_device_model_info *info, libxl_device_disk *disks, int num_disks, libxl_device_nic *vifs, int num_vifs, - libxl__device_model_starting **starting_r) + libxl__spawner_starting **starting_r) { libxl_ctx *ctx = libxl__gc_owner(gc); char *path, *logfile; int logfile_w, null; int rc; char **args; - libxl__device_model_starting buf_starting, *p; + libxl__spawner_starting buf_starting, *p; xs_transaction_t t; char *vm_path; char **pass_stuff; @@ -861,7 +861,7 @@ int libxl__create_device_model(libxl__gc if (starting_r) { rc = ERROR_NOMEM; - *starting_r = calloc(1, sizeof(libxl__device_model_starting)); + *starting_r = calloc(1, sizeof(libxl__spawner_starting)); if (!*starting_r) goto out_close; p = *starting_r; @@ -915,7 +915,7 @@ out: } static int detach_device_model(libxl__gc *gc, - libxl__device_model_starting *starting) + libxl__spawner_starting *starting) { int rc; rc = libxl__spawn_detach(gc, starting->for_spawn); @@ -926,7 +926,7 @@ static int detach_device_model(libxl__gc } int libxl__confirm_device_model_startup(libxl__gc *gc, - libxl__device_model_starting *starting) + libxl__spawner_starting *starting) { int detach; int problem = libxl__wait_for_device_model(gc, starting->domid, "running", @@ -1041,7 +1041,7 @@ out: int libxl__create_xenpv_qemu(libxl__gc *gc, uint32_t domid, libxl_device_model_info *info, libxl_device_vfb *vfb, - libxl__device_model_starting **starting_r) + libxl__spawner_starting **starting_r) { libxl__build_xenpv_qemu_args(gc, domid, vfb, info); libxl__create_device_model(gc, info, NULL, 0, NULL, 0, starting_r); diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -252,7 +252,7 @@ typedef struct { char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */ int domid; libxl__spawn_starting *for_spawn; -} libxl__device_model_starting; +} libxl__spawner_starting; /* from xl_create */ _hidden int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info, uint32_t *domid); @@ -269,11 +269,11 @@ _hidden int libxl__create_device_model(l libxl_device_model_info *info, libxl_device_disk *disk, int num_disks, libxl_device_nic *vifs, int num_vifs, - libxl__device_model_starting **starting_r); + libxl__spawner_starting **starting_r); _hidden int libxl__create_xenpv_qemu(libxl__gc *gc, uint32_t domid, libxl_device_model_info *dm_info, libxl_device_vfb *vfb, - libxl__device_model_starting **starting_r); + libxl__spawner_starting **starting_r); _hidden int libxl__need_xenpv_qemu(libxl__gc *gc, int nr_consoles, libxl_device_console *consoles, int nr_vfbs, libxl_device_vfb *vfbs, @@ -282,8 +282,8 @@ _hidden int libxl__need_xenpv_qemu(libxl * return pass *starting_r (which will be non-0) to * libxl_confirm_device_model or libxl_detach_device_model. */ _hidden int libxl__confirm_device_model_startup(libxl__gc *gc, - libxl__device_model_starting *starting); -_hidden int libxl__detach_device_model(libxl__gc *gc, libxl__device_model_starting *starting); + libxl__spawner_starting *starting); +_hidden int libxl__detach_device_model(libxl__gc *gc, libxl__spawner_starting *starting); _hidden int libxl__wait_for_device_model(libxl__gc *gc, uint32_t domid, char *state, libxl__spawn_starting *spawning, _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 13 of 24] libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653611 -7200 # Node ID df7be429654c62fb4c61f83549374d77b80ebea3 # Parent ea8738e045595a235fc05384d3f4d7c74537cd0a libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -516,31 +516,6 @@ static char ** libxl__build_device_model } } -static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild) -{ - libxl__spawner_starting *starting = for_spawn; - struct xs_handle *xsh; - char *path = NULL, *pid = NULL; - int len; - - if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0) - goto out; - - len = asprintf(&pid, "%d", innerchild); - if (len < 0) - goto out; - - /* we mustn''t use the parent''s handle in the child */ - xsh = xs_daemon_open(); - - xs_write(xsh, XBT_NULL, path, pid, len); - - xs_daemon_close(xsh); -out: - free(path); - free(pid); -} - static int libxl__vfb_and_vkb_from_device_model_info(libxl__gc *gc, libxl_device_model_info *info, libxl_device_vfb *vfb, @@ -896,7 +871,7 @@ retry_transaction: } rc = libxl__spawn_spawn(gc, p->for_spawn, "device model", - dm_xenstore_record_pid, p); + libxl_spawner_record_pid, p); if (rc < 0) goto out_close; if (!rc) { /* inner child */ diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -144,6 +144,31 @@ void libxl_report_child_exitstatus(libxl } } +void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild) +{ + libxl__spawner_starting *starting = for_spawn; + struct xs_handle *xsh; + char *path = NULL, *pid = NULL; + int len; + + if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0) + goto out; + + len = asprintf(&pid, "%d", innerchild); + if (len < 0) + goto out; + + /* we mustn''t use the parent''s handle in the child */ + xsh = xs_daemon_open(); + + xs_write(xsh, XBT_NULL, path, pid, len); + + xs_daemon_close(xsh); +out: + free(path); + free(pid); +} + static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag) { int flags; diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -249,7 +249,7 @@ typedef struct { } libxl__spawn_starting; typedef struct { - char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */ + char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ int domid; libxl__spawn_starting *for_spawn; } libxl__spawner_starting; @@ -300,6 +300,8 @@ _hidden int libxl__spawn_spawn(libxl__gc void *hook_data); _hidden int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid); +_hidden void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild); + /* Logs errors. A copy of "what" is taken. Return values: * < 0 error, for_spawn need not be detached * +1 caller is the parent, must call detach on *for_spawn eventually _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653612 -7200 # Node ID 219ab93f22c0492595686a1cc34911e9d6775b07 # Parent df7be429654c62fb4c61f83549374d77b80ebea3 libxl: add pid path to libxl__spawner_starting libxl_spawner_record_pid() should be able to write the pid to arbitrary paths. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -848,6 +848,7 @@ int libxl__create_device_model(libxl__gc p->domid = info->domid; p->dom_path = libxl__xs_get_dompath(gc, info->domid); + p->pid_path = "image/device-model-pid"; if (!p->dom_path) { rc = ERROR_FAIL; goto out_close; diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -151,7 +151,7 @@ void libxl_spawner_record_pid(void *for_ char *path = NULL, *pid = NULL; int len; - if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0) + if (asprintf(&path, "%s/%s", starting->dom_path, starting->pid_path) < 0) goto out; len = asprintf(&pid, "%d", innerchild); diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -250,6 +250,7 @@ typedef struct { typedef struct { char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ + char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ int domid; libxl__spawn_starting *for_spawn; } libxl__spawner_starting; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 15 of 24] libxl: add libxl__wait_for_offspring function
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653613 -7200 # Node ID cfca4b1f83f9c2ebf1c1986aad51571243db4c77 # Parent 219ab93f22c0492595686a1cc34911e9d6775b07 libxl: add libxl__wait_for_offspring function libxl__wait_for_offspring() is a generic version of libxl__wait_for_device_model(). Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -169,6 +169,99 @@ out: free(pid); } +int libxl__wait_for_offspring(libxl__gc *gc, + uint32_t domid, + uint32_t timeout, char *what, + char *path, char *state, + libxl__spawn_starting *spawning, + int (*check_callback)(libxl__gc *gc, + uint32_t domid, + const char *state, + void *userdata), + void *check_callback_userdata) +{ + libxl_ctx *ctx = libxl__gc_owner(gc); + char *p; + unsigned int len; + int rc = 0; + struct xs_handle *xsh; + int nfds; + fd_set rfds; + struct timeval tv; + unsigned int num; + char **l = NULL; + + xsh = xs_daemon_open(); + if (xsh == NULL) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to open xenstore connection"); + goto err; + } + + xs_watch(xsh, path, path); + tv.tv_sec = timeout; + tv.tv_usec = 0; + nfds = xs_fileno(xsh) + 1; + if (spawning && spawning->fd > xs_fileno(xsh)) + nfds = spawning->fd + 1; + + while (rc > 0 || (!rc && tv.tv_sec > 0)) { + if ( spawning ) { + rc = libxl__spawn_check(gc, spawning); + if ( rc ) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "%s died during startup", what); + rc = -1; + goto err_died; + } + } + p = xs_read(xsh, XBT_NULL, path, &len); + if ( NULL == p ) + goto again; + + if ( NULL != state && strcmp(p, state) ) + goto again; + + if ( NULL != check_callback ) { + rc = (*check_callback)(gc, domid, p, check_callback_userdata); + if ( rc > 0 ) + goto again; + } + + free(p); + xs_unwatch(xsh, path, path); + xs_daemon_close(xsh); + return rc; +again: + free(p); + FD_ZERO(&rfds); + FD_SET(xs_fileno(xsh), &rfds); + if (spawning) + FD_SET(spawning->fd, &rfds); + rc = select(nfds, &rfds, NULL, NULL, &tv); + if (rc > 0) { + if (FD_ISSET(xs_fileno(xsh), &rfds)) { + l = xs_read_watch(xsh, &num); + if (l != NULL) + free(l); + else + goto again; + } + if (spawning && FD_ISSET(spawning->fd, &rfds)) { + unsigned char dummy; + if (read(spawning->fd, &dummy, sizeof(dummy)) != 1) + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG, + "failed to read spawn status pipe"); + } + } + } + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "%s not ready", what); +err_died: + xs_unwatch(xsh, path, path); + xs_daemon_close(xsh); +err: + return -1; +} + static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag) { int flags; diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -303,6 +303,16 @@ _hidden int libxl__destroy_device_model( _hidden void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild); +_hidden int libxl__wait_for_offspring(libxl__gc *gc, + uint32_t domid, + uint32_t timeout, char *what, + char *path, char *state, + libxl__spawn_starting *spawning, + int (*check_callback)(libxl__gc *gc, + uint32_t domid, + const char *state, + void *userdata), + void *check_callback_userdata); /* Logs errors. A copy of "what" is taken. Return values: * < 0 error, for_spawn need not be detached * +1 caller is the parent, must call detach on *for_spawn eventually @@ -318,7 +328,7 @@ _hidden int libxl__spawn_check(libxl__gc /* Logs errors but also returns them. * for_spawn must actually be a libxl__spawn_starting* but * we take void* so you can pass this function directly to - * libxl__wait_for_device_model. Caller must still call detach. */ + * libxl__wait_for_offspring. Caller must still call detach. */ /* low-level stuff, for synchronous subprocesses etc. */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 16 of 24] libxl: use libxl__wait_for_offspring for device model
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653615 -7200 # Node ID 35ec0355b3283a87477c7377a2fd3da5e84d2bcd # Parent cfca4b1f83f9c2ebf1c1986aad51571243db4c77 libxl: use libxl__wait_for_offspring for device model Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r cfca4b1f83f9 -r 35ec0355b328 tools/libxl/libxl_device.c --- a/tools/libxl/libxl_device.c +++ b/tools/libxl/libxl_device.c @@ -535,88 +535,12 @@ int libxl__wait_for_device_model(libxl__ void *userdata), void *check_callback_userdata) { - libxl_ctx *ctx = libxl__gc_owner(gc); char *path; - char *p; - unsigned int len; - int rc = 0; - struct xs_handle *xsh; - int nfds; - fd_set rfds; - struct timeval tv; - unsigned int num; - char **l = NULL; - - xsh = xs_daemon_open(); - if (xsh == NULL) { - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to open xenstore connection"); - goto err; - } - path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); - xs_watch(xsh, path, path); - tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT; - tv.tv_usec = 0; - nfds = xs_fileno(xsh) + 1; - if (spawning && spawning->fd > xs_fileno(xsh)) - nfds = spawning->fd + 1; - - while (rc > 0 || (!rc && tv.tv_sec > 0)) { - if ( spawning ) { - rc = libxl__spawn_check(gc, spawning); - if ( rc ) { - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, - "Device Model died during startup"); - rc = -1; - goto err_died; - } - } - p = xs_read(xsh, XBT_NULL, path, &len); - if ( NULL == p ) - goto again; - - if ( NULL != state && strcmp(p, state) ) - goto again; - - if ( NULL != check_callback ) { - rc = (*check_callback)(gc, domid, p, check_callback_userdata); - if ( rc > 0 ) - goto again; - } - - free(p); - xs_unwatch(xsh, path, path); - xs_daemon_close(xsh); - return rc; -again: - free(p); - FD_ZERO(&rfds); - FD_SET(xs_fileno(xsh), &rfds); - if (spawning) - FD_SET(spawning->fd, &rfds); - rc = select(nfds, &rfds, NULL, NULL, &tv); - if (rc > 0) { - if (FD_ISSET(xs_fileno(xsh), &rfds)) { - l = xs_read_watch(xsh, &num); - if (l != NULL) - free(l); - else - goto again; - } - if (spawning && FD_ISSET(spawning->fd, &rfds)) { - unsigned char dummy; - if (read(spawning->fd, &dummy, sizeof(dummy)) != 1) - LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG, - "failed to read spawn status pipe"); - } - } - } - LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Device Model not ready"); -err_died: - xs_unwatch(xsh, path, path); - xs_daemon_close(xsh); -err: - return -1; + return libxl__wait_for_offspring(gc, domid, + LIBXL_DEVICE_MODEL_START_TIMEOUT, + "Device Model", path, state, spawning, + check_callback, check_callback_userdata); } int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653616 -7200 # Node ID 018f63b6e4863faca16a832a5a34c6a6e7726cf7 # Parent 35ec0355b3283a87477c7377a2fd3da5e84d2bcd libxl: add libxl__spawn_confirm_offspring_startup libxl__spawn_confirm_offspring_startup() is a generic version of libxl__confirm_device_model_startup(). Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 35ec0355b328 -r 018f63b6e486 tools/libxl/libxl_exec.c --- a/tools/libxl/libxl_exec.c +++ b/tools/libxl/libxl_exec.c @@ -262,6 +262,30 @@ err: return -1; } +static int detach_offspring(libxl__gc *gc, + libxl__spawner_starting *starting) +{ + int rc; + rc = libxl__spawn_detach(gc, starting->for_spawn); + if (starting->for_spawn) + free(starting->for_spawn); + free(starting); + return rc; +} + +int libxl__spawn_confirm_offspring_startup(libxl__gc *gc, + uint32_t timeout, char *what, + char *path, char *state, + libxl__spawner_starting *starting) +{ + int detach; + int problem = libxl__wait_for_offspring(gc, starting->domid, timeout, what, + path, state, + starting->for_spawn, NULL, NULL); + detach = detach_offspring(gc, starting); + return problem ? problem : detach; +} + static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag) { int flags; diff -r 35ec0355b328 -r 018f63b6e486 tools/libxl/libxl_internal.h --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -313,6 +313,12 @@ _hidden int libxl__wait_for_offspring(li const char *state, void *userdata), void *check_callback_userdata); + +_hidden int libxl__spawn_confirm_offspring_startup(libxl__gc *gc, + uint32_t timeout, char *what, + char *path, char *state, + libxl__spawner_starting *starting); + /* Logs errors. A copy of "what" is taken. Return values: * < 0 error, for_spawn need not be detached * +1 caller is the parent, must call detach on *for_spawn eventually _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 18 of 24] libxl: use libxl__spawn_confirm_offspring_startup for device model
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653617 -7200 # Node ID acc1ee9d0c10a961834029726d11227c2ff9e97b # Parent 018f63b6e4863faca16a832a5a34c6a6e7726cf7 libxl: use libxl__spawn_confirm_offspring_startup for device model Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 018f63b6e486 -r acc1ee9d0c10 tools/libxl/libxl_dm.c --- a/tools/libxl/libxl_dm.c +++ b/tools/libxl/libxl_dm.c @@ -890,25 +890,16 @@ out: return rc; } -static int detach_device_model(libxl__gc *gc, - libxl__spawner_starting *starting) -{ - int rc; - rc = libxl__spawn_detach(gc, starting->for_spawn); - if (starting->for_spawn) - free(starting->for_spawn); - free(starting); - return rc; -} int libxl__confirm_device_model_startup(libxl__gc *gc, libxl__spawner_starting *starting) { - int detach; - int problem = libxl__wait_for_device_model(gc, starting->domid, "running", - starting->for_spawn, NULL, NULL); - detach = detach_device_model(gc, starting); - return problem ? problem : detach; + char *path; + int domid = starting->domid; + path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid); + return libxl__spawn_confirm_offspring_startup(gc, + LIBXL_DEVICE_MODEL_START_TIMEOUT, + "Device Model", path, "running", starting); } int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid) _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 19 of 24] xenpaging: install into LIBEXEC dir
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653619 -7200 # Node ID f9b5da9bcffdd96dcae4a26ead0b9c26507711e4 # Parent acc1ee9d0c10a961834029726d11227c2ff9e97b 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 acc1ee9d0c10 -r f9b5da9bcffd 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-03 15:54 UTC
[Xen-devel] [PATCH 20 of 24] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653620 -7200 # Node ID 916749c1775b4435629c747afa4b38c8cbb7dd5b # Parent f9b5da9bcffdd96dcae4a26ead0b9c26507711e4 xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r f9b5da9bcffd -r 916749c1775b Config.mk --- a/Config.mk +++ b/Config.mk @@ -138,7 +138,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 f9b5da9bcffd -r 916749c1775b 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 f9b5da9bcffd -r 916749c1775b 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 f9b5da9bcffd -r 916749c1775b tools/libxl/libxl_paths.c --- a/tools/libxl/libxl_paths.c +++ b/tools/libxl/libxl_paths.c @@ -69,3 +69,8 @@ const char *libxl_run_dir_path(void) { return XEN_RUN_DIR; } + +const char *libxl_xenpaging_dir_path(void) +{ + return XEN_PAGING_DIR; +} diff -r f9b5da9bcffd -r 916749c1775b 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
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 21 of 24] xenpaging: use guests tot_pages as working target
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317653622 -7200 # Node ID 8fa2067ed61105a0ae31939f0ca58b8921fc55d4 # Parent 916749c1775b4435629c747afa4b38c8cbb7dd5b xenpaging: use guests tot_pages as working target Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/policy_default.c --- a/tools/xenpaging/policy_default.c +++ b/tools/xenpaging/policy_default.c @@ -71,7 +71,6 @@ int policy_init(xenpaging_t *paging) /* Start in the middle to avoid paging during BIOS startup */ current_gfn = max_pages / 2; - current_gfn -= paging->num_pages / 2; rc = 0; out: diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -137,6 +137,21 @@ err: return rc; } +static int xenpaging_get_tot_pages(xenpaging_t *paging) +{ + xc_interface *xch = paging->xc_handle; + xc_domaininfo_t domain_info; + int rc; + + rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, &domain_info); + if ( rc != 1 ) + { + PERROR("Error getting domain info"); + return -1; + } + return domain_info.tot_pages; +} + static void *init_page(void) { void *buffer; @@ -162,7 +177,7 @@ static void *init_page(void) return NULL; } -static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages) +static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages) { xenpaging_t *paging; xc_domaininfo_t domain_info; @@ -294,12 +309,7 @@ static xenpaging_t *xenpaging_init(domid } DPRINTF("max_pages = %d\n", paging->max_pages); - if ( num_pages < 0 || num_pages > paging->max_pages ) - { - num_pages = paging->max_pages; - DPRINTF("setting num_pages to %d\n", num_pages); - } - paging->num_pages = num_pages; + paging->target_tot_pages = target_tot_pages; /* Initialise policy */ rc = policy_init(paging); @@ -649,7 +659,9 @@ int main(int argc, char *argv[]) xenpaging_victim_t *victims; mem_event_request_t req; mem_event_response_t rsp; + int num, prev_num = 0; int i; + int tot_pages; int rc = -1; int rc1; xc_interface *xch; @@ -660,7 +672,7 @@ int main(int argc, char *argv[]) if ( argc != 3 ) { - fprintf(stderr, "Usage: %s <domain_id> <num_pages>\n", argv[0]); + fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]); return -1; } @@ -673,7 +685,7 @@ int main(int argc, char *argv[]) } xch = paging->xc_handle; - DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->num_pages); + DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages); /* Open file */ sprintf(filename, "page_cache_%u", paging->mem_event.domain_id); @@ -705,9 +717,6 @@ int main(int argc, char *argv[]) /* listen for page-in events to stop pager */ create_page_in_thread(paging); - i = evict_pages(paging, fd, victims, paging->num_pages); - DPRINTF("%d pages evicted. Done.\n", i); - /* Swap pages in and out */ while ( 1 ) { @@ -772,12 +781,8 @@ int main(int argc, char *argv[]) goto out; } - /* Evict a new page to replace the one we just paged in, - * or clear this pagefile slot on exit */ - if ( interrupted ) - victims[i].gfn = INVALID_MFN; - else - evict_victim(paging, &victims[i], fd, i); + /* Clear this pagefile slot */ + victims[i].gfn = INVALID_MFN; } else { @@ -822,6 +827,43 @@ int main(int argc, char *argv[]) if ( interrupted ) break; + /* Check if the target has been reached already */ + tot_pages = xenpaging_get_tot_pages(paging); + if ( tot_pages < 0 ) + goto out; + + /* Resume all pages if paging is disabled or no target was set */ + if ( paging->target_tot_pages == 0 ) + { + if ( paging->num_paged_out ) + resume_pages(paging, paging->num_paged_out); + } + /* Evict more pages if target not reached */ + else if ( tot_pages > paging->target_tot_pages ) + { + num = tot_pages - paging->target_tot_pages; + if ( num != prev_num ) + { + DPRINTF("Need to evict %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages); + prev_num = num; + } + /* Limit the number of evicts to be able to process page-in requests */ + if ( num > 42 ) + num = 42; + evict_pages(paging, fd, victims, num); + } + /* Resume some pages if target not reached */ + else if ( tot_pages < paging->target_tot_pages && paging->num_paged_out ) + { + num = paging->target_tot_pages - tot_pages; + if ( num != prev_num ) + { + DPRINTF("Need to resume %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages); + prev_num = num; + } + resume_pages(paging, num); + } + } DPRINTF("xenpaging got signal %d\n", interrupted); diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/xenpaging.h --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -50,7 +50,7 @@ typedef struct xenpaging { /* number of pages for which data structures were allocated */ int max_pages; int num_paged_out; - int num_pages; + int target_tot_pages; int policy_mru_size; unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; } xenpaging_t; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:54 UTC
[Xen-devel] [PATCH 22 of 24] xenpaging: watch the guests memory/target-tot_pages xenstore value
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317656685 -7200 # Node ID 59303aeb11d96c5c94da2e9feb2ef9728236f90d # Parent 8fa2067ed61105a0ae31939f0ca58b8921fc55d4 xenpaging: watch the guests memory/target-tot_pages xenstore value Subsequent patches will use xenstored to store the numbers of pages xenpaging is suppose to page-out. Remove num_pages and use target_pages instead. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 8fa2067ed611 -r 59303aeb11d9 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -19,8 +19,10 @@ */ #define _XOPEN_SOURCE 600 +#define _GNU_SOURCE #include <inttypes.h> +#include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <time.h> @@ -35,6 +37,10 @@ #include "policy.h" #include "xenpaging.h" +/* Defines number of mfns a guest should use at a time, in KiB */ +#define WATCH_TARGETPAGES "memory/target-tot_pages" +static char *watch_target_tot_pages; +static char *dom_path; static char watch_token[16]; static char filename[80]; static int interrupted; @@ -72,7 +78,7 @@ static int xenpaging_wait_for_event_or_t { xc_interface *xch = paging->xc_handle; xc_evtchn *xce = paging->mem_event.xce_handle; - char **vec; + char **vec, *val; unsigned int num; struct pollfd fd[2]; int port; @@ -112,6 +118,25 @@ static int xenpaging_wait_for_event_or_t rc = 0; } } + else if ( strcmp(vec[XS_WATCH_PATH], watch_target_tot_pages) == 0 ) + { + int ret, target_tot_pages; + val = xs_read(paging->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], NULL); + if ( val ) + { + ret = sscanf(val, "%d", &target_tot_pages); + if ( ret > 0 ) + { + /* KiB to pages */ + target_tot_pages >>= 2; + if ( target_tot_pages < 0 || target_tot_pages > paging->max_pages ) + target_tot_pages = paging->max_pages; + paging->target_tot_pages = target_tot_pages; + DPRINTF("new target_tot_pages %d\n", target_tot_pages); + } + free(val); + } + } free(vec); } } @@ -217,6 +242,25 @@ static xenpaging_t *xenpaging_init(domid goto err; } + /* watch guests xenpaging directory */ + dom_path = xs_get_domain_path(paging->xs_handle, domain_id); + if ( !dom_path ) + { + PERROR("Could not find domain path\n"); + goto err; + } + if ( asprintf(&watch_target_tot_pages, "%s/%s", dom_path, WATCH_TARGETPAGES) < 0 ) + { + PERROR("Could not alloc watch path\n"); + goto err; + } + DPRINTF("watching ''%s''\n", watch_target_tot_pages); + if ( xs_watch(paging->xs_handle, watch_target_tot_pages, "") == false ) + { + PERROR("Could not bind to xenpaging watch\n"); + goto err; + } + p = getenv("XENPAGING_POLICY_MRU_SIZE"); if ( p && *p ) { @@ -340,6 +384,8 @@ static xenpaging_t *xenpaging_init(domid free(paging->mem_event.ring_page); } + free(dom_path); + free(watch_target_tot_pages); free(paging->bitmap); free(paging); } @@ -355,6 +401,9 @@ static int xenpaging_teardown(xenpaging_ if ( paging == NULL ) return 0; + 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 */ _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-03 15:55 UTC
[Xen-devel] [PATCH 23 of 24] xenpaging: add cmdline interface for pager
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317656694 -7200 # Node ID 5dd8e13e8222486bc09894dc3245c28a7e654d0a # Parent 59303aeb11d96c5c94da2e9feb2ef9728236f90d xenpaging: add cmdline interface for pager Introduce a cmdline handling for the pager. This simplifies libxl support, debug and mru_size are not passed via the environment anymore. The new interface looks like this: xenpaging [options] -f <pagefile> <domain_id> options: -f <file> --pagefile=<file> pagefile to use. This option is required. -m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle. -r <num> --mru_size=<num> number of paged-in pages to keep in memory. -d --debug enable debug output. -h --help this output. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 59303aeb11d9 -r 5dd8e13e8222 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -31,6 +31,7 @@ #include <poll.h> #include <xc_private.h> #include <xs.h> +#include <getopt.h> #include "xc_bitops.h" #include "file_ops.h" @@ -42,12 +43,12 @@ static char *watch_target_tot_pages; static char *dom_path; static char watch_token[16]; -static char filename[80]; +static char *filename; static int interrupted; static void unlink_pagefile(void) { - if ( filename[0] ) + if ( filename && filename[0] ) { unlink(filename); filename[0] = ''\0''; @@ -202,11 +203,89 @@ static void *init_page(void) return NULL; } -static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages) +static void usage(void) +{ + printf("usage:\n\n"); + + printf(" xenpaging [options] -f <pagefile> <domain_id>\n\n"); + + printf("options:\n"); + printf(" -f <file> --pagefile=<file> pagefile to use. This option is required.\n"); + printf(" -m <max_memkb> --max_memkb=<max_memkb> maximum amount of memory to handle.\n"); + printf(" -r <num> --mru_size=<num> number of paged-in pages to keep in memory.\n"); + printf(" -d --debug enable debug output.\n"); + printf(" -h --help this output.\n"); +} + +static int xenpaging_getopts(xenpaging_t *paging, int argc, char *argv[]) +{ + int ch; + static const char sopts[] = "hdf:m:r:"; + static const struct option lopts[] = { + {"help", 0, NULL, ''h''}, + {"debug", 0, NULL, ''d''}, + {"pagefile", 1, NULL, ''f''}, + {"mru_size", 1, NULL, ''m''}, + { } + }; + + while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) + { + switch(ch) { + case ''f'': + filename = strdup(optarg); + break; + case ''m'': + /* KiB to pages */ + paging->max_pages = atoi(optarg) >> 2; + break; + case ''r'': + paging->policy_mru_size = atoi(optarg); + break; + case ''d'': + paging->debug = 1; + break; + case ''h'': + case ''?'': + usage(); + return 1; + } + } + + argv += optind; argc -= optind; + + /* Remaining argument is guest domain_id */ + if ( argc != 1 ) + { + printf("Numerical <domain_id> value missing!\n"); + usage(); + return 1; + } + + /* Path to pagefile is required */ + if ( !filename ) + { + printf("Filename for pagefile missing!\n"); + usage(); + return 1; + } + + /* Set domain id */ + paging->mem_event.domain_id = atoi(argv[0]); + if ( paging->mem_event.domain_id == 0 ) + { + printf("Cannot page dom0!\n"); + return 1; + } + + return 0; +} + +static xenpaging_t *xenpaging_init(int argc, char *argv[]) { xenpaging_t *paging; xc_domaininfo_t domain_info; - xc_interface *xch; + xc_interface *xch = NULL; xentoollog_logger *dbg = NULL; char *p; int rc; @@ -216,7 +295,12 @@ static xenpaging_t *xenpaging_init(domid if ( !paging ) goto err; - if ( getenv("XENPAGING_DEBUG") ) + /* Get cmdline options and domain_id */ + if ( xenpaging_getopts(paging, argc, argv) ) + goto err; + + /* Enable debug output */ + if ( paging->debug ) dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0); /* Open connection to xen */ @@ -235,7 +319,7 @@ static xenpaging_t *xenpaging_init(domid } /* write domain ID to watch so we can ignore other domain shutdowns */ - snprintf(watch_token, sizeof(watch_token), "%u", domain_id); + snprintf(watch_token, sizeof(watch_token), "%u", paging->mem_event.domain_id); if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false ) { PERROR("Could not bind to shutdown watch\n"); @@ -243,7 +327,7 @@ static xenpaging_t *xenpaging_init(domid } /* watch guests xenpaging directory */ - dom_path = xs_get_domain_path(paging->xs_handle, domain_id); + dom_path = xs_get_domain_path(paging->xs_handle, paging->mem_event.domain_id); if ( !dom_path ) { PERROR("Could not find domain path\n"); @@ -261,16 +345,6 @@ static xenpaging_t *xenpaging_init(domid goto err; } - p = getenv("XENPAGING_POLICY_MRU_SIZE"); - if ( p && *p ) - { - paging->policy_mru_size = atoi(p); - DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size); - } - - /* Set domain id */ - paging->mem_event.domain_id = domain_id; - /* Initialise shared page */ paging->mem_event.shared_page = init_page(); if ( paging->mem_event.shared_page == NULL ) @@ -333,17 +407,21 @@ static xenpaging_t *xenpaging_init(domid paging->mem_event.port = rc; - rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, - &domain_info); - if ( rc != 1 ) + /* Get max_pages from guest if not provided via cmdline */ + if ( !paging->max_pages ) { - PERROR("Error getting domain info"); - goto err; + rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, + &domain_info); + if ( rc != 1 ) + { + PERROR("Error getting domain info"); + goto err; + } + + /* Record number of max_pages */ + paging->max_pages = domain_info.max_pages; } - /* 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->max_pages); if ( !paging->bitmap ) @@ -353,8 +431,6 @@ static xenpaging_t *xenpaging_init(domid } DPRINTF("max_pages = %d\n", paging->max_pages); - paging->target_tot_pages = target_tot_pages; - /* Initialise policy */ rc = policy_init(paging); if ( rc != 0 ) @@ -719,25 +795,18 @@ int main(int argc, char *argv[]) mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH; int fd; - if ( argc != 3 ) - { - fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]); - return -1; - } - /* Initialise domain paging */ - paging = xenpaging_init(atoi(argv[1]), atoi(argv[2])); + paging = xenpaging_init(argc, argv); if ( paging == NULL ) { - fprintf(stderr, "Error initialising paging"); + fprintf(stderr, "Error initialising paging\n"); return 1; } xch = paging->xc_handle; - DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages); + DPRINTF("starting %s for domain_id %u with pagefile %s\n", argv[0], paging->mem_event.domain_id, filename); /* Open file */ - sprintf(filename, "page_cache_%u", paging->mem_event.domain_id); fd = open(filename, open_flags, open_mode); if ( fd < 0 ) { diff -r 59303aeb11d9 -r 5dd8e13e8222 tools/xenpaging/xenpaging.h --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -52,6 +52,7 @@ typedef struct xenpaging { int num_paged_out; int target_tot_pages; int policy_mru_size; + int debug; unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; } xenpaging_t; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # Date 1317656695 -7200 # Node ID c37a41cf0bf05f183a9b167f307591ec69e770e4 # Parent 5dd8e13e8222486bc09894dc3245c28a7e654d0a xenpaging: libxl support Add support to libxl for starting xenpaging. Its a huge patch and should be spit into totmem= and the actual xenpaging change. The patch adds three new config options: totmem=<int> , the number of pages xenpaging_file=<string>, pagefile to use xenpaging_extra=[ ''string'', ''string'' ], additional optional args for xenpaging xl gets a new ''mem-tot_pages'' command which modifies xenstore "memory/target-tot_pages" to notify the pager of a new target number and it instructs the xl monitor process to start the pager if the totmem= option was not in the config file. Signed-off-by: Olaf Hering <olaf@aepfle.de> diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.c --- a/tools/libxl/libxl.c +++ b/tools/libxl/libxl.c @@ -626,6 +626,21 @@ out: return rc; } +int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + int rc = -1; + if (asprintf(&waiter->path, "%s/memory/target-tot_pages", libxl__xs_get_dompath(&gc, domid)) < 0) + goto out; + if (asprintf(&waiter->token, "%d", LIBXL_EVENT_TYPE_XENPAGING) < 0) + goto out; + if (xs_watch(ctx->xsh, waiter->path, waiter->token) == true) + rc = 0; +out: + libxl__free_all(&gc); + return rc; +} + int libxl_get_event(libxl_ctx *ctx, libxl_event *event) { unsigned int num; @@ -2035,6 +2050,112 @@ out: return rc; } +int libxl_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid, + int32_t tot_pages_memkb, int relative) +{ + libxl__gc gc; + int rc, abort = 0; + uint32_t memorykb, videoram; + uint32_t current_target_memkb = 0; + uint32_t current_tot_pages_memkb, new_tot_pages_memkb; + char *memmax, *endptr, *videoram_s, *target, *tot_pages; + char *dompath; + xs_transaction_t t; + + if (domid == 0) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot set tot_pages for dom0.\n"); + return ERROR_INVAL; + } + + gc = LIBXL_INIT_GC(ctx); + dompath = libxl__xs_get_dompath(&gc, domid); + +retry_transaction: + rc = 1; + t = xs_transaction_start(ctx->xsh); + + target = libxl__xs_read(&gc, t, libxl__sprintf(&gc, + "%s/memory/target", dompath)); + if (!target) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "cannot get target memory info from %s/memory/target\n", + dompath); + abort = 1; + goto out; + } else { + current_target_memkb = strtoul(target, &endptr, 10); + if (*endptr != ''\0'') { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "invalid memory target %s from %s/memory/target\n", + target, dompath); + abort = 1; + goto out; + } + } + + videoram_s = libxl__xs_read(&gc, t, libxl__sprintf(&gc, + "%s/memory/videoram", dompath)); + videoram = videoram_s ? atoi(videoram_s) : 0; + + current_tot_pages_memkb = current_target_memkb + videoram; + tot_pages = libxl__xs_read(&gc, t, libxl__sprintf(&gc, + "%s/memory/target-tot_pages", dompath)); + if (tot_pages) { + current_tot_pages_memkb = strtoul(tot_pages, &endptr, 10); + if (*endptr != ''\0'') { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "invalid tot_pages %s from %s/memory/target-tot_pages\n", + tot_pages, dompath); + abort = 1; + goto out; + } + } + memmax = libxl__xs_read(&gc, t, libxl__sprintf(&gc, + "%s/memory/static-max", dompath)); + if (!memmax) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "cannot get memory info from %s/memory/static-max\n", + dompath); + abort = 1; + goto out; + } + memorykb = strtoul(memmax, &endptr, 10); + if (*endptr != ''\0'') { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, + "invalid max memory %s from %s/memory/static-max\n", + memmax, dompath); + abort = 1; + goto out; + } + + if (relative) { + if (tot_pages_memkb < 0 && abs(tot_pages_memkb) > current_tot_pages_memkb) + new_tot_pages_memkb = 0; + else + new_tot_pages_memkb = current_tot_pages_memkb + tot_pages_memkb; + } else + new_tot_pages_memkb = tot_pages_memkb; + if (new_tot_pages_memkb > memorykb) { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, + "memory_dynamic_max must be less than or equal to" + " memory_static_max\n"); + abort = 1; + goto out; + } + + libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/memory/target-tot_pages", + dompath), "%"PRIu32, new_tot_pages_memkb); + + rc = 0; +out: + if (!xs_transaction_end(ctx->xsh, t, abort) && !abort) + if (errno == EAGAIN) + goto retry_transaction; + + libxl__free_all(&gc); + return rc; +} + int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info, libxl_device_model_info *dm_info, uint32_t *need_memkb) { diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.h --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -261,6 +261,7 @@ int libxl_init_dm_info(libxl_ctx *ctx, typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv); int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid); int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd); +int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config, uint32_t domid, char *path); void libxl_domain_config_destroy(libxl_domain_config *d_config); int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info, uint32_t domid, int fd); @@ -312,6 +313,8 @@ int libxl_get_wait_fd(libxl_ctx *ctx, in int libxl_wait_for_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter); /* waiter is a preallocated array of num_disks libxl_waiter elements */ int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disks, int num_disks, libxl_waiter *waiter); +/* waiter is allocated by the caller */ +int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter); int libxl_get_event(libxl_ctx *ctx, libxl_event *event); int libxl_stop_waiting(libxl_ctx *ctx, libxl_waiter *waiter); int libxl_free_event(libxl_event *event); @@ -352,6 +355,7 @@ int libxl_domain_core_dump(libxl_ctx *ct int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb); int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t target_memkb, int relative, int enforce); int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target); +int libxl_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid, int32_t tot_pages_memkb, int relative); /* how much free memory in the system a domain needs to be built */ int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info, libxl_device_model_info *dm_info, uint32_t *need_memkb); diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_create.c --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -429,6 +429,121 @@ retry_transaction: return rc; } +static int create_xenpaging(libxl__gc *gc, char *dom_name, uint32_t domid, + libxl_domain_build_info *b_info) +{ + libxl__spawner_starting *buf_starting; + libxl_string_list xpe = b_info->u.hvm.xenpaging_extra; + int i, rc; + char *logfile; + int logfile_w, null; + char *path, *dom_path, *value; + char **args; + char *xp; + flexarray_t *xp_args; + libxl_ctx *ctx = libxl__gc_owner(gc); + + /* Nothing to do */ + if (b_info->target_memkb == b_info->tot_memkb) + return 0; + + /* Check if paging is already enabled */ + dom_path = libxl__xs_get_dompath(gc, domid); + if (!dom_path ) { + rc = ERROR_NOMEM; + goto out; + } + path = libxl__sprintf(gc, "%s/xenpaging/state", dom_path); + if (!path ) { + rc = ERROR_NOMEM; + goto out; + } + value = xs_read(ctx->xsh, XBT_NULL, path, NULL); + rc = value && strcmp(value, "running") == 0; + free(value); + /* Already running, nothing to do */ + if (rc) + return 0; + + /* Check if xenpaging is present */ + xp = libxl__abs_path(gc, "xenpaging", libxl_libexec_path()); + if (access(xp, X_OK) < 0) { + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not executable", xp); + rc = ERROR_FAIL; + goto out; + } + + /* Initialise settings for child */ + buf_starting = calloc(sizeof(*buf_starting), 1); + if (!buf_starting) { + rc = ERROR_NOMEM; + goto out; + } + buf_starting->domid = domid; + buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1); + buf_starting->dom_path = dom_path; + buf_starting->pid_path = "xenpaging/xenpaging-pid"; + if (!buf_starting->for_spawn) { + rc = ERROR_NOMEM; + goto out; + } + + /* Assemble arguments for xenpaging */ + xp_args = flexarray_make(5, 1); + if (!xp_args) { + rc = ERROR_NOMEM; + goto out; + } + /* Set executable path */ + flexarray_append(xp_args, xp); + + /* Append pagefile option */ + flexarray_append(xp_args, "-f"); + if (b_info->u.hvm.xenpaging_file) + flexarray_append(xp_args, b_info->u.hvm.xenpaging_file); + else + flexarray_append(xp_args, libxl__sprintf(gc, "%s/%s.%u.paging", + libxl_xenpaging_dir_path(), dom_name, domid)); + + /* Set maximum amount of memory xenpaging should handle */ + flexarray_append(xp_args, "-m"); + flexarray_append(xp_args, libxl__sprintf(gc, "%d", b_info->max_memkb)); + + /* Append extra args for pager */ + for (i = 0; xpe && xpe[i]; i++) + flexarray_append(xp_args, xpe[i]); + /* Append domid for pager */ + flexarray_append(xp_args, libxl__sprintf(gc, "%u", domid)); + flexarray_append(xp_args, NULL); + args = (char **) flexarray_contents(xp_args); + + /* Initialise logfile */ + libxl_create_logfile(ctx, libxl__sprintf(gc, "xenpaging-%s", dom_name), + &logfile); + logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644); + free(logfile); + null = open("/dev/null", O_RDONLY); + + /* Spawn the child */ + rc = libxl__spawn_spawn(gc, buf_starting->for_spawn, "xenpaging", + libxl_spawner_record_pid, buf_starting); + if (rc < 0) + goto out_close; + if (!rc) { /* inner child */ + setsid(); + /* Finally run xenpaging */ + libxl__exec(null, logfile_w, logfile_w, xp, args); + } + rc = libxl__spawn_confirm_offspring_startup(gc, 5, "xenpaging", path, + "running", buf_starting); +out_close: + close(null); + close(logfile_w); + free(args); +out: + return rc; +} + static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid_out, int restore_fd) @@ -641,3 +756,32 @@ int libxl_domain_create_restore(libxl_ct libxl__free_all(&gc); return rc; } + +int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config, + uint32_t domid, char *path) +{ + libxl__gc gc = LIBXL_INIT_GC(ctx); + char *value, *endptr; + uint32_t new_tot_pages; + int rc; + + if (d_config->c_info.type != LIBXL_DOMAIN_TYPE_HVM) + return 0; + + value = xs_read(ctx->xsh, XBT_NULL, path, NULL); + if (!value) + return 0; + new_tot_pages = strtoul(value, &endptr, 10); + free(value); + if (*endptr != ''\0'') { + LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid value in %s", path); + return 0; + } + d_config->b_info.tot_memkb = new_tot_pages; + + rc = create_xenpaging(&gc, d_config->dm_info.dom_name, domid, &d_config->b_info); + if (rc < 0) + LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to start xenpaging: %d", rc); + libxl__free_all(&gc); + return rc; +} diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_dom.c --- a/tools/libxl/libxl_dom.c +++ b/tools/libxl/libxl_dom.c @@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin if (info->cpuid != NULL) libxl_cpuid_set(ctx, domid, info->cpuid); - ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *)); + ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *)); ents[0] = "memory/static-max"; ents[1] = libxl__sprintf(gc, "%d", info->max_memkb); ents[2] = "memory/target"; @@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port); ents[10] = "store/ring-ref"; ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn); + ents[12] = "memory/target-tot_pages"; + ents[13] = libxl__sprintf(gc, "%d", info->tot_memkb); for (i = 0; i < info->max_vcpus; i++) { - ents[12+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); - ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) + ents[14+(i*2)] = libxl__sprintf(gc, "cpu/%d/availability", i); + ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i))) ? "offline" : "online"; } diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_types.idl --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -78,6 +78,7 @@ libxl_action_on_shutdown = Enumeration(" libxl_event_type = Enumeration("event_type", [ (1, "DOMAIN_DEATH"), (2, "DISK_EJECT"), + (3, "XENPAGING"), ]) libxl_button = Enumeration("button", [ @@ -157,6 +158,7 @@ libxl_domain_build_info = Struct("domain ("tsc_mode", integer), ("max_memkb", uint32), ("target_memkb", uint32), + ("tot_memkb", uint32), ("video_memkb", uint32), ("shadow_memkb", uint32), ("disable_migrate", bool), @@ -174,6 +176,8 @@ libxl_domain_build_info = Struct("domain ("vpt_align", bool), ("timer_mode", integer), ("nested_hvm", bool), + ("xenpaging_file", string), + ("xenpaging_extra", libxl_string_list), ])), ("pv", Struct(None, [("kernel", libxl_file_reference), ("slack_memkb", uint32), diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl.h --- a/tools/libxl/xl.h +++ b/tools/libxl/xl.h @@ -54,6 +54,7 @@ int main_vcpupin(int argc, char **argv); int main_vcpuset(int argc, char **argv); int main_memmax(int argc, char **argv); int main_memset(int argc, char **argv); +int main_mem_tot_pages(int argc, char **argv); int main_sched_credit(int argc, char **argv); int main_domid(int argc, char **argv); int main_domname(int argc, char **argv); diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdimpl.c --- a/tools/libxl/xl_cmdimpl.c +++ b/tools/libxl/xl_cmdimpl.c @@ -346,6 +346,7 @@ static void printf_info(int domid, printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware); printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb); printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb); + printf("\t\t\t(tot_memkb %d)\n", b_info->tot_memkb); printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae); printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic); printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi); @@ -380,6 +381,7 @@ static void printf_info(int domid, printf("\t\t\t(spicedisable_ticketing %d)\n", dm_info->spicedisable_ticketing); printf("\t\t\t(spiceagent_mouse %d)\n", dm_info->spiceagent_mouse); + printf("\t\t\t(xenpaging_file %s)\n", b_info->u.hvm.xenpaging_file); printf("\t\t)\n"); break; case LIBXL_DOMAIN_TYPE_PV: @@ -515,6 +517,28 @@ static void parse_disk_config(XLU_Config parse_disk_config_multistring(config, 1, &spec, disk); } +static void parse_xenpaging_extra(const XLU_Config *config, libxl_string_list *xpe) +{ + XLU_ConfigList *args; + libxl_string_list l; + const char *val; + int nr_args = 0, i; + + if (xlu_cfg_get_list(config, "xenpaging_extra", &args, &nr_args, 1)) + return; + + l = xmalloc(sizeof(char*)*(nr_args + 1)); + if (!l) + return; + + l[nr_args] = NULL; + for (i = 0; i < nr_args; i++) { + val = xlu_cfg_get_listitem(args, i); + l[i] = val ? strdup(val) : NULL; + } + *xpe = l; +} + static void parse_config_data(const char *configfile_filename_report, const char *configfile_data, int configfile_len, @@ -615,11 +639,15 @@ static void parse_config_data(const char if (!xlu_cfg_get_long (config, "memory", &l)) { b_info->max_memkb = l * 1024; b_info->target_memkb = b_info->max_memkb; + b_info->tot_memkb = b_info->max_memkb; } if (!xlu_cfg_get_long (config, "maxmem", &l)) b_info->max_memkb = l * 1024; + if (!xlu_cfg_get_long (config, "totmem", &l)) + b_info->tot_memkb = l * 1024; + if (xlu_cfg_get_string (config, "on_poweroff", &buf)) buf = "destroy"; if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) { @@ -695,6 +723,10 @@ static void parse_config_data(const char b_info->u.hvm.timer_mode = l; if (!xlu_cfg_get_long (config, "nestedhvm", &l)) b_info->u.hvm.nested_hvm = l; + + xlu_cfg_replace_string (config, "xenpaging_file", &b_info->u.hvm.xenpaging_file); + parse_xenpaging_extra(config, &b_info->u.hvm.xenpaging_extra); + break; case LIBXL_DOMAIN_TYPE_PV: { @@ -1356,7 +1388,7 @@ static int create_domain(struct domain_c int fd, i; int need_daemon = daemonize; int ret, rc; - libxl_waiter *w1 = NULL, *w2 = NULL; + libxl_waiter *w1 = NULL, *w2 = NULL, *w3; void *config_data = 0; int config_len = 0; int restore_fd = -1; @@ -1606,8 +1638,10 @@ start: d_config.c_info.name, domid, (long)getpid()); w1 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter) * d_config.num_disks); w2 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter)); + w3 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter)); libxl_wait_for_disk_ejects(ctx, domid, d_config.disks, d_config.num_disks, w1); libxl_wait_for_domain_death(ctx, domid, w2); + libxl_wait_for_target_tot_pages(ctx, domid, w3); libxl_get_wait_fd(ctx, &fd); while (1) { int ret; @@ -1649,8 +1683,10 @@ start: for (i = 0; i < d_config.num_disks; i++) libxl_free_waiter(&w1[i]); libxl_free_waiter(w2); + libxl_free_waiter(w3); free(w1); free(w2); + free(w3); /* * Do not attempt to reconnect if we come round again due to a @@ -1688,6 +1724,9 @@ start: libxl_device_disk_destroy(&disk); } break; + case LIBXL_EVENT_TYPE_XENPAGING: + libxl__create_xenpaging(ctx, &d_config, domid, event.path); + break; } libxl_free_event(&event); } @@ -1872,6 +1911,36 @@ int main_memset(int argc, char **argv) return 0; } +static void set_memory_tot_pages(const char *p, const char *mem) +{ + long long int memorykb; + + find_domain(p); + + memorykb = parse_mem_size_kb(mem); + if (memorykb == -1) { + fprintf(stderr, "invalid memory size: %s\n", mem); + exit(3); + } + + libxl_set_memory_tot_pages(ctx, domid, memorykb, 0); +} + +int main_mem_tot_pages(int argc, char **argv) +{ + int opt = 0; + const char *p = NULL, *mem; + + if ((opt = def_getopt(argc, argv, "", "mem-totpages", 2)) != -1) + return opt; + + p = argv[optind]; + mem = argv[optind + 1]; + + set_memory_tot_pages(p, mem); + return 0; +} + static void cd_insert(const char *dom, const char *virtdev, char *phys) { libxl_device_disk disk; /* we don''t free disk''s contents */ diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdtable.c --- a/tools/libxl/xl_cmdtable.c +++ b/tools/libxl/xl_cmdtable.c @@ -158,6 +158,11 @@ struct cmd_spec cmd_table[] = { "Set the current memory usage for a domain", "<Domain> <MemMB[''b''[bytes]|''k''[KB]|''m''[MB]|''g''[GB]|''t''[TB]]>", }, + { "mem-totpages", + &main_mem_tot_pages, 0, + "Set the how much memory is assigned to a domain", + "<Domain> <MemMB[''b''[bytes]|''k''[KB]|''m''[MB]|''g''[GB]|''t''[TB]]>", + }, { "button-press", &main_button_press, 0, "Indicate an ACPI button press to the domain", diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/xenpaging/xenpaging.c --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -40,6 +40,8 @@ /* Defines number of mfns a guest should use at a time, in KiB */ #define WATCH_TARGETPAGES "memory/target-tot_pages" +/* Defines startup confirmation */ +#define WATCH_STARTUP "xenpaging/state" static char *watch_target_tot_pages; static char *dom_path; static char watch_token[16]; @@ -777,6 +779,22 @@ static int evict_pages(xenpaging_t *pagi return num; } +static int xenpaging_confirm_startup(xenpaging_t *paging) +{ + xc_interface *xch = paging->xc_handle; + char *path; + int len; + + len = asprintf(&path, "%s/%s", dom_path, WATCH_STARTUP); + if ( len < 0 ) + return -1; + DPRINTF("confirm startup ''%s''\n", path); + len = xs_write(paging->xs_handle, XBT_NULL, path, "running", len); + DPRINTF("confirm startup returned %d\n", len); + free(path); + return 0; +} + int main(int argc, char *argv[]) { struct sigaction act; @@ -835,6 +853,9 @@ int main(int argc, char *argv[]) /* listen for page-in events to stop pager */ create_page_in_thread(paging); + /* Confirm startup to caller */ + xenpaging_confirm_startup(paging); + /* Swap pages in and out */ while ( 1 ) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Oct-04 08:23 UTC
Re: [Xen-devel] [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:> # HG changeset patch > # User Olaf Hering <olaf@aepfle.de> > # Date 1317653612 -7200 > # Node ID 219ab93f22c0492595686a1cc34911e9d6775b07 > # Parent df7be429654c62fb4c61f83549374d77b80ebea3 > libxl: add pid path to libxl__spawner_starting > > libxl_spawner_record_pid() should be able to write the pid to arbitrary paths. > > Signed-off-by: Olaf Hering <olaf@aepfle.de> > > diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_dm.c > --- a/tools/libxl/libxl_dm.c > +++ b/tools/libxl/libxl_dm.c > @@ -848,6 +848,7 @@ int libxl__create_device_model(libxl__gc > > p->domid = info->domid; > p->dom_path = libxl__xs_get_dompath(gc, info->domid); > + p->pid_path = "image/device-model-pid"; > if (!p->dom_path) { > rc = ERROR_FAIL; > goto out_close; > diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_exec.c > --- a/tools/libxl/libxl_exec.c > +++ b/tools/libxl/libxl_exec.c > @@ -151,7 +151,7 @@ void libxl_spawner_record_pid(void *for_ > char *path = NULL, *pid = NULL; > int len; > > - if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0) > + if (asprintf(&path, "%s/%s", starting->dom_path, starting->pid_path) < 0) > goto out; > > len = asprintf(&pid, "%d", innerchild); > diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_internal.h > --- a/tools/libxl/libxl_internal.h > +++ b/tools/libxl/libxl_internal.h > @@ -250,6 +250,7 @@ typedef struct { > > typedef struct { > char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ > + char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */Either this new comment is true and you need a strdup() up above where you set it and a free() somewhere else (or use libxl__strdup()) or it is false and it should be removed and pid_path should be const char *. I think the second option is sufficient for the current and new user you are about to add? Ian.> int domid; > libxl__spawn_starting *for_spawn; > } libxl__spawner_starting; > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-04 09:09 UTC
Re: [Xen-devel] [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
On Tue, Oct 04, Ian Campbell wrote:> On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:> > +++ b/tools/libxl/libxl_internal.h > > @@ -250,6 +250,7 @@ typedef struct { > > > > typedef struct { > > char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ > > + char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */ > > Either this new comment is true and you need a strdup() up above where > you set it and a free() somewhere else (or use libxl__strdup()) or it is > false and it should be removed and pid_path should be const char *. > > I think the second option is sufficient for the current and new user you > are about to add?I duplicated the dom_path line without paying attention to the comment. A const char *pid_path; is sufficient. Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Campbell
2011-Oct-04 09:51 UTC
Re: [Xen-devel] [PATCH 00 of 24] xenpaging fixes for xen-unstable
On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:> The following series adds support for xenpaging to libxl and the xl command. > A few code cleanup changes are also part of this series. > > The logic of xenpaging was reversed. > It does now monitor the guests tot_pages value and work toward that number by > either paging out more pages, or write pages back into the guest. > > Three new configuration file options specific for xenpaging were added: > totmem=<int> > xenpaging_file=<string> > xenpaging_extra=[ ''string'', ''string'' ] > > A new xl command ''mem-tot_pages'' instructs xenpaging to adjust its pagefile > size, and it instructs the xl monitor process to actually start xenpaging if > totmem= was not specified in the config file.In general xl commands do not contain "_" but rather use "-". We also sometimes use a "-set" suffix too. totmem is unfortunately not all that descriptive to an end user of what it does (which I think is a general problem we have with the memory related options). Currently the xl config file options are: memory = actual start of day RAM maxmem = max ram guest could balloon to (?) How does POD fit in? Is it just maxmem-memory for HVM domains? (not really relevant for this discussion, more for completeness). The associated command line options are: mem-set (runtime equivalent of memory?) mem-max (runtime equivalent of maxmem?) Hmm, I was hoping that enumerating the existing options would make the name and semantics of the paging option magically pop into my head, I was wrong :-( BTW tools/libxl/libxl_memory.txt should be patched by this series too, once we figure out what to call things. The phrase "actual memory" is used in that document -- perhaps that is suitable terminology for totmem? Ian.> > Please review and apply. > > Olaf > > > Config.mk | 2 > config/StdGNU.mk | 2 > tools/libxc/xc_bitops.h | 6 > tools/libxl/libxl.c | 121 +++++++++ > tools/libxl/libxl.h | 5 > tools/libxl/libxl_create.c | 146 +++++++++++ > tools/libxl/libxl_device.c | 84 ------ > tools/libxl/libxl_dm.c | 65 +---- > tools/libxl/libxl_dom.c | 8 > tools/libxl/libxl_exec.c | 142 +++++++++++ > tools/libxl/libxl_internal.h | 33 ++ > tools/libxl/libxl_paths.c | 5 > tools/libxl/libxl_types.idl | 4 > tools/libxl/xl.h | 1 > tools/libxl/xl_cmdimpl.c | 71 +++++ > tools/libxl/xl_cmdtable.c | 5 > tools/xenpaging/Makefile | 6 > tools/xenpaging/file_ops.c | 6 > tools/xenpaging/policy_default.c | 23 + > tools/xenpaging/xenpaging.c | 479 ++++++++++++++++++++++++++++----------- > tools/xenpaging/xenpaging.h | 8 > 21 files changed, 934 insertions(+), 288 deletions(-) > > > _______________________________________________ > Xen-devel mailing list > Xen-devel@lists.xensource.com > http://lists.xensource.com/xen-devel_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-04 15:05 UTC
Re: [Xen-devel] [PATCH 00 of 24] xenpaging fixes for xen-unstable
On Tue, Oct 04, Ian Campbell wrote:> totmem is unfortunately not all that descriptive to an end user of what > it does (which I think is a general problem we have with the memory > related options). > > Currently the xl config file options are: > memory = actual start of day RAM > maxmem = max ram guest could balloon to (?) > > How does POD fit in? Is it just maxmem-memory for HVM domains? (not > really relevant for this discussion, more for completeness). > > The associated command line options are: > mem-set (runtime equivalent of memory?) > mem-max (runtime equivalent of maxmem?) > > Hmm, I was hoping that enumerating the existing options would make the > name and semantics of the paging option magically pop into my head, I > was wrong :-( > > BTW tools/libxl/libxl_memory.txt should be patched by this series too, > once we figure out what to call things. > > The phrase "actual memory" is used in that document -- perhaps that is > suitable terminology for totmem?The naming of the various numbers is confusing, so far I could not come up with a better name than tot_pages. "actual target" is close to what xenpaging leaves for the guest, the amount of video ram has to be substracted. I think the code in libxl, xenstore and in my changes is not 100% consistent with the figure below. I have to wade through the individual members again and check if the math is correct in all places. Olaf /* === Domain memory breakdown: HVM guests ================================= + +----------+ + | | shadow | | | +----------+ | overhead | | extra | | | | external | | | +----------+ + | | | extra | | | | | internal | | | + +----------+ + | | footprint | | video | | | | | +----------+ + + + | | xen | | | | | guest OS | | | actual | maximum | | | guest | | real RAM | | | target | | | | | | | | build | | | | +----------+ + | | start + | | static | | paging | | | | | maximum | +----------+ | + + + | | | | | | | | | | balloon | | build | | | | maximum | | | | + +----------+ + extra internal = LIBXL_MAXMEM_CONSTANT extra external = LIBXL_HVM_EXTRA_MEMORY shadow = libxl_domain_build_info.shadow_memkb static maximum = libxl_domain_build_info.max_memkb video = libxl_domain_build_info.video_memkb build start = libxl_domain_build_info.target_memkb libxl_domain_setmaxmem -> xen maximum libxl_set_memory_target -> actual target build maximum = RAM as seen inside the virtual machine Increase/Decrease via memory hotplug of virtual hardware (?) xl mem-max (?) build start = RAM usable by the guest OS guest OS sees balloon driver as memory hog (?) Increase/Decrease via commands to the balloon driver xl mem-set real RAM = RAM allocated for the guest Increase/Decrease via commands to paging daemon xl mem-FOO guest = real RAM paging = virtual RAM / swap balloon = will become real or virtual RAM after mem-set command _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-04 15:08 UTC
Re: [Xen-devel] [PATCH 00 of 24] xenpaging fixes for xen-unstable
On Tue, Oct 04, Ian Campbell wrote:> How does POD fit in? Is it just maxmem-memory for HVM domains? (not > really relevant for this discussion, more for completeness).I dont have much experince with PoD, and started just last week some testing with a ballooned guest. In my limited testing I found no obvious bugs. But I have to check the code what PoD really means for paged pages. Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
George Dunlap
2011-Oct-04 16:19 UTC
Re: [Xen-devel] [PATCH 03 of 24] xenpaging: use PERROR to print errno
On Mon, Oct 3, 2011 at 4:54 PM, Olaf Hering <olaf@aepfle.de> wrote:> # HG changeset patch > # User Olaf Hering <olaf@aepfle.de> > # Date 1317653597 -7200 > # Node ID ee4c4c7699e0de2b6bddce1e816d35f36ffb0470 > # Parent 21b7c9a6545ac1ec9d91fce83d46aab0b5808b05 > xenpaging: use PERROR to print errno > > Also catch lseek() errors in file_op(). > > Signed-off-by: Olaf Hering <olaf@aepfle.de> > > diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/file_ops.c > --- a/tools/xenpaging/file_ops.c > +++ b/tools/xenpaging/file_ops.c > @@ -37,6 +37,11 @@ static int file_op(int fd, void *page, i > int ret; > > seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET); > + if (seek_ret == -1) > + { > + ret = -errno; > + goto err; > + }Wouldn''t it be more idiomatic to make both this check and the other check in the function: * check for seek_ret < 0 (rather than -1) * make file_op() return -1 * Let the caller read errno? (Rather than returning -errno)?> > total = 0; > while ( total < PAGE_SIZE ) > diff -r 21b7c9a6545a -r ee4c4c7699e0 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; > } > > @@ -240,13 +240,13 @@ static xenpaging_t *xenpaging_init(domid > { > switch ( errno ) { > case EBUSY: > - ERROR("xenpaging is (or was) active on this domain"); > + PERROR("xenpaging is (or was) active on this domain"); > break; > case ENODEV: > - ERROR("EPT not supported for this guest"); > + PERROR("EPT not supported for this guest"); > break; > default: > - ERROR("Error initialising shared page: %s", strerror(errno)); > + PERROR("Error initialising shared page: %s", strerror(errno)); > break; > } > goto err; > @@ -256,7 +256,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; > } > > @@ -266,7 +266,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; > } > > @@ -276,7 +276,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; > } > > @@ -284,7 +284,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; > } > > @@ -292,7 +292,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); > @@ -308,7 +308,7 @@ static xenpaging_t *xenpaging_init(domid > rc = policy_init(paging); > if ( rc != 0 ) > { > - ERROR("Error initialising policy"); > + PERROR("Error initialising policy"); > goto err; > } > > @@ -355,14 +355,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; > > @@ -370,7 +370,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; > > @@ -381,7 +381,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; > @@ -441,7 +441,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; > } > > @@ -449,8 +449,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; > } > > @@ -752,7 +752,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 >_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-04 17:19 UTC
Re: [Xen-devel] [PATCH 03 of 24] xenpaging: use PERROR to print errno
On Tue, Oct 04, George Dunlap wrote:> On Mon, Oct 3, 2011 at 4:54 PM, Olaf Hering <olaf@aepfle.de> wrote:> > seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET); > > + if (seek_ret == -1) > > + { > > + ret = -errno; > > + goto err; > > + } > > Wouldn''t it be more idiomatic to make both this check and the other > check in the function: > * check for seek_ret < 0 (rather than -1)The man page said its -1, now that I read it again it says (off_t)-1, so my change above should be updated to comply with the man page.> * make file_op() return -1 > * Let the caller read errno? (Rather than returning -errno)?Yes, I will change this in a new patch. Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Oct-25 15:31 UTC
Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):> libxl: add libxl__spawn_confirm_offspring_startup > > libxl__spawn_confirm_offspring_startup() is a generic version of > libxl__confirm_device_model_startup().Thanks but I think it would be better to refactor this to avoid the duplication of this code. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-25 17:21 UTC
Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
On Tue, Oct 25, Ian Jackson wrote:> Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"): > > libxl: add libxl__spawn_confirm_offspring_startup > > > > libxl__spawn_confirm_offspring_startup() is a generic version of > > libxl__confirm_device_model_startup(). > > Thanks but I think it would be better to refactor this to avoid the > duplication of this code.The new function is used in patch #18 of this series. Or do you have some other changes in mind? Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Oct-25 17:53 UTC
Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):> On Tue, Oct 25, Ian Jackson wrote: > > Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"): > > > libxl: add libxl__spawn_confirm_offspring_startup > > > > > > libxl__spawn_confirm_offspring_startup() is a generic version of > > > libxl__confirm_device_model_startup(). > > > > Thanks but I think it would be better to refactor this to avoid the > > duplication of this code. > > The new function is used in patch #18 of this series. > Or do you have some other changes in mind?I mean that you should arrange to replace libxl__confirm_device_model_startup with your new function libxl__spawn_confirm_offspring_startup. As it is you have made a copy of libxl__confirm_device_model_startup and lightly edited it. This is a cardinal sin in programming, known as "clone and hack". Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Olaf Hering
2011-Oct-26 16:30 UTC
Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
On Tue, Oct 25, Ian Jackson wrote:> Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"): > > On Tue, Oct 25, Ian Jackson wrote: > > > Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"): > > > > libxl: add libxl__spawn_confirm_offspring_startup > > > > > > > > libxl__spawn_confirm_offspring_startup() is a generic version of > > > > libxl__confirm_device_model_startup(). > > > > > > Thanks but I think it would be better to refactor this to avoid the > > > duplication of this code. > > > > The new function is used in patch #18 of this series. > > Or do you have some other changes in mind? > > I mean that you should arrange to replace > libxl__confirm_device_model_startup with your new function > libxl__spawn_confirm_offspring_startup. > > As it is you have made a copy of libxl__confirm_device_model_startup > and lightly edited it. This is a cardinal sin in programming, known > as "clone and hack".I moved the device model specific functions and made them generic. Perhaps I should have merged the add+use patches (15+16 / 17+18) into a single change. Once all patches are applied I see no code duplication. If you prefer I can send a series just for the spawn related changes in libxl. Olaf _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Oct-27 10:34 UTC
Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):> I moved the device model specific functions and made them generic. > Perhaps I should have merged the add+use patches (15+16 / 17+18) into a > single change. Once all patches are applied I see no code duplication.Oh, I see; I didn''t spot that, I''m afraid. I''ll look at it again. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel