All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00 of 24] xenpaging fixes for xen-unstable
@ 2011-10-03 15:54 Olaf Hering
  2011-10-03 15:54 ` [PATCH 01 of 24] xenpaging: remove filename from comment Olaf Hering
                   ` (24 more replies)
  0 siblings, 25 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel


The following series adds support for xenpaging to libxl and the xl command.
A few code cleanup changes are also part of this series.

The logic of xenpaging was reversed.
It does now monitor the guests tot_pages value and work toward that number by
either paging out more pages, or write pages back into the guest.

Three new configuration file options specific for xenpaging were added:
totmem=<int>
xenpaging_file=<string>
xenpaging_extra=[ 'string', 'string' ]

A new xl command 'mem-tot_pages' instructs xenpaging to adjust its pagefile
size, and it instructs the xl monitor process to actually start xenpaging if
totmem= was not specified in the config file.

Please review and apply.

Olaf


 Config.mk                        |    2 
 config/StdGNU.mk                 |    2 
 tools/libxc/xc_bitops.h          |    6 
 tools/libxl/libxl.c              |  121 +++++++++
 tools/libxl/libxl.h              |    5 
 tools/libxl/libxl_create.c       |  146 +++++++++++
 tools/libxl/libxl_device.c       |   84 ------
 tools/libxl/libxl_dm.c           |   65 +----
 tools/libxl/libxl_dom.c          |    8 
 tools/libxl/libxl_exec.c         |  142 +++++++++++
 tools/libxl/libxl_internal.h     |   33 ++
 tools/libxl/libxl_paths.c        |    5 
 tools/libxl/libxl_types.idl      |    4 
 tools/libxl/xl.h                 |    1 
 tools/libxl/xl_cmdimpl.c         |   71 +++++
 tools/libxl/xl_cmdtable.c        |    5 
 tools/xenpaging/Makefile         |    6 
 tools/xenpaging/file_ops.c       |    6 
 tools/xenpaging/policy_default.c |   23 +
 tools/xenpaging/xenpaging.c      |  479 ++++++++++++++++++++++++++++-----------
 tools/xenpaging/xenpaging.h      |    8 
 21 files changed, 934 insertions(+), 288 deletions(-)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 01 of 24] xenpaging: remove filename from comment
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 02 of 24] xenpaging: remove obsolete comment in resume path Olaf Hering
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653595 -7200
# Node ID f2c4a25eec9ce1fcba0efb26ef21711929cca47c
# Parent  e78cd03b0308c3ba5737ba9821bf7272f45549ca
xenpaging: remove filename from comment

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r e78cd03b0308 -r f2c4a25eec9c tools/xenpaging/file_ops.c
--- a/tools/xenpaging/file_ops.c
+++ b/tools/xenpaging/file_ops.c
@@ -1,5 +1,4 @@
 /******************************************************************************
- * tools/xenpaging/file_ops.c
  *
  * Common file operations.
  *
diff -r e78cd03b0308 -r f2c4a25eec9c tools/xenpaging/policy_default.c
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -1,5 +1,4 @@
 /******************************************************************************
- * tools/xenpaging/policy.c
  *
  * Xen domain paging default policy.
  *
diff -r e78cd03b0308 -r f2c4a25eec9c tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -1,5 +1,4 @@
 /******************************************************************************
- * tools/xenpaging/xenpaging.c
  *
  * Domain paging. 
  * Copyright (c) 2009 by Citrix Systems, Inc. (Patrick Colp)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 02 of 24] xenpaging: remove obsolete comment in resume path
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
  2011-10-03 15:54 ` [PATCH 01 of 24] xenpaging: remove filename from comment Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 03 of 24] xenpaging: use PERROR to print errno Olaf Hering
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653596 -7200
# Node ID 21b7c9a6545ac1ec9d91fce83d46aab0b5808b05
# Parent  f2c4a25eec9ce1fcba0efb26ef21711929cca47c
xenpaging: remove obsolete comment in resume path

Remove stale comment.
If a page was populated several times the vcpu is paused and
xenpaging has to unpause it again.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r f2c4a25eec9c -r 21b7c9a6545a tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -742,7 +742,6 @@ int main(int argc, char *argv[])
                         req.gfn, req.flags & MEM_EVENT_FLAG_VCPU_PAUSED);
 
                 /* Tell Xen to resume the vcpu */
-                /* XXX: Maybe just check if the vcpu was paused? */
                 if ( req.flags & MEM_EVENT_FLAG_VCPU_PAUSED )
                 {
                     /* Prepare the response */

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 03 of 24] xenpaging: use PERROR to print errno
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
  2011-10-03 15:54 ` [PATCH 01 of 24] xenpaging: remove filename from comment Olaf Hering
  2011-10-03 15:54 ` [PATCH 02 of 24] xenpaging: remove obsolete comment in resume path Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-04 16:19   ` George Dunlap
  2011-10-03 15:54 ` [PATCH 04 of 24] xenpaging: update xenpaging_init Olaf Hering
                   ` (21 subsequent siblings)
  24 siblings, 1 reply; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653597 -7200
# Node ID ee4c4c7699e0de2b6bddce1e816d35f36ffb0470
# Parent  21b7c9a6545ac1ec9d91fce83d46aab0b5808b05
xenpaging: use PERROR to print errno

Also catch lseek() errors in file_op().

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/file_ops.c
--- a/tools/xenpaging/file_ops.c
+++ b/tools/xenpaging/file_ops.c
@@ -37,6 +37,11 @@ static int file_op(int fd, void *page, i
     int ret;
 
     seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET);
+    if (seek_ret == -1)
+    {
+        ret = -errno;
+        goto err;
+    }
 
     total = 0;
     while ( total < PAGE_SIZE )
diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -90,7 +90,7 @@ static int xenpaging_wait_for_event_or_t
         if (errno == EINTR)
             return 0;
 
-        ERROR("Poll exited with an error");
+        PERROR("Poll exited with an error");
         return -errno;
     }
 
@@ -121,7 +121,7 @@ static int xenpaging_wait_for_event_or_t
         port = xc_evtchn_pending(xce);
         if ( port == -1 )
         {
-            ERROR("Failed to read port from event channel");
+            PERROR("Failed to read port from event channel");
             rc = -1;
             goto err;
         }
@@ -129,7 +129,7 @@ static int xenpaging_wait_for_event_or_t
         rc = xc_evtchn_unmask(xce, port);
         if ( rc < 0 )
         {
-            ERROR("Failed to unmask event channel port");
+            PERROR("Failed to unmask event channel port");
         }
     }
 err:
@@ -185,7 +185,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->xs_handle = xs_open(0);
     if ( paging->xs_handle == NULL )
     {
-        ERROR("Error initialising xenstore connection");
+        PERROR("Error initialising xenstore connection");
         goto err;
     }
 
@@ -193,7 +193,7 @@ static xenpaging_t *xenpaging_init(domid
     snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
     if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
     {
-        ERROR("Could not bind to shutdown watch\n");
+        PERROR("Could not bind to shutdown watch\n");
         goto err;
     }
 
@@ -214,7 +214,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->mem_event.shared_page = init_page();
     if ( paging->mem_event.shared_page == NULL )
     {
-        ERROR("Error initialising shared page");
+        PERROR("Error initialising shared page");
         goto err;
     }
 
@@ -222,7 +222,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->mem_event.ring_page = init_page();
     if ( paging->mem_event.ring_page == NULL )
     {
-        ERROR("Error initialising ring page");
+        PERROR("Error initialising ring page");
         goto err;
     }
 
@@ -240,13 +240,13 @@ static xenpaging_t *xenpaging_init(domid
     {
         switch ( errno ) {
             case EBUSY:
-                ERROR("xenpaging is (or was) active on this domain");
+                PERROR("xenpaging is (or was) active on this domain");
                 break;
             case ENODEV:
-                ERROR("EPT not supported for this guest");
+                PERROR("EPT not supported for this guest");
                 break;
             default:
-                ERROR("Error initialising shared page: %s", strerror(errno));
+                PERROR("Error initialising shared page: %s", strerror(errno));
                 break;
         }
         goto err;
@@ -256,7 +256,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->mem_event.xce_handle = xc_evtchn_open(NULL, 0);
     if ( paging->mem_event.xce_handle == NULL )
     {
-        ERROR("Failed to open event channel");
+        PERROR("Failed to open event channel");
         goto err;
     }
 
@@ -266,7 +266,7 @@ static xenpaging_t *xenpaging_init(domid
                                     paging->mem_event.shared_page->port);
     if ( rc < 0 )
     {
-        ERROR("Failed to bind event channel");
+        PERROR("Failed to bind event channel");
         goto err;
     }
 
@@ -276,7 +276,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->domain_info = malloc(sizeof(xc_domaininfo_t));
     if ( paging->domain_info == NULL )
     {
-        ERROR("Error allocating memory for domain info");
+        PERROR("Error allocating memory for domain info");
         goto err;
     }
 
@@ -284,7 +284,7 @@ static xenpaging_t *xenpaging_init(domid
                                paging->domain_info);
     if ( rc != 1 )
     {
-        ERROR("Error getting domain info");
+        PERROR("Error getting domain info");
         goto err;
     }
 
@@ -292,7 +292,7 @@ static xenpaging_t *xenpaging_init(domid
     paging->bitmap = bitmap_alloc(paging->domain_info->max_pages);
     if ( !paging->bitmap )
     {
-        ERROR("Error allocating bitmap");
+        PERROR("Error allocating bitmap");
         goto err;
     }
     DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
@@ -308,7 +308,7 @@ static xenpaging_t *xenpaging_init(domid
     rc = policy_init(paging);
     if ( rc != 0 )
     {
-        ERROR("Error initialising policy");
+        PERROR("Error initialising policy");
         goto err;
     }
 
@@ -355,14 +355,14 @@ static int xenpaging_teardown(xenpaging_
     rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
     if ( rc != 0 )
     {
-        ERROR("Error tearing down domain paging in xen");
+        PERROR("Error tearing down domain paging in xen");
     }
 
     /* Unbind VIRQ */
     rc = xc_evtchn_unbind(paging->mem_event.xce_handle, paging->mem_event.port);
     if ( rc != 0 )
     {
-        ERROR("Error unbinding event port");
+        PERROR("Error unbinding event port");
     }
     paging->mem_event.port = -1;
 
@@ -370,7 +370,7 @@ static int xenpaging_teardown(xenpaging_
     rc = xc_evtchn_close(paging->mem_event.xce_handle);
     if ( rc != 0 )
     {
-        ERROR("Error closing event channel");
+        PERROR("Error closing event channel");
     }
     paging->mem_event.xce_handle = NULL;
     
@@ -381,7 +381,7 @@ static int xenpaging_teardown(xenpaging_
     rc = xc_interface_close(xch);
     if ( rc != 0 )
     {
-        ERROR("Error closing connection to xen");
+        PERROR("Error closing connection to xen");
     }
 
     return 0;
@@ -441,7 +441,7 @@ static int xenpaging_evict_page(xenpagin
                                 PROT_READ | PROT_WRITE, &gfn, 1);
     if ( page == NULL )
     {
-        ERROR("Error mapping page");
+        PERROR("Error mapping page");
         goto out;
     }
 
@@ -449,8 +449,8 @@ static int xenpaging_evict_page(xenpagin
     ret = write_page(fd, page, i);
     if ( ret != 0 )
     {
+        PERROR("Error copying page");
         munmap(page, PAGE_SIZE);
-        ERROR("Error copying page");
         goto out;
     }
 
@@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin
                               victim->gfn);
     if ( ret != 0 )
     {
-        ERROR("Error evicting page");
+        PERROR("Error evicting page");
         goto out;
     }
 
@@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa
                 sleep(1);
                 continue;
             }
-            ERROR("Error preparing for page in");
+            PERROR("Error preparing for page in");
             goto out_map;
         }
     }
@@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa
                                 PROT_READ | PROT_WRITE, &gfn, 1);
     if ( page == NULL )
     {
-        ERROR("Error mapping page: page is null");
+        PERROR("Error mapping page: page is null");
         goto out_map;
     }
 
@@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa
     ret = read_page(fd, page, i);
     if ( ret != 0 )
     {
-        ERROR("Error reading page");
+        PERROR("Error reading page");
         goto out;
     }
 
@@ -579,7 +579,7 @@ static int evict_victim(xenpaging_t *pag
         {
             if ( j++ % 1000 == 0 )
                 if ( xenpaging_mem_paging_flush_ioemu_cache(paging) )
-                    ERROR("Error flushing ioemu cache");
+                    PERROR("Error flushing ioemu cache");
         }
     }
     while ( ret );
@@ -670,7 +670,7 @@ int main(int argc, char *argv[])
         rc = xenpaging_wait_for_event_or_timeout(paging);
         if ( rc < 0 )
         {
-            ERROR("Error getting event");
+            PERROR("Error getting event");
             goto out;
         }
         else if ( rc != 0 )
@@ -710,7 +710,7 @@ int main(int argc, char *argv[])
                     rc = xenpaging_populate_page(paging, req.gfn, fd, i);
                     if ( rc != 0 )
                     {
-                        ERROR("Error populating page");
+                        PERROR("Error populating page");
                         goto out;
                     }
                 }
@@ -723,7 +723,7 @@ int main(int argc, char *argv[])
                 rc = xenpaging_resume_page(paging, &rsp, 1);
                 if ( rc != 0 )
                 {
-                    ERROR("Error resuming page");
+                    PERROR("Error resuming page");
                     goto out;
                 }
 
@@ -752,7 +752,7 @@ int main(int argc, char *argv[])
                     rc = xenpaging_resume_page(paging, &rsp, 0);
                     if ( rc != 0 )
                     {
-                        ERROR("Error resuming");
+                        PERROR("Error resuming");
                         goto out;
                     }
                 }

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 04 of 24] xenpaging: update xenpaging_init
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (2 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 03 of 24] xenpaging: use PERROR to print errno Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 05 of 24] xenpaging: remove xc_dominfo_t from paging_t Olaf Hering
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653599 -7200
# Node ID cef74f38274df3bf619f9b4f80d2843dd033fea5
# Parent  ee4c4c7699e0de2b6bddce1e816d35f36ffb0470
xenpaging: update xenpaging_init

Move comment about xc_handle to the right place.
Allocate paging early and use calloc.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r ee4c4c7699e0 -r cef74f38274d tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -169,18 +169,21 @@ static xenpaging_t *xenpaging_init(domid
     char *p;
     int rc;
 
+    /* Allocate memory */
+    paging = calloc(1, sizeof(xenpaging_t));
+    if ( !paging )
+        goto err;
+
     if ( getenv("XENPAGING_DEBUG") )
         dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0);
-    xch = xc_interface_open(dbg, NULL, 0);
+
+    /* Open connection to xen */
+    paging->xc_handle = xch = xc_interface_open(dbg, NULL, 0);
     if ( !xch )
-        goto err_iface;
+        goto err;
 
     DPRINTF("xenpaging init\n");
 
-    /* Allocate memory */
-    paging = malloc(sizeof(xenpaging_t));
-    memset(paging, 0, sizeof(xenpaging_t));
-
     /* Open connection to xenstore */
     paging->xs_handle = xs_open(0);
     if ( paging->xs_handle == NULL )
@@ -204,9 +207,6 @@ static xenpaging_t *xenpaging_init(domid
          DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size);
     }
 
-    /* Open connection to xen */
-    paging->xc_handle = xch;
-
     /* Set domain id */
     paging->mem_event.domain_id = domain_id;
 
@@ -319,7 +319,8 @@ static xenpaging_t *xenpaging_init(domid
     {
         if ( paging->xs_handle )
             xs_close(paging->xs_handle);
-        xc_interface_close(xch);
+        if ( xch )
+            xc_interface_close(xch);
         if ( paging->mem_event.shared_page )
         {
             munlock(paging->mem_event.shared_page, PAGE_SIZE);
@@ -337,7 +338,6 @@ static xenpaging_t *xenpaging_init(domid
         free(paging);
     }
 
- err_iface: 
     return NULL;
 }

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 05 of 24] xenpaging: remove xc_dominfo_t from paging_t
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (3 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 04 of 24] xenpaging: update xenpaging_init Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 06 of 24] xenpaging: track the number of paged-out pages Olaf Hering
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653600 -7200
# Node ID 003ad7aa543db226db53760549a172dcff236672
# Parent  cef74f38274df3bf619f9b4f80d2843dd033fea5
xenpaging: remove xc_dominfo_t from paging_t

Remove xc_dominfo_t from paging_t, record only max_pages.
This value is used to setup internal data structures.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r cef74f38274d -r 003ad7aa543d tools/xenpaging/policy_default.c
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -41,17 +41,17 @@ int policy_init(xenpaging_t *paging)
     int i;
     int rc = -ENOMEM;
 
+    max_pages = paging->max_pages;
+
     /* Allocate bitmap for pages not to page out */
-    bitmap = bitmap_alloc(paging->domain_info->max_pages);
+    bitmap = bitmap_alloc(max_pages);
     if ( !bitmap )
         goto out;
     /* Allocate bitmap to track unusable pages */
-    unconsumed = bitmap_alloc(paging->domain_info->max_pages);
+    unconsumed = bitmap_alloc(max_pages);
     if ( !unconsumed )
         goto out;
 
-    max_pages = paging->domain_info->max_pages;
-
     /* Initialise MRU list of paged in pages */
     if ( paging->policy_mru_size > 0 )
         mru_size = paging->policy_mru_size;
diff -r cef74f38274d -r 003ad7aa543d tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -164,6 +164,7 @@ static void *init_page(void)
 static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages)
 {
     xenpaging_t *paging;
+    xc_domaininfo_t domain_info;
     xc_interface *xch;
     xentoollog_logger *dbg = NULL;
     char *p;
@@ -272,34 +273,29 @@ static xenpaging_t *xenpaging_init(domid
 
     paging->mem_event.port = rc;
 
-    /* Get domaininfo */
-    paging->domain_info = malloc(sizeof(xc_domaininfo_t));
-    if ( paging->domain_info == NULL )
-    {
-        PERROR("Error allocating memory for domain info");
-        goto err;
-    }
-
     rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
-                               paging->domain_info);
+                               &domain_info);
     if ( rc != 1 )
     {
         PERROR("Error getting domain info");
         goto err;
     }
 
+    /* Record number of max_pages */
+    paging->max_pages = domain_info.max_pages;
+
     /* Allocate bitmap for tracking pages that have been paged out */
-    paging->bitmap = bitmap_alloc(paging->domain_info->max_pages);
+    paging->bitmap = bitmap_alloc(paging->max_pages);
     if ( !paging->bitmap )
     {
         PERROR("Error allocating bitmap");
         goto err;
     }
-    DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
+    DPRINTF("max_pages = %d\n", paging->max_pages);
 
-    if ( num_pages < 0 || num_pages > paging->domain_info->max_pages )
+    if ( num_pages < 0 || num_pages > paging->max_pages )
     {
-        num_pages = paging->domain_info->max_pages;
+        num_pages = paging->max_pages;
         DPRINTF("setting num_pages to %d\n", num_pages);
     }
     paging->num_pages = num_pages;
@@ -334,7 +330,6 @@ static xenpaging_t *xenpaging_init(domid
         }
 
         free(paging->bitmap);
-        free(paging->domain_info);
         free(paging);
     }
 
@@ -763,7 +758,7 @@ int main(int argc, char *argv[])
         if ( interrupted == SIGTERM || interrupted == SIGINT )
         {
             int num = 0;
-            for ( i = 0; i < paging->domain_info->max_pages; i++ )
+            for ( i = 0; i < paging->max_pages; i++ )
             {
                 if ( test_bit(i, paging->bitmap) )
                 {
@@ -779,7 +774,7 @@ int main(int argc, char *argv[])
              */
             if ( num )
                 page_in_trigger();
-            else if ( i == paging->domain_info->max_pages )
+            else if ( i == paging->max_pages )
                 break;
         }
         else
diff -r cef74f38274d -r 003ad7aa543d tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -44,11 +44,11 @@ typedef struct xenpaging {
     xc_interface *xc_handle;
     struct xs_handle *xs_handle;
 
-    xc_domaininfo_t    *domain_info;
-
     unsigned long *bitmap;
 
     mem_event_t mem_event;
+    /* number of pages for which data structures were allocated */
+    int max_pages;
     int num_pages;
     int policy_mru_size;
     unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 06 of 24] xenpaging: track the number of paged-out pages
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (4 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 05 of 24] xenpaging: remove xc_dominfo_t from paging_t Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 07 of 24] xenpaging: move page add/resume loops into its own function Olaf Hering
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653601 -7200
# Node ID 363c2f3df22b27d56297fa96f8d1706e224a323e
# Parent  003ad7aa543db226db53760549a172dcff236672
xenpaging: track the number of paged-out pages

This change is required by subsequent changes.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 003ad7aa543d -r 363c2f3df22b tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -467,6 +467,9 @@ static int xenpaging_evict_page(xenpagin
     /* Notify policy of page being paged out */
     policy_notify_paged_out(victim->gfn);
 
+    /* Record number of evicted pages */
+    paging->num_paged_out++;
+
  out:
     return ret;
 }
@@ -480,8 +483,13 @@ static int xenpaging_resume_page(xenpagi
 
     /* Notify policy of page being paged in */
     if ( notify_policy )
+    {
         policy_notify_paged_in(rsp->gfn);
 
+       /* Record number of resumed pages */
+       paging->num_paged_out--;
+    }
+
     /* Tell Xen page is ready */
     ret = xc_mem_paging_resume(paging->xc_handle, paging->mem_event.domain_id,
                                rsp->gfn);
diff -r 003ad7aa543d -r 363c2f3df22b tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -49,6 +49,7 @@ typedef struct xenpaging {
     mem_event_t mem_event;
     /* number of pages for which data structures were allocated */
     int max_pages;
+    int num_paged_out;
     int num_pages;
     int policy_mru_size;
     unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 07 of 24] xenpaging: move page add/resume loops into its own function
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (5 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 06 of 24] xenpaging: track the number of paged-out pages Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 08 of 24] xenpaging: compare both token and path when checking for @releaseDomain event Olaf Hering
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653603 -7200
# Node ID 02453d6279baad46b1388267639892feaf6d56af
# Parent  363c2f3df22b27d56297fa96f8d1706e224a323e
xenpaging: move page add/resume loops into its own function.

Move page resume loop into its own function.
Move page eviction loop into its own function.
Allocate all possible slots in a paging file to allow growing and
shrinking of the number of paged-out pages. Adjust other places to
iterate over all slots.

This change is required by subsequent patches.

v2:
 - check if victims allocation succeeded

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 363c2f3df22b -r 02453d6279ba tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -553,6 +553,27 @@ static int xenpaging_populate_page(xenpa
     return ret;
 }
 
+/* Trigger a page-in for a batch of pages */
+static void resume_pages(xenpaging_t *paging, int num_pages)
+{
+    xc_interface *xch = paging->xc_handle;
+    int i, num = 0;
+
+    for ( i = 0; i < paging->max_pages && num < num_pages; i++ )
+    {
+        if ( test_bit(i, paging->bitmap) )
+        {
+            paging->pagein_queue[num] = i;
+            num++;
+            if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
+                break;
+        }
+    }
+    /* num may be less than num_pages, caller has to try again */
+    if ( num )
+        page_in_trigger();
+}
+
 static int evict_victim(xenpaging_t *paging,
                         xenpaging_victim_t *victim, int fd, int i)
 {
@@ -596,6 +617,30 @@ static int evict_victim(xenpaging_t *pag
     return ret;
 }
 
+/* Evict a batch of pages and write them to a free slot in the paging file */
+static int evict_pages(xenpaging_t *paging, int fd, xenpaging_victim_t *victims, int num_pages)
+{
+    xc_interface *xch = paging->xc_handle;
+    int rc, slot, num = 0;
+
+    for ( slot = 0; slot < paging->max_pages && num < num_pages; slot++ )
+    {
+        /* Slot is allocated */
+        if ( victims[slot].gfn != INVALID_MFN )
+            continue;
+
+        rc = evict_victim(paging, &victims[slot], fd, slot);
+        if ( rc == -ENOSPC )
+            break;
+        if ( rc == -EINTR )
+            break;
+        if ( num && num % 100 == 0 )
+            DPRINTF("%d pages evicted\n", num);
+        num++;
+    }
+    return num;
+}
+
 int main(int argc, char *argv[])
 {
     struct sigaction act;
@@ -638,7 +683,14 @@ int main(int argc, char *argv[])
         return 2;
     }
 
-    victims = calloc(paging->num_pages, sizeof(xenpaging_victim_t));
+    /* Allocate upper limit of pages to allow growing and shrinking */
+    victims = calloc(paging->max_pages, sizeof(xenpaging_victim_t));
+    if ( !victims )
+        goto out;
+
+    /* Mark all slots as unallocated */
+    for ( i = 0; i < paging->max_pages; i++ )
+        victims[i].gfn = INVALID_MFN;
 
     /* ensure that if we get a signal, we'll do cleanup, then exit */
     act.sa_handler = close_handler;
@@ -652,18 +704,7 @@ int main(int argc, char *argv[])
     /* listen for page-in events to stop pager */
     create_page_in_thread(paging);
 
-    /* Evict pages */
-    for ( i = 0; i < paging->num_pages; i++ )
-    {
-        rc = evict_victim(paging, &victims[i], fd, i);
-        if ( rc == -ENOSPC )
-            break;
-        if ( rc == -EINTR )
-            break;
-        if ( i % 100 == 0 )
-            DPRINTF("%d pages evicted\n", i);
-    }
-
+    i = evict_pages(paging, fd, victims, paging->num_pages);
     DPRINTF("%d pages evicted. Done.\n", i);
 
     /* Swap pages in and out */
@@ -689,13 +730,13 @@ int main(int argc, char *argv[])
             if ( test_and_clear_bit(req.gfn, paging->bitmap) )
             {
                 /* Find where in the paging file to read from */
-                for ( i = 0; i < paging->num_pages; i++ )
+                for ( i = 0; i < paging->max_pages; i++ )
                 {
                     if ( victims[i].gfn == req.gfn )
                         break;
                 }
     
-                if ( i >= paging->num_pages )
+                if ( i >= paging->max_pages )
                 {
                     DPRINTF("Couldn't find page %"PRIx64"\n", req.gfn);
                     goto out;
@@ -765,25 +806,12 @@ 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->max_pages; i++ )
-            {
-                if ( test_bit(i, paging->bitmap) )
-                {
-                    paging->pagein_queue[num] = i;
-                    num++;
-                    if ( num == XENPAGING_PAGEIN_QUEUE_SIZE )
-                        break;
-                }
-            }
-            /*
-             * 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->max_pages )
+            /* If no more pages to process, exit loop. */
+            if ( !paging->num_paged_out )
                 break;
+            
+            /* One more round if there are still pages to process. */
+            resume_pages(paging, paging->num_paged_out);
         }
         else
         {

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 08 of 24] xenpaging: compare both token and path when checking for @releaseDomain event
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (6 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 07 of 24] xenpaging: move page add/resume loops into its own function Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 09 of 24] xenpaging: improve mainloop exit handling Olaf Hering
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653604 -7200
# Node ID 87cc0a717a5edc87411295ad0d5cf0b3366da0d3
# Parent  02453d6279baad46b1388267639892feaf6d56af
xenpaging: compare both token and path when checking for @releaseDomain event

Subsequent patches will use xenstored to store the numbers of pages
xenpaging is suppose to page-out. A domain_id value could be
misinterpreted as number of pages. Compare both path and token to
recognize the @releaseDomain event.

Also add debug output to show received watch event.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 02453d6279ba -r 87cc0a717a5e tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -101,7 +101,8 @@ static int xenpaging_wait_for_event_or_t
         vec = xs_read_watch(paging->xs_handle, &num);
         if ( vec )
         {
-            if ( strcmp(vec[XS_WATCH_TOKEN], watch_token) == 0 )
+            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 */
                 if ( xs_is_domain_introduced(paging->xs_handle, paging->mem_event.domain_id) == false )

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 09 of 24] xenpaging: improve mainloop exit handling
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (7 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 08 of 24] xenpaging: compare both token and path when checking for @releaseDomain event Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 10 of 24] libxc: add bitmap_clear function Olaf Hering
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653605 -7200
# Node ID 5d2d87fb19e4749ca11d9d002ee5b44271594cb3
# Parent  87cc0a717a5edc87411295ad0d5cf0b3366da0d3
xenpaging: improve mainloop exit handling

Remove the if/else logic to exit from the in case a signal arrives.
Update comments.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 87cc0a717a5e -r 5d2d87fb19e4 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -804,7 +804,7 @@ int main(int argc, char *argv[])
             }
         }
 
-        /* Write all pages back into the guest */
+        /* If interrupted, write all pages back into the guest */
         if ( interrupted == SIGTERM || interrupted == SIGINT )
         {
             /* If no more pages to process, exit loop. */
@@ -813,13 +813,15 @@ int main(int argc, char *argv[])
             
             /* One more round if there are still pages to process. */
             resume_pages(paging, paging->num_paged_out);
+
+            /* Resume main loop */
+            continue;
         }
-        else
-        {
-            /* Exit on any other signal */
-            if ( interrupted )
-                break;
-        }
+
+        /* Exit main loop on any other signal */
+        if ( interrupted )
+            break;
+
     }
     DPRINTF("xenpaging got signal %d\n", interrupted);

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 10 of 24] libxc: add bitmap_clear function
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (8 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 09 of 24] xenpaging: improve mainloop exit handling Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 11 of 24] xenpaging: retry unpageable gfns Olaf Hering
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653607 -7200
# Node ID b85b2fa9a485cdd815eb9eb3e3a7794b462fa814
# Parent  5d2d87fb19e4749ca11d9d002ee5b44271594cb3
libxc: add bitmap_clear function

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 5d2d87fb19e4 -r b85b2fa9a485 tools/libxc/xc_bitops.h
--- a/tools/libxc/xc_bitops.h
+++ b/tools/libxc/xc_bitops.h
@@ -4,6 +4,7 @@
 /* bitmap operations for single threaded access */
 
 #include <stdlib.h>
+#include <string.h>
 
 #define BITS_PER_LONG (sizeof(unsigned long) * 8)
 #define ORDER_LONG (sizeof(unsigned long) == 4 ? 5 : 6)
@@ -25,6 +26,11 @@ static inline unsigned long *bitmap_allo
     return calloc(1, bitmap_size(nr_bits));
 }
 
+static inline void bitmap_clear(unsigned long *addr, int nr_bits)
+{
+    memset(addr, 0, bitmap_size(nr_bits));
+}
+
 static inline int test_bit(int nr, volatile unsigned long *addr)
 {
     return (BITMAP_ENTRY(nr, addr) >> BITMAP_SHIFT(nr)) & 1;

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 11 of 24] xenpaging: retry unpageable gfns
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (9 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 10 of 24] libxc: add bitmap_clear function Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 12 of 24] libxl: rename libxl__device_model_starting Olaf Hering
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653608 -7200
# Node ID 3924c1ef71ee975b4556ca7766b730dfa3e12295
# Parent  b85b2fa9a485cdd815eb9eb3e3a7794b462fa814
xenpaging: retry unpageable gfns

Nomination of gfns can fail, but may succeed later.
Thats the case for a guest that starts ballooned.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r b85b2fa9a485 -r 3924c1ef71ee tools/xenpaging/policy_default.c
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -32,6 +32,7 @@ static unsigned int i_mru;
 static unsigned int mru_size;
 static unsigned long *bitmap;
 static unsigned long *unconsumed;
+static unsigned int unconsumed_cleared;
 static unsigned long current_gfn;
 static unsigned long max_pages;
 
@@ -87,8 +88,20 @@ int policy_choose_victim(xenpaging_t *pa
         current_gfn++;
         if ( current_gfn >= max_pages )
             current_gfn = 0;
+        /* Could not nominate any gfn */
         if ( wrap == current_gfn )
         {
+            /* Count wrap arounds */
+            unconsumed_cleared++;
+            /* Force retry every few seconds (depends on poll() timeout) */
+            if ( unconsumed_cleared > 123)
+            {
+                /* Force retry of unconsumed gfns */
+                bitmap_clear(unconsumed, max_pages);
+                unconsumed_cleared = 0;
+                /* One more round before returning ENOSPC */
+                continue;
+            }
             victim->gfn = INVALID_MFN;
             return -ENOSPC;
         }

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 12 of 24] libxl: rename libxl__device_model_starting
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (10 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 11 of 24] xenpaging: retry unpageable gfns Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 13 of 24] libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid Olaf Hering
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653609 -7200
# Node ID ea8738e045595a235fc05384d3f4d7c74537cd0a
# Parent  3924c1ef71ee975b4556ca7766b730dfa3e12295
libxl: rename libxl__device_model_starting

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -434,7 +434,7 @@ static int do_domain_create(libxl__gc *g
                             uint32_t *domid_out, int restore_fd)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
-    libxl__device_model_starting *dm_starting = 0;
+    libxl__spawner_starting *dm_starting = 0;
     libxl_device_model_info *dm_info = &d_config->dm_info;
     libxl__domain_build_state state;
     uint32_t domid;
diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -518,7 +518,7 @@ static char ** libxl__build_device_model
 
 static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
 {
-    libxl__device_model_starting *starting = for_spawn;
+    libxl__spawner_starting *starting = for_spawn;
     struct xs_handle *xsh;
     char *path = NULL, *pid = NULL;
     int len;
@@ -619,7 +619,7 @@ static int libxl__create_stubdom(libxl__
                                  libxl_device_nic *vifs, int num_vifs,
                                  libxl_device_vfb *vfb,
                                  libxl_device_vkb *vkb,
-                                 libxl__device_model_starting **starting_r)
+                                 libxl__spawner_starting **starting_r)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     int i, num_console = STUBDOM_SPECIAL_CONSOLES, ret;
@@ -631,7 +631,7 @@ static int libxl__create_stubdom(libxl__
     char **args;
     struct xs_permissions perm[2];
     xs_transaction_t t;
-    libxl__device_model_starting *dm_starting = 0;
+    libxl__spawner_starting *dm_starting = 0;
     libxl_device_model_info xenpv_dm_info;
 
     if (info->device_model_version != LIBXL_DEVICE_MODEL_VERSION_QEMU_XEN_TRADITIONAL) {
@@ -784,7 +784,7 @@ retry_transaction:
     libxl_domain_unpause(ctx, domid);
 
     if (starting_r) {
-        *starting_r = calloc(1, sizeof(libxl__device_model_starting));
+        *starting_r = calloc(1, sizeof(libxl__spawner_starting));
         (*starting_r)->domid = info->domid;
         (*starting_r)->dom_path = libxl__xs_get_dompath(gc, info->domid);
         (*starting_r)->for_spawn = NULL;
@@ -802,14 +802,14 @@ int libxl__create_device_model(libxl__gc
                               libxl_device_model_info *info,
                               libxl_device_disk *disks, int num_disks,
                               libxl_device_nic *vifs, int num_vifs,
-                              libxl__device_model_starting **starting_r)
+                              libxl__spawner_starting **starting_r)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     char *path, *logfile;
     int logfile_w, null;
     int rc;
     char **args;
-    libxl__device_model_starting buf_starting, *p;
+    libxl__spawner_starting buf_starting, *p;
     xs_transaction_t t;
     char *vm_path;
     char **pass_stuff;
@@ -861,7 +861,7 @@ int libxl__create_device_model(libxl__gc
 
     if (starting_r) {
         rc = ERROR_NOMEM;
-        *starting_r = calloc(1, sizeof(libxl__device_model_starting));
+        *starting_r = calloc(1, sizeof(libxl__spawner_starting));
         if (!*starting_r)
             goto out_close;
         p = *starting_r;
@@ -915,7 +915,7 @@ out:
 }
 
 static int detach_device_model(libxl__gc *gc,
-                               libxl__device_model_starting *starting)
+                               libxl__spawner_starting *starting)
 {
     int rc;
     rc = libxl__spawn_detach(gc, starting->for_spawn);
@@ -926,7 +926,7 @@ static int detach_device_model(libxl__gc
 }
 
 int libxl__confirm_device_model_startup(libxl__gc *gc,
-                                       libxl__device_model_starting *starting)
+                                       libxl__spawner_starting *starting)
 {
     int detach;
     int problem = libxl__wait_for_device_model(gc, starting->domid, "running",
@@ -1041,7 +1041,7 @@ out:
 int libxl__create_xenpv_qemu(libxl__gc *gc, uint32_t domid,
                              libxl_device_model_info *info,
                              libxl_device_vfb *vfb,
-                             libxl__device_model_starting **starting_r)
+                             libxl__spawner_starting **starting_r)
 {
     libxl__build_xenpv_qemu_args(gc, domid, vfb, info);
     libxl__create_device_model(gc, info, NULL, 0, NULL, 0, starting_r);
diff -r 3924c1ef71ee -r ea8738e04559 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -252,7 +252,7 @@ typedef struct {
     char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */
     int domid;
     libxl__spawn_starting *for_spawn;
-} libxl__device_model_starting;
+} libxl__spawner_starting;
 
 /* from xl_create */
 _hidden int libxl__domain_make(libxl__gc *gc, libxl_domain_create_info *info, uint32_t *domid);
@@ -269,11 +269,11 @@ _hidden int libxl__create_device_model(l
                               libxl_device_model_info *info,
                               libxl_device_disk *disk, int num_disks,
                               libxl_device_nic *vifs, int num_vifs,
-                              libxl__device_model_starting **starting_r);
+                              libxl__spawner_starting **starting_r);
 _hidden int libxl__create_xenpv_qemu(libxl__gc *gc, uint32_t domid,
                               libxl_device_model_info *dm_info,
                               libxl_device_vfb *vfb,
-                              libxl__device_model_starting **starting_r);
+                              libxl__spawner_starting **starting_r);
 _hidden int libxl__need_xenpv_qemu(libxl__gc *gc,
         int nr_consoles, libxl_device_console *consoles,
         int nr_vfbs, libxl_device_vfb *vfbs,
@@ -282,8 +282,8 @@ _hidden int libxl__need_xenpv_qemu(libxl
    * return pass *starting_r (which will be non-0) to
    * libxl_confirm_device_model or libxl_detach_device_model. */
 _hidden int libxl__confirm_device_model_startup(libxl__gc *gc,
-                              libxl__device_model_starting *starting);
-_hidden int libxl__detach_device_model(libxl__gc *gc, libxl__device_model_starting *starting);
+                              libxl__spawner_starting *starting);
+_hidden int libxl__detach_device_model(libxl__gc *gc, libxl__spawner_starting *starting);
 _hidden int libxl__wait_for_device_model(libxl__gc *gc,
                                 uint32_t domid, char *state,
                                 libxl__spawn_starting *spawning,

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 13 of 24] libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (11 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 12 of 24] libxl: rename libxl__device_model_starting Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting Olaf Hering
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653611 -7200
# Node ID df7be429654c62fb4c61f83549374d77b80ebea3
# Parent  ea8738e045595a235fc05384d3f4d7c74537cd0a
libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -516,31 +516,6 @@ static char ** libxl__build_device_model
     }
 }
 
-static void dm_xenstore_record_pid(void *for_spawn, pid_t innerchild)
-{
-    libxl__spawner_starting *starting = for_spawn;
-    struct xs_handle *xsh;
-    char *path = NULL, *pid = NULL;
-    int len;
-
-    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
-        goto out;
-
-    len = asprintf(&pid, "%d", innerchild);
-    if (len < 0)
-        goto out;
-
-    /* we mustn't use the parent's handle in the child */
-    xsh = xs_daemon_open();
-
-    xs_write(xsh, XBT_NULL, path, pid, len);
-
-    xs_daemon_close(xsh);
-out:
-    free(path);
-    free(pid);
-}
-
 static int libxl__vfb_and_vkb_from_device_model_info(libxl__gc *gc,
                                                      libxl_device_model_info *info,
                                                      libxl_device_vfb *vfb,
@@ -896,7 +871,7 @@ retry_transaction:
     }
 
     rc = libxl__spawn_spawn(gc, p->for_spawn, "device model",
-                            dm_xenstore_record_pid, p);
+                            libxl_spawner_record_pid, p);
     if (rc < 0)
         goto out_close;
     if (!rc) { /* inner child */
diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -144,6 +144,31 @@ void libxl_report_child_exitstatus(libxl
     }
 }
 
+void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild)
+{
+    libxl__spawner_starting *starting = for_spawn;
+    struct xs_handle *xsh;
+    char *path = NULL, *pid = NULL;
+    int len;
+
+    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
+        goto out;
+
+    len = asprintf(&pid, "%d", innerchild);
+    if (len < 0)
+        goto out;
+
+    /* we mustn't use the parent's handle in the child */
+    xsh = xs_daemon_open();
+
+    xs_write(xsh, XBT_NULL, path, pid, len);
+
+    xs_daemon_close(xsh);
+out:
+    free(path);
+    free(pid);
+}
+
 static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag)
 {
     int flags;
diff -r ea8738e04559 -r df7be429654c tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -249,7 +249,7 @@ typedef struct {
 } libxl__spawn_starting;
 
 typedef struct {
-    char *dom_path; /* from libxl_malloc, only for dm_xenstore_record_pid */
+    char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
     int domid;
     libxl__spawn_starting *for_spawn;
 } libxl__spawner_starting;
@@ -300,6 +300,8 @@ _hidden int libxl__spawn_spawn(libxl__gc
                       void *hook_data);
 _hidden int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid);
 
+_hidden void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild);
+
   /* Logs errors.  A copy of "what" is taken.  Return values:
    *  < 0   error, for_spawn need not be detached
    *   +1   caller is the parent, must call detach on *for_spawn eventually

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (12 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 13 of 24] libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-04  8:23   ` Ian Campbell
  2011-10-03 15:54 ` [PATCH 15 of 24] libxl: add libxl__wait_for_offspring function Olaf Hering
                   ` (10 subsequent siblings)
  24 siblings, 1 reply; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653612 -7200
