Files
xen/tools/xenpaging/pagein.c
T
Olaf Hering d2cb52cc6c xenpaging: munmap all pages after page-in
Do munmap() on all mapped pages, not just the first one.  Without this
change the gfns backing the remaining pages can not be paged out again
because the page count does not go down to 1. This change was missing
from changeset 23827:d1d6abc1db20.

Signed-off-by: Olaf Hering <olaf@aepfle.de>
Committed-by: Ian Jackson <ian.jackson@eu.citrix.com>
2011-11-14 17:49:14 +00:00

81 lines
2.0 KiB
C

/* Trigger a page-in in a separate thread-of-execution to avoid deadlock */
#include <pthread.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_request;
static unsigned int page_in_possible;
static pthread_t page_in_thread;
static pthread_cond_t page_in_cond = PTHREAD_COND_INITIALIZER;
static pthread_mutex_t page_in_mutex = PTHREAD_MUTEX_INITIALIZER;
static void *page_in(void *arg)
{
struct page_in_args *pia = arg;
void *page;
int i, num;
xen_pfn_t gfns[XENPAGING_PAGEIN_QUEUE_SIZE];
while (1)
{
pthread_mutex_lock(&page_in_mutex);
while (!page_in_request)
pthread_cond_wait(&page_in_cond, &page_in_mutex);
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, gfns, num);
if (page)
munmap(page, PAGE_SIZE * num);
}
page_in_possible = 0;
pthread_exit(NULL);
}
void page_in_trigger(void)
{
if (!page_in_possible)
return;
pthread_mutex_lock(&page_in_mutex);
page_in_request = 1;
pthread_mutex_unlock(&page_in_mutex);
pthread_cond_signal(&page_in_cond);
}
void create_page_in_thread(xenpaging_t *paging)
{
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;
}
/*
* Local variables:
* mode: C
* c-set-style: "BSD"
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/