xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Ian Jackson <ian.jackson@eu.citrix.com>
To: xen-devel@lists.xen.org
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Subject: [PATCH 21/27] libxl: Fix an ao completion bug; document locking policy
Date: Fri, 11 May 2012 18:58:06 +0100	[thread overview]
Message-ID: <1336759092-2432-22-git-send-email-ian.jackson@eu.citrix.com> (raw)
In-Reply-To: <1336759092-2432-1-git-send-email-ian.jackson@eu.citrix.com>

Document the concurrent access policies for libxl__ao and libxl__egc,
and their corresponding gcs.

Fix a violation of the policy:

If an ao was submitted and a callback requested, and while the
initiating function was still running on the original thread, the ao
is completed on another thread, the completing thread would improperly
concurrently access the ao with the initiating thread.

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 tools/libxl/libxl_event.c    |    7 +++++++
 tools/libxl/libxl_internal.h |   23 ++++++++++++++++++++++-
 2 files changed, 29 insertions(+), 1 deletions(-)

diff --git a/tools/libxl/libxl_event.c b/tools/libxl/libxl_event.c
index 3e784f0..b546471 100644
--- a/tools/libxl/libxl_event.c
+++ b/tools/libxl/libxl_event.c
@@ -901,6 +901,11 @@ void libxl__event_disaster(libxl__egc *egc, const char *msg, int errnoval,
 
 static void egc_run_callbacks(libxl__egc *egc)
 {
+    /*
+     * The callbacks must happen with the ctx unlocked.
+     * See the comment near #define EGC_GC in libxl_internal.h and
+     * those in the definitions of libxl__egc and libxl__ao.
+     */
     EGC_GC;
     libxl_event *ev, *ev_tmp;
 
@@ -914,9 +919,11 @@ static void egc_run_callbacks(libxl__egc *egc)
                              entry_for_callback, ao_tmp) {
         LIBXL_TAILQ_REMOVE(&egc->aos_for_callback, ao, entry_for_callback);
         ao->how.callback(CTX, ao->rc, ao->how.u.for_callback);
+        CTX_LOCK;
         ao->notified = 1;
         if (!ao->in_initiator)
             libxl__ao__destroy(CTX, ao);
+        CTX_UNLOCK;
     }
 }
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 9b4c273..f48cfdc 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -359,7 +359,8 @@ struct libxl__gc {
 };
 
 struct libxl__egc {
-    /* for event-generating functions only */
+    /* For event-generating functions only.
+     * The egc and its gc may be accessed only on the creating thread. */
     struct libxl__gc gc;
     struct libxl__event_list occurred_for_callback;
     LIBXL_TAILQ_HEAD(, libxl__ao) aos_for_callback;
@@ -369,6 +370,20 @@ struct libxl__egc {
 #define LIBXL__AO_MAGIC_DESTROYED    0xA0DEAD00ul
 
 struct libxl__ao {
+    /*
+     * An ao and its gc may be accessed only with the ctx lock held.
+     *
+     * Special exception: If an ao has been added to
+     * egc->aos_for_callback, the thread owning the egc may remove the
+     * ao from that list and make the callback without holding the
+     * lock.
+     *
+     * Corresponding restriction: An ao may be added only to one
+     * egc->aos_for_callback, once; rc and how must already have been
+     * set and may not be subsequently modified.  (This restriction is
+     * easily and obviously met since the ao is queued for callback
+     * only in libxl__ao_complete.)
+     */
     uint32_t magic;
     unsigned constructing:1, in_initiator:1, complete:1, notified:1;
     int rc;
@@ -1365,6 +1380,12 @@ libxl__device_model_version_running(libxl__gc *gc, uint32_t domid);
  * should in any case not find it necessary to call egc-creators from
  * within libxl.
  *
+ * The callbacks must all take place with the ctx unlocked because
+ * the application is entitled to reenter libxl from them.  This
+ * would be bad not because the lock is not recursive (it is) but
+ * because the application might make blocking libxl calls which
+ * would hold the lock unreasonably long.
+ *
  * For the same reason libxl__egc_cleanup (or EGC_FREE) must be called
  * with the ctx *unlocked*.  So the right pattern has the EGC_...
  * macro calls on the outside of the CTX_... ones.
-- 
1.7.2.5

  parent reply	other threads:[~2012-05-11 17:58 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-11 17:57 [PATCH v9 00/27] libxl: child process handling Ian Jackson
2012-05-11 17:57 ` [PATCH 01/27] libxl: handle POLLERR, POLLHUP, POLLNVAL properly Ian Jackson
2012-05-11 17:57 ` [PATCH 02/27] libxl: support multiple libxl__ev_fds for the same fd Ian Jackson
2012-05-11 17:57 ` [PATCH 03/27] libxl: event API: new facilities for waiting for subprocesses Ian Jackson
2012-05-11 17:57 ` [PATCH 04/27] autoconf: trim the configure script; use autoheader Ian Jackson
2012-05-11 17:57 ` [PATCH 05/27] autoconf: New test for openpty et al Ian Jackson
2012-05-11 17:57 ` [PATCH 06/27] libxl: provide libxl__remove_file " Ian Jackson
2012-05-11 17:57 ` [PATCH 07/27] libxl: Introduce libxl__sendmsg_fds and libxl__recvmsg_fds Ian Jackson
2012-05-11 17:57 ` [PATCH 08/27] libxl: Clean up setdefault in do_domain_create Ian Jackson
2012-05-11 17:57 ` [PATCH 09/27] libxl: provide libxl__datacopier_* Ian Jackson
2012-05-11 17:57 ` [PATCH 10/27] libxl: provide libxl__openpty_* Ian Jackson
2012-05-11 17:57 ` [PATCH 11/27] libxl: ao: Convert libxl_run_bootloader Ian Jackson
2012-05-11 17:57 ` [PATCH 12/27] libxl: make libxl_create_logfile const-correct Ian Jackson
2012-05-11 17:57 ` [PATCH 13/27] libxl: log bootloader output Ian Jackson
2012-05-11 17:57 ` [PATCH 14/27] libxl: Allow AO_GC and EGC_GC even if not used Ian Jackson
2012-05-11 17:58 ` [PATCH 15/27] libxl: add a dummy ao_how to libxl_domain_core_dump Ian Jackson
2012-05-11 17:58 ` [PATCH 16/27] libxl: remove ctx->waitpid_instead Ian Jackson
2012-05-11 17:58 ` [PATCH 17/27] libxl: change some structures to unit arrays Ian Jackson
2012-05-11 17:58 ` [PATCH 18/27] libxl: ao: convert libxl__spawn_* Ian Jackson
2012-05-11 17:58 ` [PATCH 19/27] libxl: set guest_domid even if libxl__domain_make fails Ian Jackson
2012-05-11 17:58 ` [PATCH 20/27] libxl: make libxl_create run bootloader via callback Ian Jackson
2012-05-11 17:58 ` Ian Jackson [this message]
2012-05-11 17:58 ` [PATCH 22/27] libxl: provide progress reporting for long-running operations Ian Jackson
2012-05-11 17:58 ` [PATCH 23/27] libxl: remove malloc failure handling from NEW_EVENT Ian Jackson
2012-05-11 17:58 ` [PATCH 24/27] libxl: convert console callback to libxl_asyncprogress_how Ian Jackson
2012-05-11 17:58 ` [PATCH 25/27] libxl: clarify definition of "slow" operation Ian Jackson
2012-05-11 17:58 ` [PATCH 26/27] libxl: child processes cleanups Ian Jackson
2012-05-11 17:58 ` [PATCH 27/27] libxl: abort bootloader invocation when domain dies 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=1336759092-2432-22-git-send-email-ian.jackson@eu.citrix.com \
    --to=ian.jackson@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /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).