# Node ID 219ab93f22c0492595686a1cc34911e9d6775b07
# Parent  df7be429654c62fb4c61f83549374d77b80ebea3
libxl: add pid path to libxl__spawner_starting

libxl_spawner_record_pid() should be able to write the pid to arbitrary paths.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -848,6 +848,7 @@ int libxl__create_device_model(libxl__gc
 
     p->domid = info->domid;
     p->dom_path = libxl__xs_get_dompath(gc, info->domid);
+    p->pid_path = "image/device-model-pid";
     if (!p->dom_path) {
         rc = ERROR_FAIL;
         goto out_close;
diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -151,7 +151,7 @@ void libxl_spawner_record_pid(void *for_
     char *path = NULL, *pid = NULL;
     int len;
 
-    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
+    if (asprintf(&path, "%s/%s", starting->dom_path, starting->pid_path) < 0)
         goto out;
 
     len = asprintf(&pid, "%d", innerchild);
diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -250,6 +250,7 @@ typedef struct {
 
 typedef struct {
     char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
+    char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
     int domid;
     libxl__spawn_starting *for_spawn;
 } libxl__spawner_starting;

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 15 of 24] libxl: add libxl__wait_for_offspring function
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (13 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 16 of 24] libxl: use libxl__wait_for_offspring for device model Olaf Hering
                   ` (9 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653613 -7200
# Node ID cfca4b1f83f9c2ebf1c1986aad51571243db4c77
# Parent  219ab93f22c0492595686a1cc34911e9d6775b07
libxl: add libxl__wait_for_offspring function

libxl__wait_for_offspring() is a generic version of
libxl__wait_for_device_model().

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -169,6 +169,99 @@ out:
     free(pid);
 }
 
+int libxl__wait_for_offspring(libxl__gc *gc,
+                                 uint32_t domid,
+                                 uint32_t timeout, char *what,
+                                 char *path, char *state,
+                                 libxl__spawn_starting *spawning,
+                                 int (*check_callback)(libxl__gc *gc,
+                                                       uint32_t domid,
+                                                       const char *state,
+                                                       void *userdata),
+                                 void *check_callback_userdata)
+{
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+    char *p;
+    unsigned int len;
+    int rc = 0;
+    struct xs_handle *xsh;
+    int nfds;
+    fd_set rfds;
+    struct timeval tv;
+    unsigned int num;
+    char **l = NULL;
+
+    xsh = xs_daemon_open();
+    if (xsh == NULL) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to open xenstore connection");
+        goto err;
+    }
+
+    xs_watch(xsh, path, path);
+    tv.tv_sec = timeout;
+    tv.tv_usec = 0;
+    nfds = xs_fileno(xsh) + 1;
+    if (spawning && spawning->fd > xs_fileno(xsh))
+        nfds = spawning->fd + 1;
+
+    while (rc > 0 || (!rc && tv.tv_sec > 0)) {
+        if ( spawning ) {
+            rc = libxl__spawn_check(gc, spawning);
+            if ( rc ) {
+                LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                           "%s died during startup", what);
+                rc = -1;
+                goto err_died;
+            }
+        }
+        p = xs_read(xsh, XBT_NULL, path, &len);
+        if ( NULL == p )
+            goto again;
+
+        if ( NULL != state && strcmp(p, state) )
+            goto again;
+
+        if ( NULL != check_callback ) {
+            rc = (*check_callback)(gc, domid, p, check_callback_userdata);
+            if ( rc > 0 )
+                goto again;
+        }
+
+        free(p);
+        xs_unwatch(xsh, path, path);
+        xs_daemon_close(xsh);
+        return rc;
+again:
+        free(p);
+        FD_ZERO(&rfds);
+        FD_SET(xs_fileno(xsh), &rfds);
+        if (spawning)
+            FD_SET(spawning->fd, &rfds);
+        rc = select(nfds, &rfds, NULL, NULL, &tv);
+        if (rc > 0) {
+            if (FD_ISSET(xs_fileno(xsh), &rfds)) {
+                l = xs_read_watch(xsh, &num);
+                if (l != NULL)
+                    free(l);
+                else
+                    goto again;
+            }
+            if (spawning && FD_ISSET(spawning->fd, &rfds)) {
+                unsigned char dummy;
+                if (read(spawning->fd, &dummy, sizeof(dummy)) != 1)
+                    LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG,
+                                     "failed to read spawn status pipe");
+            }
+        }
+    }
+    LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "%s not ready", what);
+err_died:
+    xs_unwatch(xsh, path, path);
+    xs_daemon_close(xsh);
+err:
+    return -1;
+}
+
 static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag)
 {
     int flags;
diff -r 219ab93f22c0 -r cfca4b1f83f9 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -303,6 +303,16 @@ _hidden int libxl__destroy_device_model(
 
 _hidden void libxl_spawner_record_pid(void *for_spawn, pid_t innerchild);
 
+_hidden int libxl__wait_for_offspring(libxl__gc *gc,
+                                 uint32_t domid,
+                                 uint32_t timeout, char *what,
+                                 char *path, char *state,
+                                 libxl__spawn_starting *spawning,
+                                 int (*check_callback)(libxl__gc *gc,
+                                                       uint32_t domid,
+                                                       const char *state,
+                                                       void *userdata),
+                                 void *check_callback_userdata);
   /* Logs errors.  A copy of "what" is taken.  Return values:
    *  < 0   error, for_spawn need not be detached
    *   +1   caller is the parent, must call detach on *for_spawn eventually
@@ -318,7 +328,7 @@ _hidden int libxl__spawn_check(libxl__gc
   /* Logs errors but also returns them.
    * for_spawn must actually be a  libxl__spawn_starting*  but
    * we take void* so you can pass this function directly to
-   * libxl__wait_for_device_model.  Caller must still call detach. */
+   * libxl__wait_for_offspring.  Caller must still call detach. */
 
  /* low-level stuff, for synchronous subprocesses etc. */

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 16 of 24] libxl: use libxl__wait_for_offspring for device model
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (14 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 15 of 24] libxl: add libxl__wait_for_offspring function Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup Olaf Hering
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653615 -7200
# Node ID 35ec0355b3283a87477c7377a2fd3da5e84d2bcd
# Parent  cfca4b1f83f9c2ebf1c1986aad51571243db4c77
libxl: use libxl__wait_for_offspring for device model

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r cfca4b1f83f9 -r 35ec0355b328 tools/libxl/libxl_device.c
--- a/tools/libxl/libxl_device.c
+++ b/tools/libxl/libxl_device.c
@@ -535,88 +535,12 @@ int libxl__wait_for_device_model(libxl__
                                                        void *userdata),
                                  void *check_callback_userdata)
 {
-    libxl_ctx *ctx = libxl__gc_owner(gc);
     char *path;
-    char *p;
-    unsigned int len;
-    int rc = 0;
-    struct xs_handle *xsh;
-    int nfds;
-    fd_set rfds;
-    struct timeval tv;
-    unsigned int num;
-    char **l = NULL;
-
-    xsh = xs_daemon_open();
-    if (xsh == NULL) {
-        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to open xenstore connection");
-        goto err;
-    }
-
     path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
-    xs_watch(xsh, path, path);
-    tv.tv_sec = LIBXL_DEVICE_MODEL_START_TIMEOUT;
-    tv.tv_usec = 0;
-    nfds = xs_fileno(xsh) + 1;
-    if (spawning && spawning->fd > xs_fileno(xsh))
-        nfds = spawning->fd + 1;
-
-    while (rc > 0 || (!rc && tv.tv_sec > 0)) {
-        if ( spawning ) {
-            rc = libxl__spawn_check(gc, spawning);
-            if ( rc ) {
-                LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
-                           "Device Model died during startup");
-                rc = -1;
-                goto err_died;
-            }
-        }
-        p = xs_read(xsh, XBT_NULL, path, &len);
-        if ( NULL == p )
-            goto again;
-
-        if ( NULL != state && strcmp(p, state) )
-            goto again;
-
-        if ( NULL != check_callback ) {
-            rc = (*check_callback)(gc, domid, p, check_callback_userdata);
-            if ( rc > 0 )
-                goto again;
-        }
-
-        free(p);
-        xs_unwatch(xsh, path, path);
-        xs_daemon_close(xsh);
-        return rc;
-again:
-        free(p);
-        FD_ZERO(&rfds);
-        FD_SET(xs_fileno(xsh), &rfds);
-        if (spawning)
-            FD_SET(spawning->fd, &rfds);
-        rc = select(nfds, &rfds, NULL, NULL, &tv);
-        if (rc > 0) {
-            if (FD_ISSET(xs_fileno(xsh), &rfds)) {
-                l = xs_read_watch(xsh, &num);
-                if (l != NULL)
-                    free(l);
-                else
-                    goto again;
-            }
-            if (spawning && FD_ISSET(spawning->fd, &rfds)) {
-                unsigned char dummy;
-                if (read(spawning->fd, &dummy, sizeof(dummy)) != 1)
-                    LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_DEBUG,
-                                     "failed to read spawn status pipe");
-            }
-        }
-    }
-    LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Device Model not ready");
-err_died:
-    xs_unwatch(xsh, path, path);
-    xs_daemon_close(xsh);
-err:
-    return -1;
+    return libxl__wait_for_offspring(gc, domid,
+                                     LIBXL_DEVICE_MODEL_START_TIMEOUT,
+                                     "Device Model", path, state, spawning,
+                                     check_callback, check_callback_userdata);
 }
 
 int libxl__wait_for_backend(libxl__gc *gc, char *be_path, char *state)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (15 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 16 of 24] libxl: use libxl__wait_for_offspring for device model Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-25 15:31   ` Ian Jackson
  2011-10-03 15:54 ` [PATCH 18 of 24] libxl: use libxl__spawn_confirm_offspring_startup for device model Olaf Hering
                   ` (7 subsequent siblings)
  24 siblings, 1 reply; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653616 -7200
# Node ID 018f63b6e4863faca16a832a5a34c6a6e7726cf7
# Parent  35ec0355b3283a87477c7377a2fd3da5e84d2bcd
libxl: add libxl__spawn_confirm_offspring_startup

libxl__spawn_confirm_offspring_startup() is a generic version of
libxl__confirm_device_model_startup().

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 35ec0355b328 -r 018f63b6e486 tools/libxl/libxl_exec.c
--- a/tools/libxl/libxl_exec.c
+++ b/tools/libxl/libxl_exec.c
@@ -262,6 +262,30 @@ err:
     return -1;
 }
 
+static int detach_offspring(libxl__gc *gc,
+                               libxl__spawner_starting *starting)
+{
+    int rc;
+    rc = libxl__spawn_detach(gc, starting->for_spawn);
+    if (starting->for_spawn)
+        free(starting->for_spawn);
+    free(starting);
+    return rc;
+}
+
+int libxl__spawn_confirm_offspring_startup(libxl__gc *gc,
+                                       uint32_t timeout, char *what,
+                                       char *path, char *state,
+                                       libxl__spawner_starting *starting)
+{
+    int detach;
+    int problem = libxl__wait_for_offspring(gc, starting->domid, timeout, what,
+                                               path, state,
+                                               starting->for_spawn, NULL, NULL);
+    detach = detach_offspring(gc, starting);
+    return problem ? problem : detach;
+}
+
 static int libxl__set_fd_flag(libxl__gc *gc, int fd, int flag)
 {
     int flags;
diff -r 35ec0355b328 -r 018f63b6e486 tools/libxl/libxl_internal.h
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -313,6 +313,12 @@ _hidden int libxl__wait_for_offspring(li
                                                        const char *state,
                                                        void *userdata),
                                  void *check_callback_userdata);
+
+_hidden int libxl__spawn_confirm_offspring_startup(libxl__gc *gc,
+                                       uint32_t timeout, char *what,
+                                       char *path, char *state,
+                                       libxl__spawner_starting *starting);
+
   /* Logs errors.  A copy of "what" is taken.  Return values:
    *  < 0   error, for_spawn need not be detached
    *   +1   caller is the parent, must call detach on *for_spawn eventually

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 18 of 24] libxl: use libxl__spawn_confirm_offspring_startup for device model
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (16 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 19 of 24] xenpaging: install into LIBEXEC dir Olaf Hering
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653617 -7200
# Node ID acc1ee9d0c10a961834029726d11227c2ff9e97b
# Parent  018f63b6e4863faca16a832a5a34c6a6e7726cf7
libxl: use libxl__spawn_confirm_offspring_startup for device model

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 018f63b6e486 -r acc1ee9d0c10 tools/libxl/libxl_dm.c
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -890,25 +890,16 @@ out:
     return rc;
 }
 
-static int detach_device_model(libxl__gc *gc,
-                               libxl__spawner_starting *starting)
-{
-    int rc;
-    rc = libxl__spawn_detach(gc, starting->for_spawn);
-    if (starting->for_spawn)
-        free(starting->for_spawn);
-    free(starting);
-    return rc;
-}
 
 int libxl__confirm_device_model_startup(libxl__gc *gc,
                                        libxl__spawner_starting *starting)
 {
-    int detach;
-    int problem = libxl__wait_for_device_model(gc, starting->domid, "running",
-                                               starting->for_spawn, NULL, NULL);
-    detach = detach_device_model(gc, starting);
-    return problem ? problem : detach;
+    char *path;
+    int domid = starting->domid;
+    path = libxl__sprintf(gc, "/local/domain/0/device-model/%d/state", domid);
+    return libxl__spawn_confirm_offspring_startup(gc,
+                                     LIBXL_DEVICE_MODEL_START_TIMEOUT,
+                                     "Device Model", path, "running", starting);
 }
 
 int libxl__destroy_device_model(libxl__gc *gc, uint32_t domid)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 19 of 24] xenpaging: install into LIBEXEC dir
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (17 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 18 of 24] libxl: use libxl__spawn_confirm_offspring_startup for device model Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 20 of 24] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() Olaf Hering
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653619 -7200
# Node ID f9b5da9bcffdd96dcae4a26ead0b9c26507711e4
# Parent  acc1ee9d0c10a961834029726d11227c2ff9e97b
xenpaging: install into LIBEXEC dir

In preparation of upcoming libxl integration,
move xenpaging binary from /usr/sbin/ to /usr/lib/xen/bin/

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r acc1ee9d0c10 -r f9b5da9bcffd tools/xenpaging/Makefile
--- a/tools/xenpaging/Makefile
+++ b/tools/xenpaging/Makefile
@@ -24,8 +24,8 @@ xenpaging: $(OBJS)
 
 install: all
 	$(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging
-	$(INSTALL_DIR) $(DESTDIR)$(SBINDIR)
-	$(INSTALL_PROG) $(IBINS) $(DESTDIR)$(SBINDIR)
+	$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)
+	$(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC)
 
 clean:
 	rm -f *.o *~ $(DEPS) xen TAGS $(IBINS) $(LIB)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 20 of 24] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (18 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 19 of 24] xenpaging: install into LIBEXEC dir Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 21 of 24] xenpaging: use guests tot_pages as working target Olaf Hering
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653620 -7200
# Node ID 916749c1775b4435629c747afa4b38c8cbb7dd5b
# Parent  f9b5da9bcffdd96dcae4a26ead0b9c26507711e4
xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path()

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r f9b5da9bcffd -r 916749c1775b Config.mk
--- a/Config.mk
+++ b/Config.mk
@@ -138,7 +138,7 @@ define buildmakevars2file-closure
 	$(foreach var,                                                      \
 	          SBINDIR BINDIR LIBEXEC LIBDIR SHAREDIR PRIVATE_BINDIR     \
 	          XENFIRMWAREDIR XEN_CONFIG_DIR XEN_SCRIPT_DIR XEN_LOCK_DIR \
-	          XEN_RUN_DIR,                                              \
+	          XEN_RUN_DIR XEN_PAGING_DIR,                               \
 	          echo "$(var)=\"$($(var))\"" >>$(1).tmp;)        \
 	$(call move-if-changed,$(1).tmp,$(1))
 endef
diff -r f9b5da9bcffd -r 916749c1775b config/StdGNU.mk
--- a/config/StdGNU.mk
+++ b/config/StdGNU.mk
@@ -53,10 +53,12 @@ ifeq ($(PREFIX),/usr)
 CONFIG_DIR = /etc
 XEN_LOCK_DIR = /var/lock
 XEN_RUN_DIR = /var/run/xen
+XEN_PAGING_DIR = /var/lib/xen/xenpaging
 else
 CONFIG_DIR = $(PREFIX)/etc
 XEN_LOCK_DIR = $(PREFIX)/var/lock
 XEN_RUN_DIR = $(PREFIX)/var/run/xen
+XEN_PAGING_DIR = $(PREFIX)/var/lib/xen/xenpaging
 endif
 
 SYSCONFIG_DIR = $(CONFIG_DIR)/$(CONFIG_LEAF_DIR)
diff -r f9b5da9bcffd -r 916749c1775b tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -538,6 +538,7 @@ const char *libxl_xen_config_dir_path(vo
 const char *libxl_xen_script_dir_path(void);
 const char *libxl_lock_dir_path(void);
 const char *libxl_run_dir_path(void);
+const char *libxl_xenpaging_dir_path(void);
 
 #endif /* LIBXL_H */
 
diff -r f9b5da9bcffd -r 916749c1775b tools/libxl/libxl_paths.c
--- a/tools/libxl/libxl_paths.c
+++ b/tools/libxl/libxl_paths.c
@@ -69,3 +69,8 @@ const char *libxl_run_dir_path(void)
 {
     return XEN_RUN_DIR;
 }
+
+const char *libxl_xenpaging_dir_path(void)
+{
+    return XEN_PAGING_DIR;
+}
diff -r f9b5da9bcffd -r 916749c1775b tools/xenpaging/Makefile
--- a/tools/xenpaging/Makefile
+++ b/tools/xenpaging/Makefile
@@ -23,7 +23,7 @@ xenpaging: $(OBJS)
 	$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS)
 
 install: all
-	$(INSTALL_DIR) $(DESTDIR)/var/lib/xen/xenpaging
+	$(INSTALL_DIR) $(DESTDIR)$(XEN_PAGING_DIR)
 	$(INSTALL_DIR) $(DESTDIR)$(LIBEXEC)
 	$(INSTALL_PROG) $(IBINS) $(DESTDIR)$(LIBEXEC)

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 21 of 24] xenpaging: use guests tot_pages as working target
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (19 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 20 of 24] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:54 ` [PATCH 22 of 24] xenpaging: watch the guests memory/target-tot_pages xenstore value Olaf Hering
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317653622 -7200
# Node ID 8fa2067ed61105a0ae31939f0ca58b8921fc55d4
# Parent  916749c1775b4435629c747afa4b38c8cbb7dd5b
xenpaging: use guests tot_pages as working target

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/policy_default.c
--- a/tools/xenpaging/policy_default.c
+++ b/tools/xenpaging/policy_default.c
@@ -71,7 +71,6 @@ 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;
 
     rc = 0;
  out:
diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -137,6 +137,21 @@ err:
     return rc;
 }
 
+static int xenpaging_get_tot_pages(xenpaging_t *paging)
+{
+    xc_interface *xch = paging->xc_handle;
+    xc_domaininfo_t domain_info;
+    int rc;
+
+    rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1, &domain_info);
+    if ( rc != 1 )
+    {
+        PERROR("Error getting domain info");
+        return -1;
+    }
+    return domain_info.tot_pages;
+}
+
 static void *init_page(void)
 {
     void *buffer;
@@ -162,7 +177,7 @@ static void *init_page(void)
     return NULL;
 }
 
-static xenpaging_t *xenpaging_init(domid_t domain_id, int num_pages)
+static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages)
 {
     xenpaging_t *paging;
     xc_domaininfo_t domain_info;
@@ -294,12 +309,7 @@ static xenpaging_t *xenpaging_init(domid
     }
     DPRINTF("max_pages = %d\n", paging->max_pages);
 
-    if ( num_pages < 0 || num_pages > paging->max_pages )
-    {
-        num_pages = paging->max_pages;
-        DPRINTF("setting num_pages to %d\n", num_pages);
-    }
-    paging->num_pages = num_pages;
+    paging->target_tot_pages = target_tot_pages;
 
     /* Initialise policy */
     rc = policy_init(paging);
@@ -649,7 +659,9 @@ 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 tot_pages;
     int rc = -1;
     int rc1;
     xc_interface *xch;
@@ -660,7 +672,7 @@ int main(int argc, char *argv[])
 
     if ( argc != 3 )
     {
-        fprintf(stderr, "Usage: %s <domain_id> <num_pages>\n", argv[0]);
+        fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]);
         return -1;
     }
 
@@ -673,7 +685,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_tot_pages);
 
     /* Open file */
     sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
@@ -705,9 +717,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 )
     {
@@ -772,12 +781,8 @@ int main(int argc, char *argv[])
                     goto out;
                 }
 
-                /* Evict a new page to replace the one we just paged in,
-                 * or clear this pagefile slot on exit */
-                if ( interrupted )
-                    victims[i].gfn = INVALID_MFN;
-                else
-                    evict_victim(paging, &victims[i], fd, i);
+                /* Clear this pagefile slot */
+                victims[i].gfn = INVALID_MFN;
             }
             else
             {
@@ -822,6 +827,43 @@ int main(int argc, char *argv[])
         if ( interrupted )
             break;
 
+        /* Check if the target has been reached already */
+        tot_pages = xenpaging_get_tot_pages(paging);
+        if ( tot_pages < 0 )
+            goto out;
+
+        /* Resume all pages if paging is disabled or no target was set */
+        if ( paging->target_tot_pages == 0 )
+        {
+            if ( paging->num_paged_out )
+                resume_pages(paging, paging->num_paged_out);
+        }
+        /* Evict more pages if target not reached */
+        else if ( tot_pages > paging->target_tot_pages )
+        {
+            num = tot_pages - paging->target_tot_pages;
+            if ( num != prev_num )
+            {
+                DPRINTF("Need to evict %d pages to reach %d target_tot_pages\n", num, paging->target_tot_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);
+        }
+        /* Resume some pages if target not reached */
+        else if ( tot_pages < paging->target_tot_pages && paging->num_paged_out )
+        {
+            num = paging->target_tot_pages - tot_pages;
+            if ( num != prev_num )
+            {
+                DPRINTF("Need to resume %d pages to reach %d target_tot_pages\n", num, paging->target_tot_pages);
+                prev_num = num;
+            }
+            resume_pages(paging, num);
+        }
+
     }
     DPRINTF("xenpaging got signal %d\n", interrupted);
 
diff -r 916749c1775b -r 8fa2067ed611 tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -50,7 +50,7 @@ typedef struct xenpaging {
     /* number of pages for which data structures were allocated */
     int max_pages;
     int num_paged_out;
-    int num_pages;
+    int target_tot_pages;
     int policy_mru_size;
     unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
 } xenpaging_t;

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 22 of 24] xenpaging: watch the guests memory/target-tot_pages xenstore value
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (20 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 21 of 24] xenpaging: use guests tot_pages as working target Olaf Hering
@ 2011-10-03 15:54 ` Olaf Hering
  2011-10-03 15:55 ` [PATCH 23 of 24] xenpaging: add cmdline interface for pager Olaf Hering
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:54 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317656685 -7200
# Node ID 59303aeb11d96c5c94da2e9feb2ef9728236f90d
# Parent  8fa2067ed61105a0ae31939f0ca58b8921fc55d4
xenpaging: watch the guests memory/target-tot_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@aepfle.de>

diff -r 8fa2067ed611 -r 59303aeb11d9 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -19,8 +19,10 @@
  */
 
 #define _XOPEN_SOURCE	600
+#define _GNU_SOURCE
 
 #include <inttypes.h>
+#include <stdio.h>
 #include <stdlib.h>
 #include <stdarg.h>
 #include <time.h>
@@ -35,6 +37,10 @@
 #include "policy.h"
 #include "xenpaging.h"
 
+/* Defines number of mfns a guest should use at a time, in KiB */
+#define WATCH_TARGETPAGES "memory/target-tot_pages"
+static char *watch_target_tot_pages;
+static char *dom_path;
 static char watch_token[16];
 static char filename[80];
 static int interrupted;
@@ -72,7 +78,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;
@@ -112,6 +118,25 @@ static int xenpaging_wait_for_event_or_t
                     rc = 0;
                 }
             }
+            else if ( strcmp(vec[XS_WATCH_PATH], watch_target_tot_pages) == 0 )
+            {
+                int ret, target_tot_pages;
+                val = xs_read(paging->xs_handle, XBT_NULL, vec[XS_WATCH_PATH], NULL);
+                if ( val )
+                {
+                    ret = sscanf(val, "%d", &target_tot_pages);
+                    if ( ret > 0 )
+                    {
+                        /* KiB to pages */
+                        target_tot_pages >>= 2;
+                        if ( target_tot_pages < 0 || target_tot_pages > paging->max_pages )
+                            target_tot_pages = paging->max_pages;
+                        paging->target_tot_pages = target_tot_pages;
+                        DPRINTF("new target_tot_pages %d\n", target_tot_pages);
+                    }
+                    free(val);
+                }
+            }
             free(vec);
         }
     }
@@ -217,6 +242,25 @@ 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 )
+    {
+        PERROR("Could not find domain path\n");
+        goto err;
+    }
+    if ( asprintf(&watch_target_tot_pages, "%s/%s", dom_path, WATCH_TARGETPAGES) < 0 )
+    {
+        PERROR("Could not alloc watch path\n");
+        goto err;
+    }
+    DPRINTF("watching '%s'\n", watch_target_tot_pages);
+    if ( xs_watch(paging->xs_handle, watch_target_tot_pages, "") == false )
+    {
+        PERROR("Could not bind to xenpaging watch\n");
+        goto err;
+    }
+
     p = getenv("XENPAGING_POLICY_MRU_SIZE");
     if ( p && *p )
     {
@@ -340,6 +384,8 @@ static xenpaging_t *xenpaging_init(domid
             free(paging->mem_event.ring_page);
         }
 
+        free(dom_path);
+        free(watch_target_tot_pages);
         free(paging->bitmap);
         free(paging);
     }
@@ -355,6 +401,9 @@ static int xenpaging_teardown(xenpaging_
     if ( paging == NULL )
         return 0;
 
+    xs_unwatch(paging->xs_handle, watch_target_tot_pages, "");
+    xs_unwatch(paging->xs_handle, "@releaseDomain", watch_token);
+
     xch = paging->xc_handle;
     paging->xc_handle = NULL;
     /* Tear down domain paging in Xen */

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 23 of 24] xenpaging: add cmdline interface for pager
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (21 preceding siblings ...)
  2011-10-03 15:54 ` [PATCH 22 of 24] xenpaging: watch the guests memory/target-tot_pages xenstore value Olaf Hering
