[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] libxl: suspend: Abolish usleeps in domain suspend wait
commit 926e112b20bd6b928df43c6674404e8353e57915 Author: Ian Jackson <ian.jackson@xxxxxxxxxxxxx> AuthorDate: Fri Dec 6 16:12:44 2013 +0000 Commit: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CommitDate: Mon Mar 17 15:54:00 2014 +0000 libxl: suspend: Abolish usleeps in domain suspend wait 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 be on xenstore, rather than polling. Signed-off-by: Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx> CC: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx> Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx> --- v3: Remove some trailing whitespace Improve commit message. v3X: Do NOT use an xswait instead of separate watch and timeout. --- 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 0c48159..5d6dcc4 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, @@ -1176,36 +1182,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); } @@ -1215,6 +1244,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) { @@ -1238,6 +1270,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); } @@ -1424,6 +1458,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 479edb7..a67ea3c 100644 --- a/tools/libxl/libxl_internal.h +++ b/tools/libxl/libxl_internal.h @@ -2445,6 +2445,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; -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |