xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xensource.com
Cc: Shriram Rajagopalan <rshriram@cs.ubc.ca>,
	Stefano Stabellini <stefano.stabellini@eu.citrix.com>,
	Ian Jackson <Ian.Jackson@eu.citrix.com>,
	Ian Campbell <ian.campbell@citrix.com>,
	Lai Jiangshan <laijs@cn.fujitsu.com>
Subject: [PATCH 16/19] libxl: suspend: Abolish usleeps in domain suspend wait
Date: Tue, 4 Mar 2014 14:56:53 +0000	[thread overview]
Message-ID: <1393945016-1417-17-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1393945016-1417-1-git-send-email-ian.jackson@eu.citrix.com>

Replace the use of a loop with usleep().

Instead, use a xenstore watch and an event system timeout.  xenstore
fires watches on @releaseDomain when a domain shuts down.

The logic which checks for the state of the domain is unchanged, and
not ideal, but we will leave that for the next patch.

There is not intended to be any semantic change, other than to make
the algorithm properly asynchronous and the consequential waiting on
xenstore, rather than polling.

Signed-off-by: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
CC: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/libxl_dom.c      |   80 ++++++++++++++++++++++++++++++------------
 tools/libxl/libxl_internal.h |    2 ++
 2 files changed, 60 insertions(+), 22 deletions(-)

diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index dde7e33..6291115 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1028,8 +1028,14 @@ static void domain_suspend_common_wait_guest(libxl__egc *egc,
                                              libxl__domain_suspend_state *dss);
 static void domain_suspend_common_guest_suspended(libxl__egc *egc,
                                          libxl__domain_suspend_state *dss);
+
 static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc,
       libxl__xswait_state *xswa, int rc, const char *state);