@ 2011-10-03 15:55 ` Olaf Hering
  2011-10-03 15:55 ` [PATCH 24 of 24] xenpaging: libxl support Olaf Hering
  2011-10-04  9:51 ` [PATCH 00 of 24] xenpaging fixes for xen-unstable Ian Campbell
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:55 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317656694 -7200
# Node ID 5dd8e13e8222486bc09894dc3245c28a7e654d0a
# Parent  59303aeb11d96c5c94da2e9feb2ef9728236f90d
xenpaging: add cmdline interface for pager

Introduce a cmdline handling for the pager. This simplifies libxl support,
debug and mru_size are not passed via the environment anymore.
The new interface looks like this:

xenpaging [options] -f <pagefile> <domain_id>
options:
 -f <file>      --pagefile=<file>        pagefile to use. This option is required.
 -m <max_memkb> --max_memkb=<max_memkb>  maximum amount of memory to handle.
 -r <num>       --mru_size=<num>         number of paged-in pages to keep in memory.
 -d             --debug                  enable debug output.
 -h             --help                   this output.


Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 59303aeb11d9 -r 5dd8e13e8222 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -31,6 +31,7 @@
 #include <poll.h>
 #include <xc_private.h>
 #include <xs.h>
+#include <getopt.h>
 
 #include "xc_bitops.h"
 #include "file_ops.h"
@@ -42,12 +43,12 @@
 static char *watch_target_tot_pages;
 static char *dom_path;
 static char watch_token[16];
-static char filename[80];
+static char *filename;
 static int interrupted;
 
 static void unlink_pagefile(void)
 {
-    if ( filename[0] )
+    if ( filename && filename[0] )
     {
         unlink(filename);
         filename[0] = '\0';
@@ -202,11 +203,89 @@ static void *init_page(void)
     return NULL;
 }
 
-static xenpaging_t *xenpaging_init(domid_t domain_id, int target_tot_pages)
+static void usage(void)
+{
+    printf("usage:\n\n");
+
+    printf("  xenpaging [options] -f <pagefile> <domain_id>\n\n");
+
+    printf("options:\n");
+    printf(" -f <file>      --pagefile=<file>        pagefile to use. This option is required.\n");
+    printf(" -m <max_memkb> --max_memkb=<max_memkb>  maximum amount of memory to handle.\n");
+    printf(" -r <num>       --mru_size=<num>         number of paged-in pages to keep in memory.\n");
+    printf(" -d             --debug                  enable debug output.\n");
+    printf(" -h             --help                   this output.\n");
+}
+
+static int xenpaging_getopts(xenpaging_t *paging, int argc, char *argv[])
+{
+    int ch;
+    static const char sopts[] = "hdf:m:r:";
+    static const struct option lopts[] = {
+        {"help", 0, NULL, 'h'},
+        {"debug", 0, NULL, 'd'},
+        {"pagefile", 1, NULL, 'f'},
+        {"mru_size", 1, NULL, 'm'},
+        { }
+    };
+
+    while ((ch = getopt_long(argc, argv, sopts, lopts, NULL)) != -1)
+    {
+        switch(ch) {
+        case 'f':
+            filename = strdup(optarg);
+            break;
+        case 'm':
+            /* KiB to pages */
+            paging->max_pages = atoi(optarg) >> 2;
+            break;
+        case 'r':
+            paging->policy_mru_size = atoi(optarg);
+            break;
+        case 'd':
+            paging->debug = 1;
+            break;
+        case 'h':
+        case '?':
+            usage();
+            return 1;
+        }
+    }
+
+    argv += optind; argc -= optind;
+
+    /* Remaining argument is guest domain_id */
+    if ( argc != 1 )
+    {
+        printf("Numerical <domain_id> value missing!\n");
+        usage();
+        return 1;
+    }
+    
+    /* Path to pagefile is required */
+    if ( !filename )
+    {
+        printf("Filename for pagefile missing!\n");
+        usage();
+        return 1;
+    }
+
+    /* Set domain id */
+    paging->mem_event.domain_id = atoi(argv[0]);
+    if ( paging->mem_event.domain_id == 0 )
+    {
+        printf("Cannot page dom0!\n");
+        return 1;
+    }
+
+    return 0;
+}
+
+static xenpaging_t *xenpaging_init(int argc, char *argv[])
 {
     xenpaging_t *paging;
     xc_domaininfo_t domain_info;
-    xc_interface *xch;
+    xc_interface *xch = NULL;
     xentoollog_logger *dbg = NULL;
     char *p;
     int rc;
@@ -216,7 +295,12 @@ static xenpaging_t *xenpaging_init(domid
     if ( !paging )
         goto err;
 
-    if ( getenv("XENPAGING_DEBUG") )
+    /* Get cmdline options and domain_id */
+    if ( xenpaging_getopts(paging, argc, argv) )
+        goto err;
+
+    /* Enable debug output */
+    if ( paging->debug )
         dbg = (xentoollog_logger *)xtl_createlogger_stdiostream(stderr, XTL_DEBUG, 0);
 
     /* Open connection to xen */
@@ -235,7 +319,7 @@ static xenpaging_t *xenpaging_init(domid
     }
 
     /* write domain ID to watch so we can ignore other domain shutdowns */
-    snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
+    snprintf(watch_token, sizeof(watch_token), "%u", paging->mem_event.domain_id);
     if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
     {
         PERROR("Could not bind to shutdown watch\n");
@@ -243,7 +327,7 @@ static xenpaging_t *xenpaging_init(domid
     }
 
     /* watch guests xenpaging directory */
-    dom_path = xs_get_domain_path(paging->xs_handle, domain_id);
+    dom_path = xs_get_domain_path(paging->xs_handle, paging->mem_event.domain_id);
     if ( !dom_path )
     {
         PERROR("Could not find domain path\n");
@@ -261,16 +345,6 @@ static xenpaging_t *xenpaging_init(domid
         goto err;
     }
 
-    p = getenv("XENPAGING_POLICY_MRU_SIZE");
-    if ( p && *p )
-    {
-         paging->policy_mru_size = atoi(p);
-         DPRINTF("Setting policy mru_size to %d\n", paging->policy_mru_size);
-    }
-
-    /* Set domain id */
-    paging->mem_event.domain_id = domain_id;
-
     /* Initialise shared page */
     paging->mem_event.shared_page = init_page();
     if ( paging->mem_event.shared_page == NULL )
@@ -333,17 +407,21 @@ static xenpaging_t *xenpaging_init(domid
 
     paging->mem_event.port = rc;
 
-    rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
-                               &domain_info);
-    if ( rc != 1 )
+    /* Get max_pages from guest if not provided via cmdline */
+    if ( !paging->max_pages )
     {
-        PERROR("Error getting domain info");
-        goto err;
+        rc = xc_domain_getinfolist(xch, paging->mem_event.domain_id, 1,
+                                   &domain_info);
+        if ( rc != 1 )
+        {
+            PERROR("Error getting domain info");
+            goto err;
+        }
+
+        /* Record number of max_pages */
+        paging->max_pages = domain_info.max_pages;
     }
 
-    /* Record number of max_pages */
-    paging->max_pages = domain_info.max_pages;
-
     /* Allocate bitmap for tracking pages that have been paged out */
     paging->bitmap = bitmap_alloc(paging->max_pages);
     if ( !paging->bitmap )
@@ -353,8 +431,6 @@ static xenpaging_t *xenpaging_init(domid
     }
     DPRINTF("max_pages = %d\n", paging->max_pages);
 
-    paging->target_tot_pages = target_tot_pages;
-
     /* Initialise policy */
     rc = policy_init(paging);
     if ( rc != 0 )
@@ -719,25 +795,18 @@ int main(int argc, char *argv[])
     mode_t open_mode = S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
     int fd;
 
-    if ( argc != 3 )
-    {
-        fprintf(stderr, "Usage: %s <domain_id> <tot_pages>\n", argv[0]);
-        return -1;
-    }
-
     /* Initialise domain paging */
-    paging = xenpaging_init(atoi(argv[1]), atoi(argv[2]));
+    paging = xenpaging_init(argc, argv);
     if ( paging == NULL )
     {
-        fprintf(stderr, "Error initialising paging");
+        fprintf(stderr, "Error initialising paging\n");
         return 1;
     }
     xch = paging->xc_handle;
 
-    DPRINTF("starting %s %u %d\n", argv[0], paging->mem_event.domain_id, paging->target_tot_pages);
+    DPRINTF("starting %s for domain_id %u with pagefile %s\n", argv[0], paging->mem_event.domain_id, filename);
 
     /* Open file */
-    sprintf(filename, "page_cache_%u", paging->mem_event.domain_id);
     fd = open(filename, open_flags, open_mode);
     if ( fd < 0 )
     {
diff -r 59303aeb11d9 -r 5dd8e13e8222 tools/xenpaging/xenpaging.h
--- a/tools/xenpaging/xenpaging.h
+++ b/tools/xenpaging/xenpaging.h
@@ -52,6 +52,7 @@ typedef struct xenpaging {
     int num_paged_out;
     int target_tot_pages;
     int policy_mru_size;
+    int debug;
     unsigned long pagein_queue[XENPAGING_PAGEIN_QUEUE_SIZE];
 } xenpaging_t;

^ permalink raw reply	[flat|nested] 37+ messages in thread

* [PATCH 24 of 24] xenpaging: libxl support
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (22 preceding siblings ...)
  2011-10-03 15:55 ` [PATCH 23 of 24] xenpaging: add cmdline interface for pager Olaf Hering
