* [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
@ 2013-10-08 9:58 Stefan Hajnoczi
2013-10-08 12:25 ` Kevin Wolf
2014-03-23 15:56 ` Stefan Hajnoczi
0 siblings, 2 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2013-10-08 9:58 UTC (permalink / raw)
To: qemu-devel; +Cc: mario.dechenno, Paolo Bonzini, Stefan Hajnoczi, Kevin Wolf
glib versions prior to 2.31.0 require an explicit g_thread_init() call
to enable multi-threading.
Failure to initialize threading causes glib to take single-threaded code
paths without synchronization. For example, the g_slice allocator will
crash due to race conditions.
Fix this for all QEMU tool programs (qemu-nbd, qemu-io, qemu-img) by
moving the g_thread_init() call from vl.c:main() into a new
osdep.c:thread_init() constructor function.
thread_init() has __attribute__((constructor)) and is automatically
invoked by the runtime during startup.
We can now drop the "simple" trace backend's g_thread_init() call since
thread_init() already called it.
Note that we must keep coroutine-gthread.c's g_thread_init() call which
is located in a constructor function. There is no guarantee for
constructor function ordering so thread_init() may only be called later.
Reported-by: Mario de Chenno <mario.dechenno@unina2.it>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
trace/simple.c | 9 ---------
util/osdep.c | 18 ++++++++++++++++++
vl.c | 8 --------
3 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/trace/simple.c b/trace/simple.c
index 1e3f691..7833309 100644
--- a/trace/simple.c
+++ b/trace/simple.c
@@ -404,15 +404,6 @@ bool trace_backend_init(const char *events, const char *file)
{
GThread *thread;
- if (!g_thread_supported()) {
-#if !GLIB_CHECK_VERSION(2, 31, 0)
- g_thread_init(NULL);
-#else
- fprintf(stderr, "glib threading failed to initialize.\n");
- exit(1);
-#endif
- }
-
#if !GLIB_CHECK_VERSION(2, 31, 0)
trace_available_cond = g_cond_new();
trace_empty_cond = g_cond_new();
diff --git a/util/osdep.c b/util/osdep.c
index 62072b4..e29ba6f 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -437,6 +437,24 @@ int socket_init(void)
return 0;
}
+/* Ensure that glib is running in multi-threaded mode */
+static void __attribute__((constructor)) thread_init(void)
+{
+ if (!g_thread_supported()) {
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+ /* Old versions of glib require explicit initialization. Failure to do
+ * this results in the single-threaded code paths being taken inside
+ * glib. For example, the g_slice allocator will not be thread-safe
+ * and cause crashes.
+ */
+ g_thread_init(NULL);
+#else
+ fprintf(stderr, "glib threading failed to initialize.\n");
+ exit(1);
+#endif
+ }
+}
+
#ifndef CONFIG_IOVEC
/* helper function for iov_send_recv() */
static ssize_t
diff --git a/vl.c b/vl.c
index 983cdc6..e2dee8e 100644
--- a/vl.c
+++ b/vl.c
@@ -2857,14 +2857,6 @@ int main(int argc, char **argv, char **envp)
error_set_progname(argv[0]);
g_mem_set_vtable(&mem_trace);
- if (!g_thread_supported()) {
-#if !GLIB_CHECK_VERSION(2, 31, 0)
- g_thread_init(NULL);
-#else
- fprintf(stderr, "glib threading failed to initialize.\n");
- exit(1);
-#endif
- }
module_call_init(MODULE_INIT_QOM);
--
1.8.3.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
2013-10-08 9:58 [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools Stefan Hajnoczi
@ 2013-10-08 12:25 ` Kevin Wolf
2013-10-08 13:08 ` Paolo Bonzini
2014-03-23 15:56 ` Stefan Hajnoczi
1 sibling, 1 reply; 6+ messages in thread
From: Kevin Wolf @ 2013-10-08 12:25 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: mario.dechenno, Paolo Bonzini, qemu-devel
Am 08.10.2013 um 11:58 hat Stefan Hajnoczi geschrieben:
> glib versions prior to 2.31.0 require an explicit g_thread_init() call
> to enable multi-threading.
>
> Failure to initialize threading causes glib to take single-threaded code
> paths without synchronization. For example, the g_slice allocator will
> crash due to race conditions.
>
> Fix this for all QEMU tool programs (qemu-nbd, qemu-io, qemu-img) by
> moving the g_thread_init() call from vl.c:main() into a new
> osdep.c:thread_init() constructor function.
>
> thread_init() has __attribute__((constructor)) and is automatically
> invoked by the runtime during startup.
>
> We can now drop the "simple" trace backend's g_thread_init() call since
> thread_init() already called it.
>
> Note that we must keep coroutine-gthread.c's g_thread_init() call which
> is located in a constructor function. There is no guarantee for
> constructor function ordering so thread_init() may only be called later.
The glib documentation says:
Since version 2.24, calling g_thread_init() multiple times is
allowed, but nothing happens except for the first call.
I take that this means previously it wasn't allowed. qemu's configure
checks for a minimum version of 2.12, so we seems to support glib
versions that don't allow g_thread_init() to be called multiple times.
Do we need to protect against this?
Kevin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
2013-10-08 12:25 ` Kevin Wolf
@ 2013-10-08 13:08 ` Paolo Bonzini
2013-10-08 13:58 ` Kevin Wolf
0 siblings, 1 reply; 6+ messages in thread
From: Paolo Bonzini @ 2013-10-08 13:08 UTC (permalink / raw)
To: Kevin Wolf; +Cc: mario.dechenno, qemu-devel, Stefan Hajnoczi
Il 08/10/2013 14:25, Kevin Wolf ha scritto:
> The glib documentation says:
>
> Since version 2.24, calling g_thread_init() multiple times is
> allowed, but nothing happens except for the first call.
>
> I take that this means previously it wasn't allowed. qemu's configure
> checks for a minimum version of 2.12, so we seems to support glib
> versions that don't allow g_thread_init() to be called multiple times.
>
> Do we need to protect against this?
I think that's the point of the "if (!g_thread_supported ())" tests.
Paolo
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
2013-10-08 13:08 ` Paolo Bonzini
@ 2013-10-08 13:58 ` Kevin Wolf
2013-10-09 8:31 ` Stefan Hajnoczi
0 siblings, 1 reply; 6+ messages in thread
From: Kevin Wolf @ 2013-10-08 13:58 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: mario.dechenno, qemu-devel, Stefan Hajnoczi
Am 08.10.2013 um 15:08 hat Paolo Bonzini geschrieben:
> Il 08/10/2013 14:25, Kevin Wolf ha scritto:
> > The glib documentation says:
> >
> > Since version 2.24, calling g_thread_init() multiple times is
> > allowed, but nothing happens except for the first call.
> >
> > I take that this means previously it wasn't allowed. qemu's configure
> > checks for a minimum version of 2.12, so we seems to support glib
> > versions that don't allow g_thread_init() to be called multiple times.
> >
> > Do we need to protect against this?
>
> I think that's the point of the "if (!g_thread_supported ())" tests.
Ah yes, I think you're right. Not the best function name I've ever seen
that glib uses there, but okay.
Kevin
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
2013-10-08 13:58 ` Kevin Wolf
@ 2013-10-09 8:31 ` Stefan Hajnoczi
0 siblings, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2013-10-09 8:31 UTC (permalink / raw)
To: Kevin Wolf; +Cc: mario.dechenno, Paolo Bonzini, qemu-devel
On Tue, Oct 08, 2013 at 03:58:24PM +0200, Kevin Wolf wrote:
> Am 08.10.2013 um 15:08 hat Paolo Bonzini geschrieben:
> > Il 08/10/2013 14:25, Kevin Wolf ha scritto:
> > > The glib documentation says:
> > >
> > > Since version 2.24, calling g_thread_init() multiple times is
> > > allowed, but nothing happens except for the first call.
> > >
> > > I take that this means previously it wasn't allowed. qemu's configure
> > > checks for a minimum version of 2.12, so we seems to support glib
> > > versions that don't allow g_thread_init() to be called multiple times.
> > >
> > > Do we need to protect against this?
> >
> > I think that's the point of the "if (!g_thread_supported ())" tests.
>
> Ah yes, I think you're right. Not the best function name I've ever seen
> that glib uses there, but okay.
That's correct, g_thread_support() is there to initialize once only.
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools
2013-10-08 9:58 [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools Stefan Hajnoczi
2013-10-08 12:25 ` Kevin Wolf
@ 2014-03-23 15:56 ` Stefan Hajnoczi
1 sibling, 0 replies; 6+ messages in thread
From: Stefan Hajnoczi @ 2014-03-23 15:56 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: mario.dechenno, Paolo Bonzini, qemu-devel, Kevin Wolf
On Tue, Oct 08, 2013 at 11:58:31AM +0200, Stefan Hajnoczi wrote:
> glib versions prior to 2.31.0 require an explicit g_thread_init() call
> to enable multi-threading.
>
> Failure to initialize threading causes glib to take single-threaded code
> paths without synchronization. For example, the g_slice allocator will
> crash due to race conditions.
>
> Fix this for all QEMU tool programs (qemu-nbd, qemu-io, qemu-img) by
> moving the g_thread_init() call from vl.c:main() into a new
> osdep.c:thread_init() constructor function.
>
> thread_init() has __attribute__((constructor)) and is automatically
> invoked by the runtime during startup.
>
> We can now drop the "simple" trace backend's g_thread_init() call since
> thread_init() already called it.
>
> Note that we must keep coroutine-gthread.c's g_thread_init() call which
> is located in a constructor function. There is no guarantee for
> constructor function ordering so thread_init() may only be called later.
>
> Reported-by: Mario de Chenno <mario.dechenno@unina2.it>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> trace/simple.c | 9 ---------
> util/osdep.c | 18 ++++++++++++++++++
> vl.c | 8 --------
> 3 files changed, 18 insertions(+), 17 deletions(-)
Applied to my block tree, we need this for QEMU 2.0:
https://github.com/stefanha/qemu/commits/block
Stefan
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2014-03-23 15:57 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-08 9:58 [Qemu-devel] [PATCH] osdep: initialize glib threads in all QEMU tools Stefan Hajnoczi
2013-10-08 12:25 ` Kevin Wolf
2013-10-08 13:08 ` Paolo Bonzini
2013-10-08 13:58 ` Kevin Wolf
2013-10-09 8:31 ` Stefan Hajnoczi
2014-03-23 15:56 ` Stefan Hajnoczi
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).