# HG changeset patch
# User Olaf Hering <olaf@xxxxxxxxx>
# Date 1316067236 -7200
# Node ID ad903b34e0997e864539e36b92dde234f9ffbd55
# Parent 1addb9e81178ea164ef516f340df2607fddcb930
xenpaging: watch the domains /xenpaging/num_pages xenstore value
Subsequent patches will use xenstored to store the numbers of pages
xenpaging is suppose to page-out.
Remove num_pages and use target_pages instead.
Signed-off-by: Olaf Hering <olaf@xxxxxxxxx>
diff -r 1addb9e81178 -r ad903b34e099 tools/xenpaging/policy_default.c
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -70,7 +70,7 @@ int policy_init(xenpaging_t *paging)
/* Start in the middle to avoid paging during BIOS startup */
current_gfn = max_pages / 2;
- current_gfn -= paging->num_pages / 2;
+ current_gfn -= paging->target_pages / 2;
rc = 0;
out:
diff -r 1addb9e81178 -r ad903b34e099 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -35,6 +35,9 @@
#include "policy.h"
#include "xenpaging.h"
+/* Defines number of pages to page-out */
+#define WATCH_TARGETPAGES "/xenpaging/num_pages"
+static char *watch_targetpages;
static char watch_token[16];
static char filename[80];
static int interrupted;
@@ -72,7 +75,7 @@ static int xenpaging_wait_for_event_or_t
{
xc_interface *xch = paging->xc_handle;
xc_evtchn *xce = paging->mem_event.xce_handle;
- char **vec;
+ char **vec, *val;
unsigned int num;
struct pollfd fd[2];
int port;
@@ -101,6 +104,7 @@ static int xenpaging_wait_for_event_or_t
vec = xs_read_watch(paging->xs_handle, &num);
if ( vec )
{
+ DPRINTF("path '%s' token '%s'\n", vec[XS_WATCH_PATH],
vec[XS_WATCH_TOKEN]);
if ( strcmp(vec[XS_WATCH_PATH], "@releaseDomain") == 0 &&
strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 )
{
/* If our guest disappeared, set interrupt flag and fall
through */
@@ -111,6 +115,22 @@ static int xenpaging_wait_for_event_or_t
rc = 0;
}
}
+ else if ( strcmp(vec[XS_WATCH_PATH], watch_targetpages) == 0 )
+ {
+ int ret, target_pages;
+ val = xs_read(paging->xs_handle, XBT_NULL, vec[XS_WATCH_PATH],
NULL);
+ if (val)
+ {
+ ret = sscanf(val, "%d", &target_pages);
+ if ( ret > 0 )
+ {
+ if ( target_pages < 0 || target_pages >
paging->max_pages )
+ target_pages = paging->max_pages;
+ paging->target_pages = target_pages;
+ DPRINTF("new target_pages %d\n", target_pages);
+ }
+ }
+ }
free(vec);
}
}
@@ -167,8 +187,8 @@ static xenpaging_t *xenpaging_init(domid
xc_domaininfo_t domain_info;
xc_interface *xch;
xentoollog_logger *dbg = NULL;
- char *p;
- int rc;
+ char *p, *dom_path = NULL, *watchdir = WATCH_TARGETPAGES;
+ int rc, len;
/* Allocate memory */
paging = calloc(1, sizeof(xenpaging_t));
@@ -201,6 +221,28 @@ static xenpaging_t *xenpaging_init(domid
goto err;
}
+ /* watch guests xenpaging directory */
+ dom_path = xs_get_domain_path(paging->xs_handle, domain_id);
+ if ( !dom_path )
+ {
+ ERROR("Could not find domain path\n");
+ goto err;
+ }
+ len = strlen(dom_path) + strlen(watchdir) + 1;
+ watch_targetpages = malloc(len);
+ if ( !watch_targetpages )
+ {
+ ERROR("Could not alloc domain path\n");
+ goto err;
+ }
+ snprintf(watch_targetpages, len, "%s%s", dom_path, watchdir);
+ DPRINTF("watching '%s'\n", watch_targetpages);
+ if ( xs_watch(paging->xs_handle, watch_targetpages, "") == false )
+ {
+ ERROR("Could not bind to xenpaging watch\n");
+ goto err;
+ }
+
p = getenv("XENPAGING_POLICY_MRU_SIZE");
if ( p && *p )
{
@@ -299,7 +341,7 @@ static xenpaging_t *xenpaging_init(domid
num_pages = paging->max_pages;
DPRINTF("setting num_pages to %d\n", num_pages);
}
- paging->num_pages = num_pages;
+ paging->target_pages = num_pages;
/* Initialise policy */
rc = policy_init(paging);
@@ -330,6 +372,8 @@ static xenpaging_t *xenpaging_init(domid
free(paging->mem_event.ring_page);
}
+ free(dom_path);
+ free(watch_targetpages);
free(paging->bitmap);
free(paging);
}
@@ -345,6 +389,9 @@ static int xenpaging_teardown(xenpaging_
if ( paging == NULL )
return 0;
+ xs_unwatch(paging->xs_handle, watch_targetpages, "");
+ xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
+
xch = paging->xc_handle;
paging->xc_handle = NULL;
/* Tear down domain paging in Xen */
@@ -649,6 +696,7 @@ int main(int argc, char *argv[])
xenpaging_victim_t *victims;
mem_event_request_t req;
mem_event_response_t rsp;
+ int num, prev_num = 0;
int i;
int rc = -1;
int rc1;
@@ -673,7 +721,7 @@ int main(int argc, char *argv[])
}
xch = paging->xc_handle;
- DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id,
paging->num_pages);
+ DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id,
paging->target_pages);
/* Open file */
sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
@@ -703,9 +751,6 @@ int main(int argc, char *argv[])
/* listen for page-in events to stop pager */
create_page_in_thread(paging);
- i = evict_pages(paging, fd, victims, paging->num_pages);
- DPRINTF("%d pages evicted. Done.\n", i);
-
/* Swap pages in and out */
while ( 1 )
{
@@ -774,8 +819,6 @@ int main(int argc, char *argv[])
* or clear this pagefile slot on exit */
if ( interrupted )
victims[i].gfn = INVALID_MFN;
- else
- evict_victim(paging, &victims[i], fd, i);
}
else
{
@@ -819,6 +862,29 @@ int main(int argc, char *argv[])
if ( interrupted )
break;
}
+ if ( paging->num_paged_out < paging->target_pages )
+ {
+ num = paging->target_pages - paging->num_paged_out;
+ if ( num != prev_num )
+ {
+ DPRINTF("Need to evict %d pages to reach %d target_pages\n",
num, paging->target_pages);
+ prev_num = num;
+ }
+ /* Limit the number of evicts to be able to process page-in
requests */
+ if ( num > 42 )
+ num = 42;
+ evict_pages(paging, fd, victims, num);
+ }
+ else if ( paging->num_paged_out > paging->target_pages )
+ {
+ num = paging->num_paged_out - paging->target_pages;
+ if ( num != prev_num )
+ {
+ DPRINTF("Need to resume %d pages to reach %d target_pages\n",
num, paging->target_pages);
+ prev_num = num;
+ }
+ resume_pages(paging, num);
+ }
}
DPRINTF("xenpaging got signal %d\n", interrupted);
diff -r 1addb9e81178 -r ad903b34e099 tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -50,7 +50,8 @@ typedef struct xenpaging {
/* number of pages for which data structures were allocated */
int max_pages;
int num_paged_out;
- int num_pages;
+ /* number of pages xenpaging is supposed to page-out */
+ int target_pages;
int policy_mru_size;
unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
} xenpaging_t;
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel
|