[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] xenpaging: use batch of pages during final page-in



# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1315905932 -3600
# Node ID d1d6abc1db2077d2d4f1c7a441399d07c0c05471
# Parent  ad958e87db79549165661d50b9b77526f22b0f03
xenpaging: use batch of pages during final page-in

Map up to RING_SIZE pages in exit path to fill the ring instead of
populating one page at a time.

Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
---


diff -r ad958e87db79 -r d1d6abc1db20 tools/xenpaging/pagein.c
--- a/tools/xenpaging/pagein.c  Tue Sep 13 10:22:03 2011 +0100
+++ b/tools/xenpaging/pagein.c  Tue Sep 13 10:25:32 2011 +0100
@@ -1,14 +1,16 @@
 /* Trigger a page-in in a separate thread-of-execution to avoid deadlock */
 #include <pthread.h>
-#include "xc_private.h"
+#include <xc_private.h>
+#include "xenpaging.h"
 
 struct page_in_args {
     domid_t dom;
+    unsigned long *pagein_queue;
     xc_interface *xch;
 };
 
 static struct page_in_args page_in_args;
-static unsigned long page_in_gfn;
+static unsigned long page_in_request;
 static unsigned int page_in_possible;
 
 static pthread_t page_in_thread;
@@ -19,19 +21,28 @@
 {
     struct page_in_args *pia = arg;
     void *page;
-    xen_pfn_t gfn;
+    int i, num;
+    xen_pfn_t gfns[XENPAGING_PAGEIN_QUEUE_SIZE];
 
     while (1)
     {
         pthread_mutex_lock(&page_in_mutex);
-        while (!page_in_gfn)
+        while (!page_in_request)
             pthread_cond_wait(&page_in_cond, &page_in_mutex);
-        gfn = page_in_gfn;
-        page_in_gfn = 0;
+        num = 0;
+        for (i = 0; i < XENPAGING_PAGEIN_QUEUE_SIZE; i++)
+        {
+            if (!pia->pagein_queue[i])
+               continue;
+            gfns[num] = pia->pagein_queue[i];
+            pia->pagein_queue[i] = 0;
+            num++;
+        }
+        page_in_request = 0;
         pthread_mutex_unlock(&page_in_mutex);
 
         /* Ignore errors */
-        page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, &gfn, 1);
+        page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, gfns, num);
         if (page)
             munmap(page, PAGE_SIZE);
     }
@@ -39,21 +50,22 @@
     pthread_exit(NULL);
 }
 
-void page_in_trigger(unsigned long gfn)
+void page_in_trigger(void)
 {
     if (!page_in_possible)
         return;
 
     pthread_mutex_lock(&page_in_mutex);
-    page_in_gfn = gfn;
+    page_in_request = 1;
     pthread_mutex_unlock(&page_in_mutex);
     pthread_cond_signal(&page_in_cond);
 }
 
-void create_page_in_thread(domid_t domain_id, xc_interface *xch)
+void create_page_in_thread(xenpaging_t *paging)
 {
-    page_in_args.dom = domain_id;
-    page_in_args.xch = xch;
+    page_in_args.dom = paging->mem_event.domain_id;
+    page_in_args.pagein_queue = paging->pagein_queue;
+    page_in_args.xch = paging->xc_handle;
     if (pthread_create(&page_in_thread, NULL, page_in, &page_in_args) == 0)
         page_in_possible = 1;
 }
diff -r ad958e87db79 -r d1d6abc1db20 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c       Tue Sep 13 10:22:03 2011 +0100
+++ b/tools/xenpaging/xenpaging.c       Tue Sep 13 10:25:32 2011 +0100
@@ -648,7 +648,7 @@
     sigaction(SIGALRM, &act, NULL);
 
     /* listen for page-in events to stop pager */
-    create_page_in_thread(paging->mem_event.domain_id, xch);
+    create_page_in_thread(paging);
 
     /* Evict pages */
     for ( i = 0; i < paging->num_pages; i++ )
@@ -764,16 +764,24 @@
         /* Write all pages back into the guest */
         if ( interrupted == SIGTERM || interrupted == SIGINT )
         {
+            int num = 0;
             for ( i = 0; i < paging->domain_info->max_pages; i++ )
             {
                 if ( test_bit(i, paging->bitmap) )
                 {
-                    page_in_trigger(i);
-                    break;
+                    paging->pagein_queue[num] = i;
+                    num++;
+                    if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
+                        break;
                 }
             }
-            /* If no more pages to process, exit loop */
-            if ( i == paging->domain_info->max_pages )
+            /*
+             * 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->domain_info->max_pages )
                 break;
         }
         else
diff -r ad958e87db79 -r d1d6abc1db20 tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h       Tue Sep 13 10:22:03 2011 +0100
+++ b/tools/xenpaging/xenpaging.h       Tue Sep 13 10:25:32 2011 +0100
@@ -29,6 +29,8 @@
 #include <xen/event_channel.h>
 #include <xen/mem_event.h>
 
+#define XENPAGING_PAGEIN_QUEUE_SIZE 64
+
 typedef struct mem_event {
     domid_t domain_id;
     xc_evtchn *xce_handle;
@@ -49,6 +51,7 @@
     mem_event_t mem_event;
     int num_pages;
     int policy_mru_size;
+    unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
 } xenpaging_t;
 
 
@@ -58,8 +61,8 @@
 } xenpaging_victim_t;
 
 
-extern void create_page_in_thread(domid_t domain_id, xc_interface *xch);
-extern void page_in_trigger(unsigned long gfn);
+extern void create_page_in_thread(xenpaging_t *paging);
+extern void page_in_trigger(void);
 
 #endif // __XEN_PAGING_H__
 

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.