+static void suspend_common_wait_guest_watch(libxl__egc *egc,
+      libxl__ev_xswatch *xsw, const char *watch_path, const char *event_path);
+static void suspend_common_wait_guest_timeout(libxl__egc *egc,
+      libxl__ev_time *ev, const struct timeval *requested_abs);
+
 static void domain_suspend_common_failed(libxl__egc *egc,
                                          libxl__domain_suspend_state *dss);
 static void domain_suspend_common_done(libxl__egc *egc,
@@ -1175,36 +1181,59 @@ static void domain_suspend_common_wait_guest(libxl__egc *egc,
                                              libxl__domain_suspend_state *dss)
 {
     STATE_AO_GC(dss->ao);
+    int rc;
+
+    LOG(DEBUG, "wait for the guest to suspend");
+
+    rc = libxl__ev_xswatch_register(gc, &dss->guest_watch,
+                                    suspend_common_wait_guest_watch,
+                                    "@releaseDomain");
+    if (rc) goto err;
+
+    rc = libxl__ev_time_register_rel(gc, &dss->guest_timeout, 
+                                     suspend_common_wait_guest_timeout,
+                                     60*1000);
+    if (rc) goto err;
+    return;
+
+ err:
+    domain_suspend_common_failed(egc, dss);
+}
+
+static void suspend_common_wait_guest_watch(libxl__egc *egc,
+      libxl__ev_xswatch *xsw, const char *watch_path, const char *event_path)
+{
+    libxl__domain_suspend_state *dss =
+        CONTAINER_OF(xsw, *dss, guest_watch);
+    STATE_AO_GC(dss->ao);
+    xc_domaininfo_t info;
     int ret;
-    int watchdog;
 
     /* Convenience aliases */
     const uint32_t domid = dss->domid;
 
-    LOG(DEBUG, "wait for the guest to suspend");
-    watchdog = 60;
-    while (watchdog > 0) {
-        xc_domaininfo_t info;
-
-        usleep(100000);
-        ret = xc_domain_getinfolist(CTX->xch, domid, 1, &info);
-        if (ret == 1 && info.domain == domid &&
-            (info.flags & XEN_DOMINF_shutdown)) {
-            int shutdown_reason;
-
-            shutdown_reason = (info.flags >> XEN_DOMINF_shutdownshift)
-                & XEN_DOMINF_shutdownmask;
-            if (shutdown_reason == SHUTDOWN_suspend) {
-                LOG(DEBUG, "guest has suspended");
-                domain_suspend_common_guest_suspended(egc, dss);
-                return;
-            }
+    ret = xc_domain_getinfolist(CTX->xch, domid, 1, &info);
+    if (ret == 1 && info.domain == domid &&
+        (info.flags & XEN_DOMINF_shutdown)) {
+        int shutdown_reason;
+
+        shutdown_reason = (info.flags >> XEN_DOMINF_shutdownshift)
+            & XEN_DOMINF_shutdownmask;
+        if (shutdown_reason == SHUTDOWN_suspend) {
+            LOG(DEBUG, "guest has suspended");
+            domain_suspend_common_guest_suspended(egc, dss);
+            return;
         }
-
-        watchdog--;
     }
+    /* otherwise, keep waiting */
+}
 
-    LOG(ERROR, "guest did not suspend");
+static void suspend_common_wait_guest_timeout(libxl__egc *egc,
+      libxl__ev_time *ev, const struct timeval *requested_abs)
+{
+    libxl__domain_suspend_state *dss = CONTAINER_OF(ev, *dss, guest_timeout);
+    STATE_AO_GC(dss->ao);
+    LOG(ERROR, "guest did not suspend, timed out");
     domain_suspend_common_failed(egc, dss);
 }
 
@@ -1214,6 +1243,9 @@ static void domain_suspend_common_guest_suspended(libxl__egc *egc,
     STATE_AO_GC(dss->ao);
     int ret;
 
+    libxl__ev_xswatch_deregister(gc, &dss->guest_watch);
+    libxl__ev_time_deregister(gc, &dss->guest_timeout);
+
     if (dss->hvm) {
         ret = libxl__domain_suspend_device_model(gc, dss);
         if (ret) {
@@ -1237,6 +1269,8 @@ static void domain_suspend_common_done(libxl__egc *egc,
 {
     EGC_GC;
     assert(!libxl__xswait_inuse(&dss->pvcontrol));
+    libxl__ev_xswatch_deregister(gc, &dss->guest_watch);
+    libxl__ev_time_deregister(gc, &dss->guest_timeout);
     dss->callback_common_done(egc, dss, ok);
 }
 
@@ -1423,6 +1457,8 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
 
     logdirty_init(&dss->logdirty);
     libxl__xswait_init(&dss->pvcontrol);
+    libxl__ev_xswatch_init(&dss->guest_watch);
+    libxl__ev_time_init(&dss->guest_timeout);
 
     switch (type) {
     case LIBXL_DOMAIN_TYPE_HVM: {
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 5ac02cb..7ad15b5 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2423,6 +2423,8 @@ struct libxl__domain_suspend_state {
     int xcflags;
     int guest_responded;
     libxl__xswait_state pvcontrol;
+    libxl__ev_xswatch guest_watch;
+    libxl__ev_time guest_timeout;
     const char *dm_savefile;
     int interval; /* checkpoint interval (for Remus) */
     libxl__save_helper_state shs;
-- 
1.7.10.4

  parent reply	other threads:[~2014-03-04 14:56 UTC|newest]

Thread overview: 70+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-03-04 14:56 [PATCH v2.1 RESEND 00/19] libxl: asynchronous suspend Ian Jackson
2014-03-04 14:56 ` [PATCH 01/19] libxl: init: Provide a gc later in libxl_ctx_alloc Ian Jackson
2014-03-13 16:20   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 02/19] libxl: init: libxl__poller_init and _get take gc Ian Jackson
2014-03-13 16:21   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 03/19] libxl: events: const-correct *_inuse, *_isregistered Ian Jackson
2014-03-04 14:56 ` [PATCH 04/19] libxl: events: Provide libxl__xswait_* Ian Jackson
2014-03-13 16:33   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 05/19] libxl: events: Use libxl__xswait_* in spawn code Ian Jackson
2014-03-10  3:35   ` Lai Jiangshan
2014-03-10 10:26     ` Ian Jackson
2014-03-13 16:33       ` Ian Campbell
2014-03-04 14:56 ` [PATCH 06/19] libxl: events: Provide libxl__ev_evtchn* Ian Jackson
2014-03-13 16:36   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 07/19] libxc: suspend: Rename, improve xc_suspend_evtchn_init Ian Jackson
2014-03-04 15:10   ` Andrew Cooper
2014-03-04 15:30     ` Ian Jackson
2014-03-13 16:38   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 08/19] libxc: suspend: Fix suspend event channel locking Ian Jackson
2014-03-13 16:47   ` Ian Campbell
2014-03-13 18:46     ` Ian Jackson
2014-03-14  9:55       ` Ian Campbell
2014-03-16  4:53   ` Shriram Rajagopalan
2014-03-17 11:35     ` Ian Jackson
2014-03-17 13:00       ` Ian Jackson
2014-03-04 14:56 ` [PATCH 09/19] libxl: suspend: Async libxl__domain_suspend_callback Ian Jackson
2014-03-13 16:58   ` Ian Campbell
2014-03-13 18:19     ` Ian Jackson
2014-03-14  9:54       ` Ian Campbell
2014-03-04 14:56 ` [PATCH 10/19] libxl: suspend: Async domain_suspend_callback_common Ian Jackson
2014-03-13 16:59   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 11/19] libxl: suspend: Reorg domain_suspend_callback_common Ian Jackson
2014-03-13 17:02   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 12/19] libxl: suspend: New libxl__domain_pvcontrol_xspath Ian Jackson
2014-03-13 17:03   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 13/19] libxl: suspend: New domain_suspend_pvcontrol_acked Ian Jackson
2014-03-13 17:05   ` Ian Campbell
2014-03-13 18:22     ` Ian Jackson
2014-03-04 14:56 ` [PATCH 14/19] libxl: suspend: domain_suspend_callback_common xs errs Ian Jackson
2014-03-13 17:06   ` Ian Campbell
2014-03-04 14:56 ` [PATCH 15/19] libxl: suspend: Async xenstore pvcontrol wait Ian Jackson
2014-03-13 17:13   ` Ian Campbell
2014-03-13 18:26     ` Ian Jackson
2014-03-14 10:06       ` Ian Campbell
2014-03-14 17:24         ` Ian Jackson
2014-03-14 17:39           ` Ian Campbell
2014-03-04 14:56 ` Ian Jackson [this message]
2014-03-13 17:16   ` [PATCH 16/19] libxl: suspend: Abolish usleeps in domain suspend wait Ian Campbell
2014-03-13 18:29     ` Ian Jackson
2014-03-14 10:10       ` Ian Campbell
2014-03-14 17:28         ` Ian Jackson
2014-03-14 17:39           ` Ian Campbell
2014-03-14 17:41           ` Ian Jackson
2014-03-14 17:46             ` Ian Campbell
2014-03-14 18:16               ` Ian Jackson
2014-03-17  9:55                 ` Ian Campbell
2014-03-17 11:55                   ` Ian Jackson
2014-03-17 11:58                     ` Ian Campbell
2014-03-04 14:56 ` [PATCH 17/19] libxl: suspend: Fix suspend wait corner cases Ian Jackson
2014-03-13 17:18   ` Ian Campbell
2014-03-13 18:33     ` Ian Jackson
2014-03-14 10:20       ` Ian Campbell
2014-03-04 14:56 ` [PATCH 18/19] libxl: suspend: Async evtchn wait Ian Jackson
2014-03-13 17:23   ` Ian Campbell
2014-03-13 18:36     ` Ian Jackson
2014-03-14 10:21       ` Ian Campbell
2014-03-04 14:56 ` [PATCH 19/19] libxl: suspend: Apply guest timeout in evtchn case Ian Jackson
2014-03-13 17:23   ` Ian Campbell
2014-03-11  8:55 ` [PATCH v2.1 RESEND 00/19] libxl: asynchronous suspend Lai Jiangshan
2014-03-11 11:35   ` Ian Jackson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1393945016-1417-17-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=ian.campbell@citrix.com \
    --cc=laijs@cn.fujitsu.com \
    --cc=rshriram@cs.ubc.ca \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xensource.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).