@ 2011-10-03 15:55 ` Olaf Hering
  2011-10-04  9:51 ` [PATCH 00 of 24] xenpaging fixes for xen-unstable Ian Campbell
  24 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-03 15:55 UTC (permalink / raw)
  To: xen-devel

# HG changeset patch
# User Olaf Hering <olaf@aepfle.de>
# Date 1317656695 -7200
# Node ID c37a41cf0bf05f183a9b167f307591ec69e770e4
# Parent  5dd8e13e8222486bc09894dc3245c28a7e654d0a
xenpaging: libxl support

Add support to libxl for starting xenpaging.
Its a huge patch and should be spit into totmem= and the actual xenpaging
change.

The patch adds three new config options:
totmem=<int> , the number of pages
xenpaging_file=<string>, pagefile to use
xenpaging_extra=[ 'string', 'string' ], additional optional args for xenpaging

xl gets a new 'mem-tot_pages' command which modifies xenstore
"memory/target-tot_pages" to notify the pager of a new target number and it
instructs the xl monitor process to start the pager if the totmem= option was
not in the config file.

Signed-off-by: Olaf Hering <olaf@aepfle.de>

diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.c
--- a/tools/libxl/libxl.c
+++ b/tools/libxl/libxl.c
@@ -626,6 +626,21 @@ out:
     return rc;
 }
 
+int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    int rc = -1;
+    if (asprintf(&waiter->path, "%s/memory/target-tot_pages", libxl__xs_get_dompath(&gc, domid)) < 0)
+        goto out;
+    if (asprintf(&waiter->token, "%d", LIBXL_EVENT_TYPE_XENPAGING) < 0)
+        goto out;
+    if (xs_watch(ctx->xsh, waiter->path, waiter->token) == true)
+        rc = 0;
+out:
+    libxl__free_all(&gc);
+    return rc;
+}
+
 int libxl_get_event(libxl_ctx *ctx, libxl_event *event)
 {
     unsigned int num;
@@ -2035,6 +2050,112 @@ out:
     return rc;
 }
 
+int libxl_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid,
+        int32_t tot_pages_memkb, int relative)
+{
+    libxl__gc gc;
+    int rc, abort = 0;
+    uint32_t memorykb, videoram;
+    uint32_t current_target_memkb = 0;
+    uint32_t current_tot_pages_memkb, new_tot_pages_memkb;
+    char *memmax, *endptr, *videoram_s, *target, *tot_pages;
+    char *dompath;
+    xs_transaction_t t;
+
+    if (domid == 0) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "cannot set tot_pages for dom0.\n");
+        return ERROR_INVAL;
+    }
+
+    gc = LIBXL_INIT_GC(ctx);
+    dompath = libxl__xs_get_dompath(&gc, domid);
+
+retry_transaction:
+    rc = 1;
+    t = xs_transaction_start(ctx->xsh);
+
+    target = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+                "%s/memory/target", dompath));
+    if (!target) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                "cannot get target memory info from %s/memory/target\n",
+                dompath);
+        abort = 1;
+        goto out;
+    } else {
+        current_target_memkb = strtoul(target, &endptr, 10);
+        if (*endptr != '\0') {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                    "invalid memory target %s from %s/memory/target\n",
+                    target, dompath);
+            abort = 1;
+            goto out;
+        }
+    }
+
+    videoram_s = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+                "%s/memory/videoram", dompath));
+    videoram = videoram_s ? atoi(videoram_s) : 0;
+
+    current_tot_pages_memkb = current_target_memkb + videoram;
+    tot_pages = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+                "%s/memory/target-tot_pages", dompath));
+    if (tot_pages) {
+        current_tot_pages_memkb = strtoul(tot_pages, &endptr, 10);
+        if (*endptr != '\0') {
+            LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                    "invalid tot_pages %s from %s/memory/target-tot_pages\n",
+                    tot_pages, dompath);
+            abort = 1;
+            goto out;
+        }
+    }
+    memmax = libxl__xs_read(&gc, t, libxl__sprintf(&gc,
+                "%s/memory/static-max", dompath));
+    if (!memmax) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                "cannot get memory info from %s/memory/static-max\n",
+                dompath);
+        abort = 1;
+        goto out;
+    }
+    memorykb = strtoul(memmax, &endptr, 10);
+    if (*endptr != '\0') {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR,
+                "invalid max memory %s from %s/memory/static-max\n",
+                memmax, dompath);
+        abort = 1;
+        goto out;
+    }
+
+    if (relative) {
+        if (tot_pages_memkb < 0 && abs(tot_pages_memkb) > current_tot_pages_memkb)
+            new_tot_pages_memkb = 0;
+        else
+            new_tot_pages_memkb = current_tot_pages_memkb + tot_pages_memkb;
+    } else
+        new_tot_pages_memkb = tot_pages_memkb;
+    if (new_tot_pages_memkb > memorykb) {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR,
+                "memory_dynamic_max must be less than or equal to"
+                " memory_static_max\n");
+        abort = 1;
+        goto out;
+    }
+
+    libxl__xs_write(&gc, t, libxl__sprintf(&gc, "%s/memory/target-tot_pages",
+                dompath), "%"PRIu32, new_tot_pages_memkb);
+
+    rc = 0;
+out:
+    if (!xs_transaction_end(ctx->xsh, t, abort) && !abort)
+        if (errno == EAGAIN)
+            goto retry_transaction;
+
+    libxl__free_all(&gc);
+    return rc;
+}
+
 int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
         libxl_device_model_info *dm_info, uint32_t *need_memkb)
 {
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl.h
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -261,6 +261,7 @@ int libxl_init_dm_info(libxl_ctx *ctx,
 typedef int (*libxl_console_ready)(libxl_ctx *ctx, uint32_t domid, void *priv);
 int libxl_domain_create_new(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid);
 int libxl_domain_create_restore(libxl_ctx *ctx, libxl_domain_config *d_config, libxl_console_ready cb, void *priv, uint32_t *domid, int restore_fd);
+int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config, uint32_t domid, char *path);
 void libxl_domain_config_destroy(libxl_domain_config *d_config);
 int libxl_domain_suspend(libxl_ctx *ctx, libxl_domain_suspend_info *info,
                           uint32_t domid, int fd);
@@ -312,6 +313,8 @@ int libxl_get_wait_fd(libxl_ctx *ctx, in
 int libxl_wait_for_domain_death(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter);
 /* waiter is a preallocated array of num_disks libxl_waiter elements */
 int libxl_wait_for_disk_ejects(libxl_ctx *ctx, uint32_t domid, libxl_device_disk *disks, int num_disks, libxl_waiter *waiter);
+/* waiter is allocated by the caller */
+int libxl_wait_for_target_tot_pages(libxl_ctx *ctx, uint32_t domid, libxl_waiter *waiter);
 int libxl_get_event(libxl_ctx *ctx, libxl_event *event);
 int libxl_stop_waiting(libxl_ctx *ctx, libxl_waiter *waiter);
 int libxl_free_event(libxl_event *event);
@@ -352,6 +355,7 @@ int libxl_domain_core_dump(libxl_ctx *ct
 int libxl_domain_setmaxmem(libxl_ctx *ctx, uint32_t domid, uint32_t target_memkb);
 int libxl_set_memory_target(libxl_ctx *ctx, uint32_t domid, int32_t target_memkb, int relative, int enforce);
 int libxl_get_memory_target(libxl_ctx *ctx, uint32_t domid, uint32_t *out_target);
+int libxl_set_memory_tot_pages(libxl_ctx *ctx, uint32_t domid, int32_t tot_pages_memkb, int relative);
 /* how much free memory in the system a domain needs to be built */
 int libxl_domain_need_memory(libxl_ctx *ctx, libxl_domain_build_info *b_info,
         libxl_device_model_info *dm_info, uint32_t *need_memkb);
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_create.c
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -429,6 +429,121 @@ retry_transaction:
     return rc;
 }
 
+static int create_xenpaging(libxl__gc *gc, char *dom_name, uint32_t domid,
+                            libxl_domain_build_info *b_info)
+{
+    libxl__spawner_starting *buf_starting;
+    libxl_string_list xpe = b_info->u.hvm.xenpaging_extra;
+    int i, rc;
+    char *logfile;
+    int logfile_w, null;
+    char *path, *dom_path, *value;
+    char **args;
+    char *xp;
+    flexarray_t *xp_args;
+    libxl_ctx *ctx = libxl__gc_owner(gc);
+
+    /* Nothing to do */
+    if (b_info->target_memkb == b_info->tot_memkb)
+        return 0;
+
+    /* Check if paging is already enabled */
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    if (!dom_path ) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+    path = libxl__sprintf(gc, "%s/xenpaging/state", dom_path);
+    if (!path ) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+    value = xs_read(ctx->xsh, XBT_NULL, path, NULL);
+    rc = value && strcmp(value, "running") == 0;
+    free(value);
+    /* Already running, nothing to do */
+    if (rc)
+        return 0;
+
+    /* Check if xenpaging is present */
+    xp = libxl__abs_path(gc, "xenpaging", libxl_libexec_path());
+    if (access(xp, X_OK) < 0) {
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "%s is not executable", xp);
+        rc = ERROR_FAIL;
+        goto out;
+    }
+
+    /* Initialise settings for child */
+    buf_starting = calloc(sizeof(*buf_starting), 1);
+    if (!buf_starting) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+    buf_starting->domid = domid;
+    buf_starting->for_spawn = calloc(sizeof(libxl__spawn_starting), 1);
+    buf_starting->dom_path = dom_path;
+    buf_starting->pid_path = "xenpaging/xenpaging-pid";
+    if (!buf_starting->for_spawn) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+
+    /* Assemble arguments for xenpaging */
+    xp_args = flexarray_make(5, 1);
+    if (!xp_args) {
+        rc = ERROR_NOMEM;
+        goto out;
+    }
+    /* Set executable path */
+    flexarray_append(xp_args, xp);
+
+    /* Append pagefile option */
+    flexarray_append(xp_args, "-f");
+    if (b_info->u.hvm.xenpaging_file)
+        flexarray_append(xp_args, b_info->u.hvm.xenpaging_file);
+    else
+        flexarray_append(xp_args, libxl__sprintf(gc, "%s/%s.%u.paging",
+                         libxl_xenpaging_dir_path(), dom_name, domid));
+
+    /* Set maximum amount of memory xenpaging should handle */
+    flexarray_append(xp_args, "-m");
+    flexarray_append(xp_args, libxl__sprintf(gc, "%d", b_info->max_memkb));
+
+    /* Append extra args for pager */
+    for (i = 0; xpe && xpe[i]; i++)
+        flexarray_append(xp_args, xpe[i]);
+    /* Append domid for pager */
+    flexarray_append(xp_args, libxl__sprintf(gc, "%u", domid));
+    flexarray_append(xp_args, NULL);
+    args = (char **) flexarray_contents(xp_args);
+
+    /* Initialise logfile */
+    libxl_create_logfile(ctx, libxl__sprintf(gc, "xenpaging-%s", dom_name),
+                         &logfile);
+    logfile_w = open(logfile, O_WRONLY|O_CREAT, 0644);
+    free(logfile);
+    null = open("/dev/null", O_RDONLY);
+
+    /* Spawn the child */
+    rc = libxl__spawn_spawn(gc, buf_starting->for_spawn, "xenpaging",
+                            libxl_spawner_record_pid, buf_starting);
+    if (rc < 0)
+        goto out_close;
+    if (!rc) { /* inner child */
+        setsid();
+        /* Finally run xenpaging */
+        libxl__exec(null, logfile_w, logfile_w, xp, args);
+    }
+    rc = libxl__spawn_confirm_offspring_startup(gc, 5, "xenpaging", path,
+                                                "running", buf_starting);
+out_close:
+    close(null);
+    close(logfile_w);
+    free(args);
+out:
+    return rc;
+}
+
 static int do_domain_create(libxl__gc *gc, libxl_domain_config *d_config,
                             libxl_console_ready cb, void *priv,
                             uint32_t *domid_out, int restore_fd)
@@ -641,3 +756,32 @@ int libxl_domain_create_restore(libxl_ct
     libxl__free_all(&gc);
     return rc;
 }
+
+int libxl__create_xenpaging(libxl_ctx *ctx, libxl_domain_config *d_config,
+                            uint32_t domid, char *path)
+{
+    libxl__gc gc = LIBXL_INIT_GC(ctx);
+    char *value, *endptr;
+    uint32_t new_tot_pages;
+    int rc;
+
+    if (d_config->c_info.type != LIBXL_DOMAIN_TYPE_HVM)
+        return 0;
+
+    value = xs_read(ctx->xsh, XBT_NULL, path, NULL);
+    if (!value)
+        return 0;
+    new_tot_pages = strtoul(value, &endptr, 10);
+    free(value);
+    if (*endptr != '\0') {
+        LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Invalid value in %s", path);
+        return 0;
+    }
+    d_config->b_info.tot_memkb = new_tot_pages;
+
+    rc = create_xenpaging(&gc, d_config->dm_info.dom_name, domid, &d_config->b_info);
+    if (rc < 0)
+        LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "failed to start xenpaging: %d", rc);
+    libxl__free_all(&gc);
+    return rc;
+}
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_dom.c
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -108,7 +108,7 @@ int libxl__build_post(libxl__gc *gc, uin
     if (info->cpuid != NULL)
         libxl_cpuid_set(ctx, domid, info->cpuid);
 
-    ents = libxl__calloc(gc, 12 + (info->max_vcpus * 2) + 2, sizeof(char *));
+    ents = libxl__calloc(gc, 14 + (info->max_vcpus * 2) + 2, sizeof(char *));
     ents[0] = "memory/static-max";
     ents[1] = libxl__sprintf(gc, "%d", info->max_memkb);
     ents[2] = "memory/target";
@@ -121,9 +121,11 @@ int libxl__build_post(libxl__gc *gc, uin
     ents[9] = libxl__sprintf(gc, "%"PRIu32, state->store_port);
     ents[10] = "store/ring-ref";
     ents[11] = libxl__sprintf(gc, "%lu", state->store_mfn);
+    ents[12] = "memory/target-tot_pages";
+    ents[13] = libxl__sprintf(gc, "%d", info->tot_memkb);
     for (i = 0; i < info->max_vcpus; i++) {
-        ents[12+(i*2)]   = libxl__sprintf(gc, "cpu/%d/availability", i);
-        ents[12+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i)))
+        ents[14+(i*2)]   = libxl__sprintf(gc, "cpu/%d/availability", i);
+        ents[14+(i*2)+1] = (i && info->cur_vcpus && !(info->cur_vcpus & (1 << i)))
                             ? "offline" : "online";
     }
 
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/libxl_types.idl
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -78,6 +78,7 @@ libxl_action_on_shutdown = Enumeration("
 libxl_event_type = Enumeration("event_type", [
     (1, "DOMAIN_DEATH"),
     (2, "DISK_EJECT"),
+    (3, "XENPAGING"),
     ])
 
 libxl_button = Enumeration("button", [
@@ -157,6 +158,7 @@ libxl_domain_build_info = Struct("domain
     ("tsc_mode",        integer),
     ("max_memkb",       uint32),
     ("target_memkb",    uint32),
+    ("tot_memkb",       uint32),
     ("video_memkb",     uint32),
     ("shadow_memkb",    uint32),
     ("disable_migrate", bool),
@@ -174,6 +176,8 @@ libxl_domain_build_info = Struct("domain
                                        ("vpt_align", bool),
                                        ("timer_mode", integer),
                                        ("nested_hvm", bool),
+                                       ("xenpaging_file", string),
+                                       ("xenpaging_extra", libxl_string_list),
                                        ])),
                  ("pv", Struct(None, [("kernel", libxl_file_reference),
                                       ("slack_memkb", uint32),
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl.h
--- a/tools/libxl/xl.h
+++ b/tools/libxl/xl.h
@@ -54,6 +54,7 @@ int main_vcpupin(int argc, char **argv);
 int main_vcpuset(int argc, char **argv);
 int main_memmax(int argc, char **argv);
 int main_memset(int argc, char **argv);
+int main_mem_tot_pages(int argc, char **argv);
 int main_sched_credit(int argc, char **argv);
 int main_domid(int argc, char **argv);
 int main_domname(int argc, char **argv);
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -346,6 +346,7 @@ static void printf_info(int domid,
         printf("\t\t\t(firmware %s)\n", b_info->u.hvm.firmware);
         printf("\t\t\t(video_memkb %d)\n", b_info->video_memkb);
         printf("\t\t\t(shadow_memkb %d)\n", b_info->shadow_memkb);
+        printf("\t\t\t(tot_memkb %d)\n", b_info->tot_memkb);
         printf("\t\t\t(pae %d)\n", b_info->u.hvm.pae);
         printf("\t\t\t(apic %d)\n", b_info->u.hvm.apic);
         printf("\t\t\t(acpi %d)\n", b_info->u.hvm.acpi);
@@ -380,6 +381,7 @@ static void printf_info(int domid,
         printf("\t\t\t(spicedisable_ticketing %d)\n",
                     dm_info->spicedisable_ticketing);
         printf("\t\t\t(spiceagent_mouse %d)\n", dm_info->spiceagent_mouse);
+        printf("\t\t\t(xenpaging_file %s)\n", b_info->u.hvm.xenpaging_file);
         printf("\t\t)\n");
         break;
     case LIBXL_DOMAIN_TYPE_PV:
@@ -515,6 +517,28 @@ static void parse_disk_config(XLU_Config
     parse_disk_config_multistring(config, 1, &spec, disk);
 }
 
+static void parse_xenpaging_extra(const XLU_Config *config, libxl_string_list *xpe)
+{
+    XLU_ConfigList *args;
+    libxl_string_list l;
+    const char *val;
+    int nr_args = 0, i;
+
+    if (xlu_cfg_get_list(config, "xenpaging_extra", &args, &nr_args, 1))
+        return;
+
+    l = xmalloc(sizeof(char*)*(nr_args + 1));
+    if (!l)
+        return;
+
+    l[nr_args] = NULL;
+    for (i = 0; i < nr_args; i++) {
+        val = xlu_cfg_get_listitem(args, i);
+        l[i] = val ? strdup(val) : NULL;
+    }
+    *xpe = l;
+}
+
 static void parse_config_data(const char *configfile_filename_report,
                               const char *configfile_data,
                               int configfile_len,
@@ -615,11 +639,15 @@ static void parse_config_data(const char
     if (!xlu_cfg_get_long (config, "memory", &l)) {
         b_info->max_memkb = l * 1024;
         b_info->target_memkb = b_info->max_memkb;
+        b_info->tot_memkb = b_info->max_memkb;
     }
 
     if (!xlu_cfg_get_long (config, "maxmem", &l))
         b_info->max_memkb = l * 1024;
 
+    if (!xlu_cfg_get_long (config, "totmem", &l))
+        b_info->tot_memkb = l * 1024;
+
     if (xlu_cfg_get_string (config, "on_poweroff", &buf))
         buf = "destroy";
     if (!parse_action_on_shutdown(buf, &d_config->on_poweroff)) {
@@ -695,6 +723,10 @@ static void parse_config_data(const char
             b_info->u.hvm.timer_mode = l;
         if (!xlu_cfg_get_long (config, "nestedhvm", &l))
             b_info->u.hvm.nested_hvm = l;
+
+        xlu_cfg_replace_string (config, "xenpaging_file", &b_info->u.hvm.xenpaging_file);
+        parse_xenpaging_extra(config, &b_info->u.hvm.xenpaging_extra);
+
         break;
     case LIBXL_DOMAIN_TYPE_PV:
     {
@@ -1356,7 +1388,7 @@ static int create_domain(struct domain_c
     int fd, i;
     int need_daemon = daemonize;
     int ret, rc;
-    libxl_waiter *w1 = NULL, *w2 = NULL;
+    libxl_waiter *w1 = NULL, *w2 = NULL, *w3;
     void *config_data = 0;
     int config_len = 0;
     int restore_fd = -1;
@@ -1606,8 +1638,10 @@ start:
         d_config.c_info.name, domid, (long)getpid());
     w1 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter) * d_config.num_disks);
     w2 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
+    w3 = (libxl_waiter*) xmalloc(sizeof(libxl_waiter));
     libxl_wait_for_disk_ejects(ctx, domid, d_config.disks, d_config.num_disks, w1);
     libxl_wait_for_domain_death(ctx, domid, w2);
+    libxl_wait_for_target_tot_pages(ctx, domid, w3);
     libxl_get_wait_fd(ctx, &fd);
     while (1) {
         int ret;
@@ -1649,8 +1683,10 @@ start:
                         for (i = 0; i < d_config.num_disks; i++)
                             libxl_free_waiter(&w1[i]);
                         libxl_free_waiter(w2);
+                        libxl_free_waiter(w3);
                         free(w1);
                         free(w2);
+                        free(w3);
 
                         /*
                          * Do not attempt to reconnect if we come round again due to a
@@ -1688,6 +1724,9 @@ start:
                     libxl_device_disk_destroy(&disk);
                 }
                 break;
+            case LIBXL_EVENT_TYPE_XENPAGING:
+                libxl__create_xenpaging(ctx, &d_config, domid, event.path);
+                break;
         }
         libxl_free_event(&event);
     }
@@ -1872,6 +1911,36 @@ int main_memset(int argc, char **argv)
     return 0;
 }
 
+static void set_memory_tot_pages(const char *p, const char *mem)
+{
+    long long int memorykb;
+
+    find_domain(p);
+
+    memorykb = parse_mem_size_kb(mem);
+    if (memorykb == -1)  {
+        fprintf(stderr, "invalid memory size: %s\n", mem);
+        exit(3);
+    }
+
+    libxl_set_memory_tot_pages(ctx, domid, memorykb, 0);
+}
+
+int main_mem_tot_pages(int argc, char **argv)
+{
+    int opt = 0;
+    const char *p = NULL, *mem;
+
+    if ((opt = def_getopt(argc, argv, "", "mem-totpages", 2)) != -1)
+        return opt;
+
+    p = argv[optind];
+    mem = argv[optind + 1];
+
+    set_memory_tot_pages(p, mem);
+    return 0;
+}
+
 static void cd_insert(const char *dom, const char *virtdev, char *phys)
 {
     libxl_device_disk disk; /* we don't free disk's contents */
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/libxl/xl_cmdtable.c
--- a/tools/libxl/xl_cmdtable.c
+++ b/tools/libxl/xl_cmdtable.c
@@ -158,6 +158,11 @@ struct cmd_spec cmd_table[] = {
       "Set the current memory usage for a domain",
       "<Domain> <MemMB['b'[bytes]|'k'[KB]|'m'[MB]|'g'[GB]|'t'[TB]]>",
     },
+    { "mem-totpages",
+      &main_mem_tot_pages, 0,
+      "Set the how much memory is assigned to a domain",
+      "<Domain> <MemMB['b'[bytes]|'k'[KB]|'m'[MB]|'g'[GB]|'t'[TB]]>",
+    },
     { "button-press",
       &main_button_press, 0,
       "Indicate an ACPI button press to the domain",
diff -r 5dd8e13e8222 -r c37a41cf0bf0 tools/xenpaging/xenpaging.c
--- a/tools/xenpaging/xenpaging.c
+++ b/tools/xenpaging/xenpaging.c
@@ -40,6 +40,8 @@
 
 /* Defines number of mfns a guest should use at a time, in KiB */
 #define WATCH_TARGETPAGES "memory/target-tot_pages"
+/* Defines startup confirmation */
+#define WATCH_STARTUP "xenpaging/state"
 static char *watch_target_tot_pages;
 static char *dom_path;
 static char watch_token[16];
@@ -777,6 +779,22 @@ static int evict_pages(xenpaging_t *pagi
     return num;
 }
 
+static int xenpaging_confirm_startup(xenpaging_t *paging)
+{
+    xc_interface *xch = paging->xc_handle;
+    char *path;
+    int len;
+
+    len = asprintf(&path, "%s/%s", dom_path, WATCH_STARTUP);
+    if ( len < 0 )
+        return -1;
+    DPRINTF("confirm startup '%s'\n", path);
+    len = xs_write(paging->xs_handle, XBT_NULL, path, "running", len);
+    DPRINTF("confirm startup returned %d\n", len);
+    free(path);
+    return 0;
+}
+
 int main(int argc, char *argv[])
 {
     struct sigaction act;
@@ -835,6 +853,9 @@ int main(int argc, char *argv[])
     /* listen for page-in events to stop pager */
     create_page_in_thread(paging);
 
+    /* Confirm startup to caller */
+    xenpaging_confirm_startup(paging);
+
     /* Swap pages in and out */
     while ( 1 )
     {

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
  2011-10-03 15:54 ` [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting Olaf Hering
@ 2011-10-04  8:23   ` Ian Campbell
  2011-10-04  9:09     ` Olaf Hering
  0 siblings, 1 reply; 37+ messages in thread
From: Ian Campbell @ 2011-10-04  8:23 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:
> # HG changeset patch
> # User Olaf Hering <olaf@aepfle.de>
> # Date 1317653612 -7200
> # Node ID 219ab93f22c0492595686a1cc34911e9d6775b07
> # Parent  df7be429654c62fb4c61f83549374d77b80ebea3
> libxl: add pid path to libxl__spawner_starting
> 
> libxl_spawner_record_pid() should be able to write the pid to arbitrary paths.
> 
> Signed-off-by: Olaf Hering <olaf@aepfle.de>
> 
> diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_dm.c
> --- a/tools/libxl/libxl_dm.c
> +++ b/tools/libxl/libxl_dm.c
> @@ -848,6 +848,7 @@ int libxl__create_device_model(libxl__gc
>  
>      p->domid = info->domid;
>      p->dom_path = libxl__xs_get_dompath(gc, info->domid);
> +    p->pid_path = "image/device-model-pid";
>      if (!p->dom_path) {
>          rc = ERROR_FAIL;
>          goto out_close;
> diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_exec.c
> --- a/tools/libxl/libxl_exec.c
> +++ b/tools/libxl/libxl_exec.c
> @@ -151,7 +151,7 @@ void libxl_spawner_record_pid(void *for_
>      char *path = NULL, *pid = NULL;
>      int len;
>  
> -    if (asprintf(&path, "%s/%s", starting->dom_path, "image/device-model-pid") < 0)
> +    if (asprintf(&path, "%s/%s", starting->dom_path, starting->pid_path) < 0)
>          goto out;
>  
>      len = asprintf(&pid, "%d", innerchild);
> diff -r df7be429654c -r 219ab93f22c0 tools/libxl/libxl_internal.h
> --- a/tools/libxl/libxl_internal.h
> +++ b/tools/libxl/libxl_internal.h
> @@ -250,6 +250,7 @@ typedef struct {
>  
>  typedef struct {
>      char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
> +    char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */

Either this new comment is true and you need a strdup() up above where
you set it and a free() somewhere else (or use libxl__strdup()) or it is
false and it should be removed and pid_path should be const char *.

I think the second option is sufficient for the current and new user you
are about to add?

Ian.

>      int domid;
>      libxl__spawn_starting *for_spawn;
>  } libxl__spawner_starting;
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting
  2011-10-04  8:23   ` Ian Campbell
@ 2011-10-04  9:09     ` Olaf Hering
  0 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-04  9:09 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, Oct 04, Ian Campbell wrote:

> On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:

> > +++ b/tools/libxl/libxl_internal.h
> > @@ -250,6 +250,7 @@ typedef struct {
> >  
> >  typedef struct {
> >      char *dom_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
> > +    char *pid_path; /* from libxl_malloc, only for libxl_spawner_record_pid */
> 
> Either this new comment is true and you need a strdup() up above where
> you set it and a free() somewhere else (or use libxl__strdup()) or it is
> false and it should be removed and pid_path should be const char *.
> 
> I think the second option is sufficient for the current and new user you
> are about to add?

I duplicated the dom_path line without paying attention to the comment.
A const char *pid_path; is sufficient.

Olaf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00 of 24] xenpaging fixes for xen-unstable
  2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
                   ` (23 preceding siblings ...)
  2011-10-03 15:55 ` [PATCH 24 of 24] xenpaging: libxl support Olaf Hering
@ 2011-10-04  9:51 ` Ian Campbell
  2011-10-04 15:05   ` Olaf Hering
  2011-10-04 15:08   ` Olaf Hering
  24 siblings, 2 replies; 37+ messages in thread
From: Ian Campbell @ 2011-10-04  9:51 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

On Mon, 2011-10-03 at 16:54 +0100, Olaf Hering wrote:
> The following series adds support for xenpaging to libxl and the xl command.
> A few code cleanup changes are also part of this series.
> 
> The logic of xenpaging was reversed.
> It does now monitor the guests tot_pages value and work toward that number by
> either paging out more pages, or write pages back into the guest.
> 
> Three new configuration file options specific for xenpaging were added:
> totmem=<int>
> xenpaging_file=<string>
> xenpaging_extra=[ 'string', 'string' ]
> 
> A new xl command 'mem-tot_pages' instructs xenpaging to adjust its pagefile
> size, and it instructs the xl monitor process to actually start xenpaging if
> totmem= was not specified in the config file.

In general xl commands do not contain "_" but rather use "-". We also
sometimes use a "-set" suffix too.

totmem is unfortunately not all that descriptive to an end user of what
it does (which I think is a general problem we have with the memory
related options).

Currently the xl config file options are:
        memory = actual start of day RAM
        maxmem = max ram guest could balloon to (?)

How does POD fit in? Is it just maxmem-memory for HVM domains? (not
really relevant for this discussion, more for completeness).

The associated command line options are:
        mem-set (runtime equivalent of memory?)
        mem-max (runtime equivalent of maxmem?)

Hmm, I was hoping that enumerating the existing options would make the
name and semantics of the paging option magically pop into my head, I
was wrong :-(

BTW tools/libxl/libxl_memory.txt should be patched by this series too,
once we figure out what to call things.

The phrase "actual memory" is used in that document -- perhaps that is
suitable terminology for totmem?

Ian.

> 
> Please review and apply.
> 
> Olaf
> 
> 
>  Config.mk                        |    2 
>  config/StdGNU.mk                 |    2 
>  tools/libxc/xc_bitops.h          |    6 
>  tools/libxl/libxl.c              |  121 +++++++++
>  tools/libxl/libxl.h              |    5 
>  tools/libxl/libxl_create.c       |  146 +++++++++++
>  tools/libxl/libxl_device.c       |   84 ------
>  tools/libxl/libxl_dm.c           |   65 +----
>  tools/libxl/libxl_dom.c          |    8 
>  tools/libxl/libxl_exec.c         |  142 +++++++++++
>  tools/libxl/libxl_internal.h     |   33 ++
>  tools/libxl/libxl_paths.c        |    5 
>  tools/libxl/libxl_types.idl      |    4 
>  tools/libxl/xl.h                 |    1 
>  tools/libxl/xl_cmdimpl.c         |   71 +++++
>  tools/libxl/xl_cmdtable.c        |    5 
>  tools/xenpaging/Makefile         |    6 
>  tools/xenpaging/file_ops.c       |    6 
>  tools/xenpaging/policy_default.c |   23 +
>  tools/xenpaging/xenpaging.c      |  479 ++++++++++++++++++++++++++++-----------
>  tools/xenpaging/xenpaging.h      |    8 
>  21 files changed, 934 insertions(+), 288 deletions(-)
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00 of 24] xenpaging fixes for xen-unstable
  2011-10-04  9:51 ` [PATCH 00 of 24] xenpaging fixes for xen-unstable Ian Campbell
@ 2011-10-04 15:05   ` Olaf Hering
  2011-10-04 15:08   ` Olaf Hering
  1 sibling, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-04 15:05 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, Oct 04, Ian Campbell wrote:

> totmem is unfortunately not all that descriptive to an end user of what
> it does (which I think is a general problem we have with the memory
> related options).
> 
> Currently the xl config file options are:
>         memory = actual start of day RAM
>         maxmem = max ram guest could balloon to (?)
> 
> How does POD fit in? Is it just maxmem-memory for HVM domains? (not
> really relevant for this discussion, more for completeness).
> 
> The associated command line options are:
>         mem-set (runtime equivalent of memory?)
>         mem-max (runtime equivalent of maxmem?)
> 
> Hmm, I was hoping that enumerating the existing options would make the
> name and semantics of the paging option magically pop into my head, I
> was wrong :-(
> 
> BTW tools/libxl/libxl_memory.txt should be patched by this series too,
> once we figure out what to call things.
> 
> The phrase "actual memory" is used in that document -- perhaps that is
> suitable terminology for totmem?

The naming of the various numbers is confusing, so far I could not come
up with a better name than tot_pages.

"actual target" is close to what xenpaging leaves for the guest, the
amount of video ram has to be substracted.

I think the code in libxl, xenstore and in my changes is not 100%
consistent with the figure below. I have to wade through the individual
members again and check if the math is correct in all places.

Olaf

/* === Domain memory breakdown: HVM guests ==================================
                           
             +  +----------+                                                 +            
             |  | shadow   |                                                 |            
             |  +----------+                                                 |            
    overhead |  | extra    |                                                 |            
             |  | external |                                                 |            
             |  +----------+                                      +          |            
             |  | extra    |                                      |          |            
             |  | internal |                                      |          |            
             +  +----------+                            +         |          | footprint  
             |  | video    |                            |         |          |            
             |  +----------+  +           +    +        |         | xen      |            
             |  |          |  | guest OS  |    |        | actual  | maximum  |            
             |  | guest    |  | real RAM  |    |        | target  |          |            
             |  |          |  |           |    | build  |         |          |            
             |  +----------+  +           |    | start  +         |          |            
      static |  | paging   |              |    |                  |          |            
     maximum |  +----------+              |    +                  +          +            
             |  |          |              |                                               
             |  |          |              |                                               
             |  | balloon  |              | build                                         
             |  |          |              | maximum                                       
             |  |          |              |                                               
             +  +----------+              +                                               
                
                
    extra internal = LIBXL_MAXMEM_CONSTANT
    extra external = LIBXL_HVM_EXTRA_MEMORY
    shadow = libxl_domain_build_info.shadow_memkb
    static maximum = libxl_domain_build_info.max_memkb
    video = libxl_domain_build_info.video_memkb
    build start = libxl_domain_build_info.target_memkb
    libxl_domain_setmaxmem -> xen maximum
    libxl_set_memory_target -> actual target
                
    build maximum = RAM as seen inside the virtual machine
                    Increase/Decrease via memory hotplug of virtual hardware (?)
		    xl mem-max (?)
    build start   = RAM usable by the guest OS
                    guest OS sees balloon driver as memory hog (?)
                    Increase/Decrease via commands to the balloon driver
		    xl mem-set
    real RAM      = RAM allocated for the guest
                    Increase/Decrease via commands to paging daemon
		    xl mem-FOO

    guest = real RAM
    paging = virtual RAM / swap
    balloon = will become real or virtual RAM after mem-set command

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 00 of 24] xenpaging fixes for xen-unstable
  2011-10-04  9:51 ` [PATCH 00 of 24] xenpaging fixes for xen-unstable Ian Campbell
  2011-10-04 15:05   ` Olaf Hering
@ 2011-10-04 15:08   ` Olaf Hering
  1 sibling, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-04 15:08 UTC (permalink / raw)
  To: Ian Campbell; +Cc: xen-devel

On Tue, Oct 04, Ian Campbell wrote:

> How does POD fit in? Is it just maxmem-memory for HVM domains? (not
> really relevant for this discussion, more for completeness).

I dont have much experince with PoD, and started just last week some
testing with a ballooned guest. In my limited testing I found no obvious
bugs. But I have to check the code what PoD really means for paged pages.

Olaf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03 of 24] xenpaging: use PERROR to print errno
  2011-10-03 15:54 ` [PATCH 03 of 24] xenpaging: use PERROR to print errno Olaf Hering
@ 2011-10-04 16:19   ` George Dunlap
  2011-10-04 17:19     ` Olaf Hering
  0 siblings, 1 reply; 37+ messages in thread
From: George Dunlap @ 2011-10-04 16:19 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

On Mon, Oct 3, 2011 at 4:54 PM, Olaf Hering <olaf@aepfle.de> wrote:
> # HG changeset patch
> # User Olaf Hering <olaf@aepfle.de>
> # Date 1317653597 -7200
> # Node ID ee4c4c7699e0de2b6bddce1e816d35f36ffb0470
> # Parent  21b7c9a6545ac1ec9d91fce83d46aab0b5808b05
> xenpaging: use PERROR to print errno
>
> Also catch lseek() errors in file_op().
>
> Signed-off-by: Olaf Hering <olaf@aepfle.de>
>
> diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/file_ops.c
> --- a/tools/xenpaging/file_ops.c
> +++ b/tools/xenpaging/file_ops.c
> @@ -37,6 +37,11 @@ static int file_op(int fd, void *page, i
>     int ret;
>
>     seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET);
> +    if (seek_ret == -1)
> +    {
> +        ret = -errno;
> +        goto err;
> +    }

Wouldn't it be more idiomatic to make both this check and the other
check in the function:
* check for seek_ret < 0 (rather than -1)
* make file_op() return -1
* Let the caller read errno?  (Rather than returning -errno)?


>
>     total = 0;
>     while ( total < PAGE_SIZE )
> diff -r 21b7c9a6545a -r ee4c4c7699e0 tools/xenpaging/xenpaging.c
> --- a/tools/xenpaging/xenpaging.c
> +++ b/tools/xenpaging/xenpaging.c
> @@ -90,7 +90,7 @@ static int xenpaging_wait_for_event_or_t
>         if (errno == EINTR)
>             return 0;
>
> -        ERROR("Poll exited with an error");
> +        PERROR("Poll exited with an error");
>         return -errno;
>     }
>
> @@ -121,7 +121,7 @@ static int xenpaging_wait_for_event_or_t
>         port = xc_evtchn_pending(xce);
>         if ( port == -1 )
>         {
> -            ERROR("Failed to read port from event channel");
> +            PERROR("Failed to read port from event channel");
>             rc = -1;
>             goto err;
>         }
> @@ -129,7 +129,7 @@ static int xenpaging_wait_for_event_or_t
>         rc = xc_evtchn_unmask(xce, port);
>         if ( rc < 0 )
>         {
> -            ERROR("Failed to unmask event channel port");
> +            PERROR("Failed to unmask event channel port");
>         }
>     }
>  err:
> @@ -185,7 +185,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->xs_handle = xs_open(0);
>     if ( paging->xs_handle == NULL )
>     {
> -        ERROR("Error initialising xenstore connection");
> +        PERROR("Error initialising xenstore connection");
>         goto err;
>     }
>
> @@ -193,7 +193,7 @@ static xenpaging_t *xenpaging_init(domid
>     snprintf(watch_token, sizeof(watch_token), "%u", domain_id);
>     if ( xs_watch(paging->xs_handle, "@releaseDomain", watch_token) == false )
>     {
> -        ERROR("Could not bind to shutdown watch\n");
> +        PERROR("Could not bind to shutdown watch\n");
>         goto err;
>     }
>
> @@ -214,7 +214,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->mem_event.shared_page = init_page();
>     if ( paging->mem_event.shared_page == NULL )
>     {
> -        ERROR("Error initialising shared page");
> +        PERROR("Error initialising shared page");
>         goto err;
>     }
>
> @@ -222,7 +222,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->mem_event.ring_page = init_page();
>     if ( paging->mem_event.ring_page == NULL )
>     {
> -        ERROR("Error initialising ring page");
> +        PERROR("Error initialising ring page");
>         goto err;
>     }
>
> @@ -240,13 +240,13 @@ static xenpaging_t *xenpaging_init(domid
>     {
>         switch ( errno ) {
>             case EBUSY:
> -                ERROR("xenpaging is (or was) active on this domain");
> +                PERROR("xenpaging is (or was) active on this domain");
>                 break;
>             case ENODEV:
> -                ERROR("EPT not supported for this guest");
> +                PERROR("EPT not supported for this guest");
>                 break;
>             default:
> -                ERROR("Error initialising shared page: %s", strerror(errno));
> +                PERROR("Error initialising shared page: %s", strerror(errno));
>                 break;
>         }
>         goto err;
> @@ -256,7 +256,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->mem_event.xce_handle = xc_evtchn_open(NULL, 0);
>     if ( paging->mem_event.xce_handle == NULL )
>     {
> -        ERROR("Failed to open event channel");
> +        PERROR("Failed to open event channel");
>         goto err;
>     }
>
> @@ -266,7 +266,7 @@ static xenpaging_t *xenpaging_init(domid
>                                     paging->mem_event.shared_page->port);
>     if ( rc < 0 )
>     {
> -        ERROR("Failed to bind event channel");
> +        PERROR("Failed to bind event channel");
>         goto err;
>     }
>
> @@ -276,7 +276,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->domain_info = malloc(sizeof(xc_domaininfo_t));
>     if ( paging->domain_info == NULL )
>     {
> -        ERROR("Error allocating memory for domain info");
> +        PERROR("Error allocating memory for domain info");
>         goto err;
>     }
>
> @@ -284,7 +284,7 @@ static xenpaging_t *xenpaging_init(domid
>                                paging->domain_info);
>     if ( rc != 1 )
>     {
> -        ERROR("Error getting domain info");
> +        PERROR("Error getting domain info");
>         goto err;
>     }
>
> @@ -292,7 +292,7 @@ static xenpaging_t *xenpaging_init(domid
>     paging->bitmap = bitmap_alloc(paging->domain_info->max_pages);
>     if ( !paging->bitmap )
>     {
> -        ERROR("Error allocating bitmap");
> +        PERROR("Error allocating bitmap");
>         goto err;
>     }
>     DPRINTF("max_pages = %"PRIx64"\n", paging->domain_info->max_pages);
> @@ -308,7 +308,7 @@ static xenpaging_t *xenpaging_init(domid
>     rc = policy_init(paging);
>     if ( rc != 0 )
>     {
> -        ERROR("Error initialising policy");
> +        PERROR("Error initialising policy");
>         goto err;
>     }
>
> @@ -355,14 +355,14 @@ static int xenpaging_teardown(xenpaging_
>     rc = xc_mem_paging_disable(xch, paging->mem_event.domain_id);
>     if ( rc != 0 )
>     {
> -        ERROR("Error tearing down domain paging in xen");
> +        PERROR("Error tearing down domain paging in xen");
>     }
>
>     /* Unbind VIRQ */
>     rc = xc_evtchn_unbind(paging->mem_event.xce_handle, paging->mem_event.port);
>     if ( rc != 0 )
>     {
> -        ERROR("Error unbinding event port");
> +        PERROR("Error unbinding event port");
>     }
>     paging->mem_event.port = -1;
>
> @@ -370,7 +370,7 @@ static int xenpaging_teardown(xenpaging_
>     rc = xc_evtchn_close(paging->mem_event.xce_handle);
>     if ( rc != 0 )
>     {
> -        ERROR("Error closing event channel");
> +        PERROR("Error closing event channel");
>     }
>     paging->mem_event.xce_handle = NULL;
>
> @@ -381,7 +381,7 @@ static int xenpaging_teardown(xenpaging_
>     rc = xc_interface_close(xch);
>     if ( rc != 0 )
>     {
> -        ERROR("Error closing connection to xen");
> +        PERROR("Error closing connection to xen");
>     }
>
>     return 0;
> @@ -441,7 +441,7 @@ static int xenpaging_evict_page(xenpagin
>                                 PROT_READ | PROT_WRITE, &gfn, 1);
>     if ( page == NULL )
>     {
> -        ERROR("Error mapping page");
> +        PERROR("Error mapping page");
>         goto out;
>     }
>
> @@ -449,8 +449,8 @@ static int xenpaging_evict_page(xenpagin
>     ret = write_page(fd, page, i);
>     if ( ret != 0 )
>     {
> +        PERROR("Error copying page");
>         munmap(page, PAGE_SIZE);
> -        ERROR("Error copying page");
>         goto out;
>     }
>
> @@ -464,7 +464,7 @@ static int xenpaging_evict_page(xenpagin
>                               victim->gfn);
>     if ( ret != 0 )
>     {
> -        ERROR("Error evicting page");
> +        PERROR("Error evicting page");
>         goto out;
>     }
>
> @@ -520,7 +520,7 @@ static int xenpaging_populate_page(xenpa
>                 sleep(1);
>                 continue;
>             }
> -            ERROR("Error preparing for page in");
> +            PERROR("Error preparing for page in");
>             goto out_map;
>         }
>     }
> @@ -532,7 +532,7 @@ static int xenpaging_populate_page(xenpa
>                                 PROT_READ | PROT_WRITE, &gfn, 1);
>     if ( page == NULL )
>     {
> -        ERROR("Error mapping page: page is null");
> +        PERROR("Error mapping page: page is null");
>         goto out_map;
>     }
>
> @@ -540,7 +540,7 @@ static int xenpaging_populate_page(xenpa
>     ret = read_page(fd, page, i);
>     if ( ret != 0 )
>     {
> -        ERROR("Error reading page");
> +        PERROR("Error reading page");
>         goto out;
>     }
>
> @@ -579,7 +579,7 @@ static int evict_victim(xenpaging_t *pag
>         {
>             if ( j++ % 1000 == 0 )
>                 if ( xenpaging_mem_paging_flush_ioemu_cache(paging) )
> -                    ERROR("Error flushing ioemu cache");
> +                    PERROR("Error flushing ioemu cache");
>         }
>     }
>     while ( ret );
> @@ -670,7 +670,7 @@ int main(int argc, char *argv[])
>         rc = xenpaging_wait_for_event_or_timeout(paging);
>         if ( rc < 0 )
>         {
> -            ERROR("Error getting event");
> +            PERROR("Error getting event");
>             goto out;
>         }
>         else if ( rc != 0 )
> @@ -710,7 +710,7 @@ int main(int argc, char *argv[])
>                     rc = xenpaging_populate_page(paging, req.gfn, fd, i);
>                     if ( rc != 0 )
>                     {
> -                        ERROR("Error populating page");
> +                        PERROR("Error populating page");
>                         goto out;
>                     }
>                 }
> @@ -723,7 +723,7 @@ int main(int argc, char *argv[])
>                 rc = xenpaging_resume_page(paging, &rsp, 1);
>                 if ( rc != 0 )
>                 {
> -                    ERROR("Error resuming page");
> +                    PERROR("Error resuming page");
>                     goto out;
>                 }
>
> @@ -752,7 +752,7 @@ int main(int argc, char *argv[])
>                     rc = xenpaging_resume_page(paging, &rsp, 0);
>                     if ( rc != 0 )
>                     {
> -                        ERROR("Error resuming");
> +                        PERROR("Error resuming");
>                         goto out;
>                     }
>                 }
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xensource.com
> http://lists.xensource.com/xen-devel
>

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 03 of 24] xenpaging: use PERROR to print errno
  2011-10-04 16:19   ` George Dunlap
@ 2011-10-04 17:19     ` Olaf Hering
  0 siblings, 0 replies; 37+ messages in thread
From: Olaf Hering @ 2011-10-04 17:19 UTC (permalink / raw)
  To: George Dunlap; +Cc: xen-devel

On Tue, Oct 04, George Dunlap wrote:

> On Mon, Oct 3, 2011 at 4:54 PM, Olaf Hering <olaf@aepfle.de> wrote:

> >     seek_ret = lseek(fd, i << PAGE_SHIFT, SEEK_SET);
> > +    if (seek_ret == -1)
> > +    {
> > +        ret = -errno;
> > +        goto err;
> > +    }
> 
> Wouldn't it be more idiomatic to make both this check and the other
> check in the function:
> * check for seek_ret < 0 (rather than -1)

The man page said its -1, now that I read it again it says (off_t)-1, so
my change above should be updated to comply with the man page.

> * make file_op() return -1
> * Let the caller read errno?  (Rather than returning -errno)?

Yes, I will change this in a new patch.

Olaf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-03 15:54 ` [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup Olaf Hering
@ 2011-10-25 15:31   ` Ian Jackson
  2011-10-25 17:21     ` Olaf Hering
  0 siblings, 1 reply; 37+ messages in thread
From: Ian Jackson @ 2011-10-25 15:31 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> libxl: add libxl__spawn_confirm_offspring_startup
> 
> libxl__spawn_confirm_offspring_startup() is a generic version of
> libxl__confirm_device_model_startup().

Thanks but I think it would be better to refactor this to avoid the
duplication of this code.

Ian.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-25 15:31   ` Ian Jackson
@ 2011-10-25 17:21     ` Olaf Hering
  2011-10-25 17:53       ` Ian Jackson
  0 siblings, 1 reply; 37+ messages in thread
From: Olaf Hering @ 2011-10-25 17:21 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Tue, Oct 25, Ian Jackson wrote:

> Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> > libxl: add libxl__spawn_confirm_offspring_startup
> > 
> > libxl__spawn_confirm_offspring_startup() is a generic version of
> > libxl__confirm_device_model_startup().
> 
> Thanks but I think it would be better to refactor this to avoid the
> duplication of this code.

The new function is used in patch #18 of this series.
Or do you have some other changes in mind?

Olaf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-25 17:21     ` Olaf Hering
@ 2011-10-25 17:53       ` Ian Jackson
  2011-10-26 16:30         ` Olaf Hering
  0 siblings, 1 reply; 37+ messages in thread
From: Ian Jackson @ 2011-10-25 17:53 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel, Ian Jackson

Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> On Tue, Oct 25, Ian Jackson wrote:
> > Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> > > libxl: add libxl__spawn_confirm_offspring_startup
> > > 
> > > libxl__spawn_confirm_offspring_startup() is a generic version of
> > > libxl__confirm_device_model_startup().
> > 
> > Thanks but I think it would be better to refactor this to avoid the
> > duplication of this code.
> 
> The new function is used in patch #18 of this series.
> Or do you have some other changes in mind?

I mean that you should arrange to replace
libxl__confirm_device_model_startup with your new function
libxl__spawn_confirm_offspring_startup.

As it is you have made a copy of libxl__confirm_device_model_startup
and lightly edited it.  This is a cardinal sin in programming, known
as "clone and hack".

Ian.

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-25 17:53       ` Ian Jackson
@ 2011-10-26 16:30         ` Olaf Hering
  2011-10-27 10:34           ` Ian Jackson
  0 siblings, 1 reply; 37+ messages in thread
From: Olaf Hering @ 2011-10-26 16:30 UTC (permalink / raw)
  To: Ian Jackson; +Cc: xen-devel

On Tue, Oct 25, Ian Jackson wrote:

> Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> > On Tue, Oct 25, Ian Jackson wrote:
> > > Olaf Hering writes ("[Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> > > > libxl: add libxl__spawn_confirm_offspring_startup
> > > > 
> > > > libxl__spawn_confirm_offspring_startup() is a generic version of
> > > > libxl__confirm_device_model_startup().
> > > 
> > > Thanks but I think it would be better to refactor this to avoid the
> > > duplication of this code.
> > 
> > The new function is used in patch #18 of this series.
> > Or do you have some other changes in mind?
> 
> I mean that you should arrange to replace
> libxl__confirm_device_model_startup with your new function
> libxl__spawn_confirm_offspring_startup.
> 
> As it is you have made a copy of libxl__confirm_device_model_startup
> and lightly edited it.  This is a cardinal sin in programming, known
> as "clone and hack".

I moved the device model specific functions and made them generic.
Perhaps I should have merged the add+use patches (15+16 / 17+18) into a
single change. Once all patches are applied I see no code duplication.

If you prefer I can send a series just for the spawn related changes in
libxl.


Olaf

^ permalink raw reply	[flat|nested] 37+ messages in thread

* Re: [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup
  2011-10-26 16:30         ` Olaf Hering
@ 2011-10-27 10:34           ` Ian Jackson
  0 siblings, 0 replies; 37+ messages in thread
From: Ian Jackson @ 2011-10-27 10:34 UTC (permalink / raw)
  To: Olaf Hering; +Cc: xen-devel

Olaf Hering writes ("Re: [Xen-devel] [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup"):
> I moved the device model specific functions and made them generic.
> Perhaps I should have merged the add+use patches (15+16 / 17+18) into a
> single change. Once all patches are applied I see no code duplication.

Oh, I see; I didn't spot that, I'm afraid.  I'll look at it again.

Ian.

^ permalink raw reply	[flat|nested] 37+ messages in thread

end of thread, other threads:[~2011-10-27 10:34 UTC | newest]

Thread overview: 37+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-10-03 15:54 [PATCH 00 of 24] xenpaging fixes for xen-unstable Olaf Hering
2011-10-03 15:54 ` [PATCH 01 of 24] xenpaging: remove filename from comment Olaf Hering
2011-10-03 15:54 ` [PATCH 02 of 24] xenpaging: remove obsolete comment in resume path Olaf Hering
2011-10-03 15:54 ` [PATCH 03 of 24] xenpaging: use PERROR to print errno Olaf Hering
2011-10-04 16:19   ` George Dunlap
2011-10-04 17:19     ` Olaf Hering
2011-10-03 15:54 ` [PATCH 04 of 24] xenpaging: update xenpaging_init Olaf Hering
2011-10-03 15:54 ` [PATCH 05 of 24] xenpaging: remove xc_dominfo_t from paging_t Olaf Hering
2011-10-03 15:54 ` [PATCH 06 of 24] xenpaging: track the number of paged-out pages Olaf Hering
2011-10-03 15:54 ` [PATCH 07 of 24] xenpaging: move page add/resume loops into its own function Olaf Hering
2011-10-03 15:54 ` [PATCH 08 of 24] xenpaging: compare both token and path when checking for @releaseDomain event Olaf Hering
2011-10-03 15:54 ` [PATCH 09 of 24] xenpaging: improve mainloop exit handling Olaf Hering
2011-10-03 15:54 ` [PATCH 10 of 24] libxc: add bitmap_clear function Olaf Hering
2011-10-03 15:54 ` [PATCH 11 of 24] xenpaging: retry unpageable gfns Olaf Hering
2011-10-03 15:54 ` [PATCH 12 of 24] libxl: rename libxl__device_model_starting Olaf Hering
2011-10-03 15:54 ` [PATCH 13 of 24] libxl: rename dm_xenstore_record_pid to libxl_spawner_record_pid Olaf Hering
2011-10-03 15:54 ` [PATCH 14 of 24] libxl: add pid path to libxl__spawner_starting Olaf Hering
2011-10-04  8:23   ` Ian Campbell
2011-10-04  9:09     ` Olaf Hering
2011-10-03 15:54 ` [PATCH 15 of 24] libxl: add libxl__wait_for_offspring function Olaf Hering
2011-10-03 15:54 ` [PATCH 16 of 24] libxl: use libxl__wait_for_offspring for device model Olaf Hering
2011-10-03 15:54 ` [PATCH 17 of 24] libxl: add libxl__spawn_confirm_offspring_startup Olaf Hering
2011-10-25 15:31   ` Ian Jackson
2011-10-25 17:21     ` Olaf Hering
2011-10-25 17:53       ` Ian Jackson
2011-10-26 16:30         ` Olaf Hering
2011-10-27 10:34           ` Ian Jackson
2011-10-03 15:54 ` [PATCH 18 of 24] libxl: use libxl__spawn_confirm_offspring_startup for device model Olaf Hering
2011-10-03 15:54 ` [PATCH 19 of 24] xenpaging: install into LIBEXEC dir Olaf Hering
2011-10-03 15:54 ` [PATCH 20 of 24] xenpaging: add XEN_PAGING_DIR / libxl_xenpaging_dir_path() Olaf Hering
2011-10-03 15:54 ` [PATCH 21 of 24] xenpaging: use guests tot_pages as working target Olaf Hering
2011-10-03 15:54 ` [PATCH 22 of 24] xenpaging: watch the guests memory/target-tot_pages xenstore value Olaf Hering
2011-10-03 15:55 ` [PATCH 23 of 24] xenpaging: add cmdline interface for pager Olaf Hering
2011-10-03 15:55 ` [PATCH 24 of 24] xenpaging: libxl support Olaf Hering
2011-10-04  9:51 ` [PATCH 00 of 24] xenpaging fixes for xen-unstable Ian Campbell
2011-10-04 15:05   ` Olaf Hering
2011-10-04 15:08   ` Olaf Hering

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.