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 18/19] libxl: suspend: Async evtchn wait
Date: Tue, 4 Mar 2014 14:56:55 +0000 [thread overview]
Message-ID: <1393945016-1417-19-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1393945016-1417-1-git-send-email-ian.jackson@eu.citrix.com>
When negotiating guest suspend via the evtchn ("fast") protocol,
abolish synchronous wait for domain suspend.
If the guest supports the event channel suspend protocol, we used to
sit in a loop waiting for it to suspend.
Instead, use the new libxl event channel event facility. When we see
that the event is signaled, we look at the domain to see if it has
suspended.
So the suspend operation no longer blocks with the libxl ctx lock
held, and instead returns to the event loop. Additionally, domains
which signal the event channel themselves, or undergo other state
changes, will be handled more correctly.
We end up making a few more hypercalls.
Also, if we encounter errors setting up the suspend event channel
(which should not happen), abort the operation rather than falling
back to the xenstore protocol.
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 | 78 ++++++++++++++++++++++++++----------------
tools/libxl/libxl_internal.h | 3 +-
2 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index 88700ee..c431a2d 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -1031,8 +1031,12 @@ static void domain_suspend_common_guest_suspended(libxl__egc *egc,
static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc,
libxl__xswait_state *xswa, int rc, const char *state);
+static void domain_suspend_common_wait_guest_evtchn(libxl__egc *egc,
+ libxl__ev_evtchn *evev);
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_check(libxl__egc *egc,
+ libxl__domain_suspend_state *dss);
static void suspend_common_wait_guest_timeout(libxl__egc *egc,
libxl__ev_time *ev, const struct timeval *requested_abs);
@@ -1054,7 +1058,7 @@ static void domain_suspend_callback_common(libxl__egc *egc,
{
STATE_AO_GC(dss->ao);
unsigned long hvm_s_state = 0, hvm_pvdrv = 0;
- int ret;
+ int ret, rc;
/* Convenience aliases */
const uint32_t domid = dss->domid;
@@ -1064,21 +1068,19 @@ static void domain_suspend_callback_common(libxl__egc *egc,
xc_get_hvm_param(CTX->xch, domid, HVM_PARAM_ACPI_S_STATE, &hvm_s_state);
}
- if ((hvm_s_state == 0) && (dss->suspend_eventchn >= 0)) {
+ if ((hvm_s_state == 0) && (dss->guest_evtchn.port >= 0)) {
LOG(DEBUG, "issuing %s suspend request via event channel",
dss->hvm ? "PVHVM" : "PV");
- ret = xc_evtchn_notify(dss->xce, dss->suspend_eventchn);
+ ret = xc_evtchn_notify(CTX->xce, dss->guest_evtchn.port);
if (ret < 0) {
LOG(ERROR, "xc_evtchn_notify failed ret=%d", ret);
goto err;
}
- ret = xc_await_suspend(CTX->xch, dss->xce, dss->suspend_eventchn);
- if (ret < 0) {
- LOG(ERROR, "xc_await_suspend failed ret=%d", ret);
- goto err;
- }
- dss->guest_responded = 1;
- domain_suspend_common_guest_suspended(egc, dss);
+
+ dss->guest_evtchn.callback = domain_suspend_common_wait_guest_evtchn;
+ rc = libxl__ev_evtchn_wait(gc, &dss->guest_evtchn);
+ if (rc) goto err;
+
return;
}
@@ -1114,6 +1116,19 @@ static void domain_suspend_callback_common(libxl__egc *egc,
domain_suspend_common_failed(egc, dss);
}
+static void domain_suspend_common_wait_guest_evtchn(libxl__egc *egc,
+ libxl__ev_evtchn *evev)
+{
+ libxl__domain_suspend_state *dss = CONTAINER_OF(evev, *dss, guest_evtchn);
+ STATE_AO_GC(dss->ao);
+ /* If we should be done waiting, suspend_common_wait_guest_check
+ * will end up calling domain_suspend_common_guest_suspended or
+ * domain_suspend_common_failed, both of which cancel the evtchn
+ * wait. So re-enable it now. */
+ libxl__ev_evtchn_wait(gc, &dss->guest_evtchn);
+ suspend_common_wait_guest_check(egc, dss);
+}
+
static void domain_suspend_common_pvcontrol_suspending(libxl__egc *egc,
libxl__xswait_state *xswa, int rc, const char *state)
{
@@ -1203,8 +1218,13 @@ static void domain_suspend_common_wait_guest(libxl__egc *egc,
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);
+ libxl__domain_suspend_state *dss = CONTAINER_OF(xsw, *dss, guest_watch);
+ suspend_common_wait_guest_check(egc, dss);
+}
+
+static void suspend_common_wait_guest_check(libxl__egc *egc,
+ libxl__domain_suspend_state *dss)
+{
STATE_AO_GC(dss->ao);
xc_domaininfo_t info;
int ret;
@@ -1261,6 +1281,7 @@ static void domain_suspend_common_guest_suspended(libxl__egc *egc,
STATE_AO_GC(dss->ao);
int ret;
+ libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn);
libxl__ev_xswatch_deregister(gc, &dss->guest_watch);
libxl__ev_time_deregister(gc, &dss->guest_timeout);
@@ -1287,6 +1308,7 @@ static void domain_suspend_common_done(libxl__egc *egc,
{
EGC_GC;
assert(!libxl__xswait_inuse(&dss->pvcontrol));
+ libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn);
libxl__ev_xswatch_deregister(gc, &dss->guest_watch);
libxl__ev_time_deregister(gc, &dss->guest_timeout);
dss->callback_common_done(egc, dss, ok);
@@ -1475,6 +1497,7 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
logdirty_init(&dss->logdirty);
libxl__xswait_init(&dss->pvcontrol);
+ libxl__ev_evtchn_init(&dss->guest_evtchn);
libxl__ev_xswatch_init(&dss->guest_watch);
libxl__ev_time_init(&dss->guest_timeout);
@@ -1503,7 +1526,7 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
| (debug ? XCFLAGS_DEBUG : 0)
| (dss->hvm ? XCFLAGS_HVM : 0);
- dss->suspend_eventchn = -1;
+ dss->guest_evtchn.port = -1;
dss->guest_evtchn_lockfd = -1;
dss->guest_responded = 0;
dss->dm_savefile = libxl__device_model_savefile(gc, domid);
@@ -1514,20 +1537,17 @@ void libxl__domain_suspend(libxl__egc *egc, libxl__domain_suspend_state *dss)
dss->xcflags |= XCFLAGS_CHECKPOINT_COMPRESS;
}
- dss->xce = xc_evtchn_open(NULL, 0);
- if (dss->xce == NULL)
- goto out;
- else
- {
- port = xs_suspend_evtchn_port(dss->domid);
+ port = xs_suspend_evtchn_port(dss->domid);
- if (port >= 0) {
- dss->suspend_eventchn =
- xc_suspend_evtchn_init_exclusive(CTX->xch, dss->xce,
+ if (port >= 0) {
+ dss->guest_evtchn.port =
+ xc_suspend_evtchn_init_exclusive(CTX->xch, CTX->xce,
dss->domid, port, &dss->guest_evtchn_lockfd);
- if (dss->suspend_eventchn < 0)
- LOG(WARN, "Suspend event channel initialization failed");
+ if (dss->guest_evtchn.port < 0) {
+ LOG(WARN, "Suspend event channel initialization failed");
+ rc = ERROR_FAIL;
+ goto out;
}
}
@@ -1686,11 +1706,11 @@ static void domain_suspend_done(libxl__egc *egc,
/* Convenience aliases */
const uint32_t domid = dss->domid;
- if (dss->suspend_eventchn > 0)
- xc_suspend_evtchn_release(CTX->xch, dss->xce, domid,
- dss->suspend_eventchn, &dss->guest_evtchn_lockfd);
- if (dss->xce != NULL)
- xc_evtchn_close(dss->xce);
+ libxl__ev_evtchn_cancel(gc, &dss->guest_evtchn);
+
+ if (dss->guest_evtchn.port > 0)
+ xc_suspend_evtchn_release(CTX->xch, CTX->xce, domid,
+ dss->guest_evtchn.port, &dss->guest_evtchn_lockfd);
dss->callback(egc, dss, rc);
}
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 7ad15b5..ceb5af7 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -2416,8 +2416,7 @@ struct libxl__domain_suspend_state {
int debug;
const libxl_domain_remus_info *remus;
/* private */
- xc_evtchn *xce; /* event channel handle */
- int suspend_eventchn;
+ libxl__ev_evtchn guest_evtchn;
int guest_evtchn_lockfd;
int hvm;
int xcflags;
--
1.7.10.4
next prev 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 ` [PATCH 16/19] libxl: suspend: Abolish usleeps in domain suspend wait Ian Jackson
2014-03-13 17:16 ` 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 ` Ian Jackson [this message]
2014-03-13 17:23 ` [PATCH 18/19] libxl: suspend: Async evtchn wait 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-19-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).