From f994788c5e4cd25e5b67b93a6a9c68491082277f Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Sun, 20 Nov 2011 17:02:45 +0100 Subject: xenpaging: use guests tot_pages as working target This change reverses the task of xenpaging. Before this change a fixed number of pages was paged out. With this change the guest will not have access to more than the given number of pages at the same time. Signed-off-by: Olaf Hering Committed-by: Ian Jackson --- tools/xenpaging/policy_default.c | 1 - tools/xenpaging/xenpaging.c | 78 ++++++++++++++++++++++++++++++---------- tools/xenpaging/xenpaging.h | 2 +- 3 files changed, 61 insertions(+), 20 deletions(-) (limited to 'tools/xenpaging') diff --git a/tools/xenpaging/policy_default.c b/tools/xenpaging/policy_default.c index 57da85d076..0285d0dd8a 100644 --- 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 --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c index 07c9109829..656a8b6749 100644 --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -136,6 +136,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; @@ -161,7 +176,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; @@ -296,12 +311,7 @@ static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages) } 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); @@ -648,7 +658,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; @@ -659,7 +671,7 @@ int main(int argc, char *argv[]) if ( argc != 3 ) { - fprintf(stderr, "Usage: %s \n", argv[0]); + fprintf(stderr, "Usage: %s \n", argv[0]); return -1; } @@ -672,7 +684,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); @@ -704,9 +716,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 ) { @@ -771,12 +780,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 { @@ -823,6 +828,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 --git a/tools/xenpaging/xenpaging.h b/tools/xenpaging/xenpaging.h index 2ea8064234..2bd9e7fdb5 100644 --- 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; -- cgit v1.2.3