From: Kevin Wolf <kwolf@redhat.com>
To: Eric Blake <eblake@redhat.com>
Cc: Peter Maydell <peter.maydell@linaro.org>,
Paolo Bonzini <pbonzini@redhat.com>,
"patches@linaro.org" <patches@linaro.org>,
QEMU Developers <qemu-devel@nongnu.org>,
Qemu-block <qemu-block@nongnu.org>, Max Reitz <mreitz@redhat.com>
Subject: Re: [Qemu-devel] [PATCH] tests: Disable test-bdrv-drain
Date: Tue, 9 Oct 2018 11:48:51 +0200 [thread overview]
Message-ID: <20181009094851.GA5407@localhost.localdomain> (raw)
In-Reply-To: <12068340-1ce5-7cf1-afb2-94f3cd2fd109@redhat.com>
Am 08.10.2018 um 21:53 hat Eric Blake geschrieben:
> On 10/8/18 11:40 AM, Kevin Wolf wrote:
> > Am 08.10.2018 um 17:43 hat Peter Maydell geschrieben:
> > > Looking at the backtraces I'm wondering if this is the result of
> > > an implicit reliance on the order in which per-thread destructors
> > > are called (which is left unspecified by POSIX) -- the destructor
> > > function qemu_thread_atexit_run() is called after some other
> > > destructor, but accesses its memory.
> > >
> > > Specifically, the memory it's trying to read looks like
> > > the __thread local variable pollfds_cleanup_notifier in
> > > util/aio-posix.c. So I think what is happening is:
> > > * util/aio-posix.c calls qemu_thread_atexit_add(), passing
> > > it a pointer to a thread-local variable pollfds_cleanup_notifier
> > > * qemu_thread_atexit_add() works by arranging to run the
> > > notifiers when its 'exit_key' variable's destructor is called
> > > * the destructor for pollfds_cleanup_notifier runs before that
> > > for exit_key, and so the qemu_thread_atexit_run() function
> > > ends up touching freed memory
> > >
> > > I'm pretty confident this analysis of the problem is correct:
> > > unfortunately I have no idea what the right way to fix it is...
> >
> > Yes, I agree with your analysis. If __thread variables can be destructed
> > before pthread_key_create() destructors are called (and in particular if
> > the former are implemented in terms of the latter), this implies at
> > least two rules:
> >
> > 1. The Notfier itself can't be a TLS variable
> >
> > 2. The notifier callback can't access any TLS variables
> >
> > Of course, with these restrictions, qemu_thread_atexit_*() with its
> > existing API is as useless as it could be.
> >
> > The best I can think of at the moment would be to use a separate
> > pthread_key_create() (and therefore a separate destructor) for
> > registering each TLS variable, so that the destructor always gets a
> > valid pointer. Maybe move all __thread variables of a file into a single
> > malloced struct to make it more managable (we could then keep a __thread
> > pointer to it for convenience, but only free the struct with the pointer
> > passed by the pthread_key destructor so that we don't have to access
> > __thread variables in the destructor).
>
> pthread_key_create() says that a when a destructor is triggered, it sets the
> value of the key to NULL; but that you can once again set the key back to a
> non-NULL value, and that the implementation will loop at least
> PTHREAD_DESTRUCTOR_ITERATIONS over all destructors or until it has convinced
> the destructors to leave values at NULL. Thus, while you cannot guarantee
> ordering between destructors within a single iteration of the cleanup loop,
> you CAN do some sort of witness locking or down-counter where a destructor
> purposefully calls pthread_setspecific() to revive the value to survive into
> the next iteration of destructor calls, for variables which are known to be
> referenced by other destructors while the witness count is still high
> enough, as a way of imposing order between loops.
Yes, everything that is explicitly managed with pthread_key_create() is
fine. The point is that the destructors for __thread variables aren't
controlled by QEMU, but by the system libraries, so their memory can go
away earlier than other destructors are called.
Kevin
next prev parent reply other threads:[~2018-10-09 9:49 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-05 14:38 [Qemu-devel] [PATCH] tests: Disable test-bdrv-drain Peter Maydell
2018-10-05 14:41 ` Peter Maydell
2018-10-05 16:17 ` Kevin Wolf
2018-10-05 16:54 ` Peter Maydell
2018-10-05 18:09 ` Kevin Wolf
2018-10-08 9:12 ` Peter Maydell
2018-10-08 15:43 ` Peter Maydell
2018-10-08 16:40 ` Kevin Wolf
2018-10-08 17:07 ` Peter Maydell
2018-10-08 19:53 ` Eric Blake
2018-10-09 9:48 ` Kevin Wolf [this message]
2018-10-09 11:16 ` Paolo Bonzini
2018-11-02 13:33 ` Peter Maydell
2018-11-04 22:03 ` Paolo Bonzini
2018-11-05 10:34 ` Peter Maydell
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=20181009094851.GA5407@localhost.localdomain \
--to=kwolf@redhat.com \
--cc=eblake@redhat.com \
--cc=mreitz@redhat.com \
--cc=patches@linaro.org \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.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 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.