From 2484d09e2a4574e181df58de6a44bafc6c663a40 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Mon, 20 Feb 2012 21:18:44 +0100 Subject: xenpaging: implement stack of free slots in pagefile Scanning the slot_to_gfn[] array for a free slot is expensive because evict_pages() always needs to scan the whole array. Remember the last slots freed during page-in requests and reuse them in evict_pages(). Signed-off-by: Olaf Hering Committed-by: Ian Jackson --- tools/xenpaging/xenpaging.c | 23 +++++++++++++++++++++++ tools/xenpaging/xenpaging.h | 2 ++ 2 files changed, 25 insertions(+) (limited to 'tools/xenpaging') diff --git a/tools/xenpaging/xenpaging.c b/tools/xenpaging/xenpaging.c index 5f943b5ad7..b7b754541a 100644 --- a/tools/xenpaging/xenpaging.c +++ b/tools/xenpaging/xenpaging.c @@ -432,6 +432,11 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[]) if ( !paging->slot_to_gfn || !paging->gfn_to_slot ) goto err; + /* Allocate stack for known free slots in pagefile */ + paging->free_slot_stack = calloc(paging->max_pages, sizeof(*paging->free_slot_stack)); + if ( !paging->free_slot_stack ) + goto err; + /* Initialise policy */ rc = policy_init(paging); if ( rc != 0 ) @@ -483,6 +488,7 @@ static struct xenpaging *xenpaging_init(int argc, char *argv[]) free(dom_path); free(watch_target_tot_pages); + free(paging->free_slot_stack); free(paging->slot_to_gfn); free(paging->gfn_to_slot); free(paging->bitmap); @@ -807,6 +813,20 @@ static int evict_pages(struct xenpaging *paging, int num_pages) xc_interface *xch = paging->xc_handle; int rc, slot, num = 0; + /* Reuse known free slots */ + while ( paging->stack_count > 0 && num < num_pages ) + { + slot = paging->free_slot_stack[--paging->stack_count]; + rc = evict_victim(paging, slot); + if ( rc ) + { + num = rc < 0 ? -1 : num; + return num; + } + num++; + } + + /* Scan all slots slots for remainders */ for ( slot = 0; slot < paging->max_pages && num < num_pages; slot++ ) { /* Slot is allocated */ @@ -930,6 +950,9 @@ int main(int argc, char *argv[]) /* Clear this pagefile slot */ paging->slot_to_gfn[slot] = 0; + + /* Record this free slot */ + paging->free_slot_stack[paging->stack_count++] = slot; } else { diff --git a/tools/xenpaging/xenpaging.h b/tools/xenpaging/xenpaging.h index 746556b1a0..e348db63c5 100644 --- a/tools/xenpaging/xenpaging.h +++ b/tools/xenpaging/xenpaging.h @@ -60,6 +60,8 @@ struct xenpaging { int policy_mru_size; int use_poll_timeout; int debug; + int stack_count; + int *free_slot_stack; unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE]; }; -- cgit v1.2.3