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

[Xen-devel] [PATCH] xenpaging: use batch of pages during final page-in


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Olaf Hering <olaf@xxxxxxxxx>
  • Date: Wed, 07 Sep 2011 19:05:57 +0200
  • Delivery-date: Wed, 07 Sep 2011 10:09:14 -0700
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1315415105 -7200
# Node ID 52e2fd24423147b8ad1384b5e98ce9d78be7d169
# Parent  0268e73809532a4a3ca18a075efcee3c62caf458
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 0268e7380953 -r 52e2fd244231 tools/xenpaging/pagein.c
--- a/tools/xenpaging/pagein.c
+++ b/tools/xenpaging/pagein.c
@@ -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 @@ static void *page_in(void *arg)
 {
     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 @@ static void *page_in(void *arg)
     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 0268e7380953 -r 52e2fd244231 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -648,7 +648,7 @@ int main(int argc, char *argv[])
     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 @@ int main(int argc, char *argv[])
         /* 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 0268e7380953 -r 52e2fd244231 tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -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 @@ typedef struct xenpaging {
     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 @@ typedef struct xenpaging_victim {
 } 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-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

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