aboutsummaryrefslogtreecommitdiffstats
path: root/tools/xenpaging
diff options
context:
space:
mode:
authorOlaf Hering <olaf@aepfle.de>2012-02-20 21:18:44 +0100
committerOlaf Hering <olaf@aepfle.de>2012-02-20 21:18:44 +0100
commit2484d09e2a4574e181df58de6a44bafc6c663a40 (patch)
tree293391884f7d3718493abb9066f042cea2a708a3 /tools/xenpaging
parent8e37ea4bb89f91593d7a07ebc049da540f6279ac (diff)
downloadxen-2484d09e2a4574e181df58de6a44bafc6c663a40.tar.gz
xen-2484d09e2a4574e181df58de6a44bafc6c663a40.tar.bz2
xen-2484d09e2a4574e181df58de6a44bafc6c663a40.zip
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 <olaf@aepfle.de> Committed-by: Ian Jackson <ian.jackson.citrix.com>
Diffstat (limited to 'tools/xenpaging')
-rw-r--r--tools/xenpaging/xenpaging.c23
-rw-r--r--tools/xenpaging/xenpaging.h2
2 files changed, 25 insertions, 0 deletions
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];
};