File xenpaging.speedup-page-in.gfn_to_slot.patch of Package xen

xenpaging: use flat index for pagefile and page-in requests

This change is based on an idea by <hongkaixing@huawei.com> and
<bicky.shi@huawei.com>.

Scanning the victims[] array is time consuming with a large number of
target pages. Replace the loop to find the slot in the pagefile which
holds the requested gfn with an index.

---
 tools/xenpaging/xenpaging.c |   13 ++++++++++---
 tools/xenpaging/xenpaging.h |    2 ++
 2 files changed, 12 insertions(+), 3 deletions(-)

Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.c
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.c
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.c
@@ -626,6 +626,8 @@ static int xenpaging_evict_page(xenpagin
     /* Record number of evicted pages */
     paging->num_paged_out++;
 
+    paging->gfn_to_slot[victim->gfn] = i;
+
     ret = 0;
 
  out:
@@ -805,7 +807,7 @@ int main(int argc, char *argv[])
 {
     struct sigaction act;
     xenpaging_t *paging;
-    xenpaging_victim_t *victims;
+    xenpaging_victim_t *victims = NULL;
     mem_event_request_t req;
     mem_event_response_t rsp;
     int num, prev_num = 0;
@@ -838,6 +840,10 @@ int main(int argc, char *argv[])
         return 2;
     }
 
+    paging->gfn_to_slot = calloc(paging->max_pages, sizeof(int));
+    if ( ! paging->gfn_to_slot )
+        goto out;
+
     /* Allocate upper limit of pages to allow growing and shrinking */
     victims = calloc(paging->max_pages, sizeof(xenpaging_victim_t));
     if ( !victims )
@@ -882,10 +888,11 @@ 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->max_pages; i++ )
+                i = paging->gfn_to_slot[req.gfn];
+                if ( victims[i].gfn != req.gfn || i > paging->max_pages )
                 {
-                    if ( victims[i].gfn == req.gfn )
-                        break;
+                    ERROR("Expected gfn %lx in slot %d, got gfn %lx instead\n", req.gfn, i, victims[i].gfn);
+                    goto out;
                 }
     
                 if ( i >= paging->max_pages )
@@ -1019,7 +1026,8 @@ int main(int argc, char *argv[])
  out:
     close(fd);
     unlink_pagefile();
-    free(victims);
+    if ( victims != NULL )
+        free(victims);
 
     /* Tear down domain paging */
     rc1 = xenpaging_teardown(paging);
Index: xen-4.1.2-testing/tools/xenpaging/xenpaging.h
===================================================================
--- xen-4.1.2-testing.orig/tools/xenpaging/xenpaging.h
+++ xen-4.1.2-testing/tools/xenpaging/xenpaging.h
@@ -46,6 +46,8 @@ typedef struct xenpaging {
 
     unsigned long *bitmap;
 
+    int *gfn_to_slot;
+
     mem_event_t mem_event;
     /* number of pages for which data structures were allocated */
     int max_pages;
openSUSE Build Service is sponsored by