1 /* Trigger a page-in in a separate thread-of-execution to avoid deadlock */
2 #include <pthread.h>
3 #include "xenpaging.h"
4
5 struct page_in_args {
6 domid_t dom;
7 unsigned long *pagein_queue;
8 xc_interface *xch;
9 };
10
11 static struct page_in_args page_in_args;
12 static unsigned long page_in_request;
13 static unsigned int page_in_possible;
14
15 static pthread_t page_in_thread;
16 static pthread_cond_t page_in_cond = PTHREAD_COND_INITIALIZER;
17 static pthread_mutex_t page_in_mutex = PTHREAD_MUTEX_INITIALIZER;
18
page_in(void * arg)19 static void *page_in(void *arg)
20 {
21 struct page_in_args *pia = arg;
22 void *page;
23 int i, num;
24 xen_pfn_t gfns[XENPAGING_PAGEIN_QUEUE_SIZE];
25
26 while (1)
27 {
28 pthread_mutex_lock(&page_in_mutex);
29 while (!page_in_request)
30 pthread_cond_wait(&page_in_cond, &page_in_mutex);
31 num = 0;
32 for (i = 0; i < XENPAGING_PAGEIN_QUEUE_SIZE; i++)
33 {
34 if (!pia->pagein_queue[i])
35 continue;
36 gfns[num] = pia->pagein_queue[i];
37 pia->pagein_queue[i] = 0;
38 num++;
39 }
40 page_in_request = 0;
41 pthread_mutex_unlock(&page_in_mutex);
42
43 /* Ignore errors */
44 page = xc_map_foreign_pages(pia->xch, pia->dom, PROT_READ, gfns, num);
45 if (page)
46 munmap(page, PAGE_SIZE * num);
47 }
48 page_in_possible = 0;
49 pthread_exit(NULL);
50 }
51
page_in_trigger(void)52 void page_in_trigger(void)
53 {
54 if (!page_in_possible)
55 return;
56
57 pthread_mutex_lock(&page_in_mutex);
58 page_in_request = 1;
59 pthread_mutex_unlock(&page_in_mutex);
60 pthread_cond_signal(&page_in_cond);
61 }
62
create_page_in_thread(struct xenpaging * paging)63 void create_page_in_thread(struct xenpaging *paging)
64 {
65 page_in_args.dom = paging->vm_event.domain_id;
66 page_in_args.pagein_queue = paging->pagein_queue;
67 page_in_args.xch = paging->xc_handle;
68 if (pthread_create(&page_in_thread, NULL, page_in, &page_in_args) == 0)
69 page_in_possible = 1;
70 }
71
72 /*
73 * Local variables:
74 * mode: C
75 * c-file-style: "BSD"
76 * c-basic-offset: 4
77 * indent-tabs-mode: nil
78 * End:
79 */
80