All of lore.kernel.org
 help / color / mirror / Atom feed
From: Peter Xu <peterx@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: qemu-devel@nongnu.org, Stefan Hajnoczi <shajnocz@redhat.com>,
	"Daniel P . Berrange" <berrange@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>, Fam Zheng <famz@redhat.com>,
	Jiri Denemark <jdenemar@redhat.com>,
	Juan Quintela <quintela@redhat.com>,
	mdroth@linux.vnet.ibm.com, Eric Blake <eblake@redhat.com>,
	Laurent Vivier <lvivier@redhat.com>,
	marcandre.lureau@redhat.com,
	Markus Armbruster <armbru@redhat.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>
Subject: Re: [Qemu-devel] [RFC v3 01/27] char-io: fix possible race on IOWatchPoll
Date: Tue, 14 Nov 2017 14:09:39 +0800	[thread overview]
Message-ID: <20171114060939.GC6821@xz-mi> (raw)
In-Reply-To: <20171113165211.GG27765@stefanha-x1.localdomain>

On Mon, Nov 13, 2017 at 04:52:11PM +0000, Stefan Hajnoczi wrote:
> On Mon, Nov 06, 2017 at 05:46:17PM +0800, Peter Xu wrote:
> > This is not a problem if we are only having one single loop thread like
> > before.  However, after per-monitor thread is introduced, this is not
> > true any more, and the race can happen.
> > 
> > The race can be triggered with "make check -j8" sometimes:
> 
> Please mention a specific test case that fails.

It was any of the check-qtest-$(TARGET)s that failed.  I'll mention
that in next post.

> 
> > 
> >   qemu-system-x86_64: /root/git/qemu/chardev/char-io.c:91:
> >   io_watch_poll_finalize: Assertion `iwp->src == NULL' failed.
> > 
> > This patch keeps the reference for the watch object when creating in
> > io_add_watch_poll(), so that the object will never be released in the
> > context main loop, especially when the context loop is running in
> > another standalone thread.  Meanwhile, when we want to remove the watch
> > object, we always first detach the watch object from its owner context,
> > then we continue with the cleanup.
> > 
> > Without this patch, calling io_remove_watch_poll() in main loop thread
> > is not thread-safe, since the other per-monitor thread may be modifying
> > the watch object at the same time.
> > 
> > Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Signed-off-by: Peter Xu <peterx@redhat.com>
> > ---
> >  chardev/char-io.c | 16 ++++++++++++++--
> >  1 file changed, 14 insertions(+), 2 deletions(-)
> > 
> > diff --git a/chardev/char-io.c b/chardev/char-io.c
> > index f81052481a..50b5bac704 100644
> > --- a/chardev/char-io.c
> > +++ b/chardev/char-io.c
> > @@ -122,7 +122,6 @@ GSource *io_add_watch_poll(Chardev *chr,
> >      g_free(name);
> >  
> >      g_source_attach(&iwp->parent, context);
> > -    g_source_unref(&iwp->parent);
> >      return (GSource *)iwp;
> >  }
> >  
> > @@ -131,12 +130,25 @@ static void io_remove_watch_poll(GSource *source)
> >      IOWatchPoll *iwp;
> >  
> >      iwp = io_watch_poll_from_source(source);
> > +
> > +    /*
> > +     * Here the order of destruction really matters.  We need to first
> > +     * detach the IOWatchPoll object from the context (which may still
> > +     * be running in another loop thread), only after that could we
> > +     * continue to operate on iwp->src, or there may be race condition
> > +     * between current thread and the context loop thread.
> > +     *
> > +     * Let's blame the glib bug mentioned in commit 2b316774f6
> > +     * ("qemu-char: do not operate on sources from finalize
> > +     * callbacks") for this extra complexity.
> 
> I don't understand how this bug is to blame.  Isn't the problem here a
> race condition between two QEMU threads?

Yes, it is.

The problem is, we won't have the race condition if glib does not have
that bug mentioned.  Then the thread running GMainContext will have
full control of iwp->src destruction, and destruction of it would be
fairly straightforward (unref iwp->src in IOWatchPoll destructor).
Now IIUC we are doing this in a hacky way, say, we destroy iwp->src
explicitly from main thread before quitting (see [1] below, the whole
if clause).

> 
> Why are two threads accessing the watch at the same time?

Here is how I understand:

Firstly we need to tackle with that bug, by an explicit destruction of
iwp->src below; meanwhile when we are destroying it, the GMainContext
can still be running somewhere (it's not happening in current series
since I stopped iothread earlier than this point, however it can still
happen if in the future we don't do that), then we possibly want this
patch.

Again, without this patch, current series should work; however I do
hope this patch can be in, in case someday we want to provide complete
thread safety for Chardevs (now it is not really thread-safe).

> 
> > +     */
> > +    g_source_destroy(&iwp->parent);
> >      if (iwp->src) {
> >          g_source_destroy(iwp->src);
> >          g_source_unref(iwp->src);
> >          iwp->src = NULL;
> >      }

[1]

> > -    g_source_destroy(&iwp->parent);
> > +    g_source_unref(&iwp->parent);
> >  }
> >  
> >  void remove_fd_in_watch(Chardev *chr)
> > -- 
> > 2.13.5
> > 

Thanks,

-- 
Peter Xu

  reply	other threads:[~2017-11-14  6:10 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-06  9:46 [Qemu-devel] [RFC v3 00/27] QMP: out-of-band (OOB) execution support Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 01/27] char-io: fix possible race on IOWatchPoll Peter Xu
2017-11-07  6:43   ` Fam Zheng
2017-11-13 16:52   ` Stefan Hajnoczi
2017-11-14  6:09     ` Peter Xu [this message]
2017-11-14 10:32       ` Stefan Hajnoczi
2017-11-14 11:31         ` Peter Xu
2017-11-15  9:37           ` Stefan Hajnoczi
2017-11-15  9:48             ` Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 02/27] qobject: introduce qstring_get_try_str() Peter Xu
2017-11-07  6:47   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 03/27] qobject: introduce qobject_get_try_str() Peter Xu
2017-11-07  6:48   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 04/27] qobject: let object_property_get_str() use new API Peter Xu
2017-11-07  6:50   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 05/27] monitor: move skip_flush into monitor_data_init Peter Xu
2017-11-07  6:51   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 06/27] qjson: add "opaque" field to JSONMessageParser Peter Xu
2017-11-07  6:54   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 07/27] monitor: move the cur_mon hack deeper for QMP Peter Xu
2017-11-07  6:58   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 08/27] monitor: unify global init Peter Xu
2017-11-07  7:03   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 09/27] monitor: let mon_list be tail queue Peter Xu
2017-11-07  7:05   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 10/27] monitor: create monitor dedicate iothread Peter Xu
2017-11-07  7:11   ` Fam Zheng
2017-11-08  7:25     ` Peter Xu
2017-11-08 11:18       ` Fam Zheng
2017-11-08 11:35         ` Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 11/27] monitor: allow to use IO thread for parsing Peter Xu
2017-11-07  7:17   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 12/27] qmp: introduce QMPCapability Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 13/27] qmp: negociate QMP capabilities Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 14/27] qmp: introduce some capability helpers Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 15/27] monitor: introduce monitor_qmp_respond() Peter Xu
2017-11-07  7:24   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 16/27] monitor: let monitor_{suspend|resume} thread safe Peter Xu
2017-11-07  7:26   ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 17/27] monitor: separate QMP parser and dispatcher Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 18/27] qmp: add new event "request-dropped" Peter Xu
2017-11-15 10:50   ` Stefan Hajnoczi
2017-11-16  5:56     ` Peter Xu
2017-11-16  6:29       ` Peter Xu
2017-11-16  6:49         ` Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 19/27] monitor: send event when request queue full Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 20/27] qapi: introduce new cmd option "allow-oob" Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 21/27] qmp: support out-of-band (oob) execution Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 22/27] qmp: let migrate-incoming allow out-of-band Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 23/27] qmp: isolate responses into io thread Peter Xu
2017-11-07  7:57   ` Fam Zheng
2017-11-08  7:31     ` Peter Xu
2017-11-08 11:16       ` Fam Zheng
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 24/27] monitor: enable IO thread for (qmp & !mux) typed Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 25/27] docs: update QMP documents for OOB commands Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 26/27] tests: qmp-test: verify command batching Peter Xu
2017-11-06  9:46 ` [Qemu-devel] [RFC v3 27/27] tests: qmp-test: add oob test Peter Xu
2017-11-15 10:21   ` Stefan Hajnoczi
2017-11-16  8:02     ` Peter Xu
2017-11-06 10:12 ` [Qemu-devel] [RFC v3 00/27] QMP: out-of-band (OOB) execution support no-reply
2017-11-06 13:08   ` Peter Xu
2017-11-15  9:42     ` Stefan Hajnoczi
2017-11-16  5:32       ` Peter Xu
2017-11-16  5:39         ` Fam Zheng
2017-11-16  6:36           ` Peter Xu

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=20171114060939.GC6821@xz-mi \
    --to=peterx@redhat.com \
    --cc=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=famz@redhat.com \
    --cc=jdenemar@redhat.com \
    --cc=lvivier@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=mdroth@linux.vnet.ibm.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    --cc=shajnocz@redhat.com \
    --cc=stefanha@redhat.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 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.