Olaf Hering
2011-Sep-07 17:05 UTC
[Xen-devel] [PATCH] xenpaging: use batch of pages during final page-in
# HG changeset patch # User Olaf Hering <olaf@aepfle.de> # 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@aepfle.de> 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@lists.xensource.com http://lists.xensource.com/xen-devel