From: Paolo Bonzini <pbonzini@redhat.com>
To: Stefan Hajnoczi <stefanha@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>,
xiawenc@linux.vnet.ibm.com, qemu-devel@nongnu.org,
Michael Roth <mdroth@linux.vnet.ibm.com>
Subject: Re: [Qemu-devel] [PATCH 0/2] aio: add aio_context_acquire() and aio_context_release()
Date: Wed, 09 Oct 2013 12:16:47 +0200 [thread overview]
Message-ID: <52552D0F.5010804@redhat.com> (raw)
In-Reply-To: <1381312531-28723-1-git-send-email-stefanha@redhat.com>
Il 09/10/2013 11:55, Stefan Hajnoczi ha scritto:
> aio_context_acquire() and aio_context_release() make it possible for multiple
> threads to safely operate on a shared AioContext. This is a prerequisite for
> using the block layer outside the QEMU global mutex.
>
> Imagine that a dataplane thread is performing I/O on behalf of the guest when
> the user issues a monitor command that needs to access the BlockDriverState.
> The monitor thread needs to acquire the AioContext before calling bdrv_*()
> functions on it. This prevents the dataplane thread from interfering with the
> monitor thread.
>
> There was a discussion in the RFC email thread about how to implement fairness:
> each thread should get a turn to acquire the AioContext so that starvation is
> avoided.
>
> Paolo suggested doing what the QEMU main loop does today: drop the lock before
> invoking ppoll(2). It turns out that this is tricky since we want both threads
> to be able to call aio_poll() simultaneously. AioContext->pollfds[] currently
> prevents two simultaneous aio_poll() calls since it is a shared resource. It's
> also tricky to avoid deadlocks if two threads execute aio_poll() simulatenously
> except by waking all threads each time *any* thread makes any progress.
>
> I found the simplest solution is to implement RFifoLock, a recursive lock with
> FIFO ordering. This lock supports the semantics we need for the following
> pattern:
>
> /* Event loop thread */
> while (running) {
> aio_context_acquire(ctx);
> aio_poll(ctx, true);
> aio_context_release(ctx);
> }
>
> /* Another thread */
> aio_context_acquire(ctx);
> bdrv_read(bs, 0x1000, buf, 1);
> aio_context_release(ctx);
Should bdrv_read itself call aio_context_acquire? If not, what's the
use of recursion?
> When the other thread wants to acquire the AioContext but the lock is
> contended, it uses aio_notify(ctx) to bump the event loop thread out of
> aio_poll(). Fairness ensures everyone gets an opportunity to use the
> AioContext.
The implementation of fairness is very nice. The callbacks are an
interesting solution, too. They ensure that the lock is released fast,
but at the same time some progress is allowed.
I don't like recursive mutexes very much, because it's easier to get
AB-BA deadlocks with them. However, it's not easy to avoid them except
by adding a lot of acquire/release pairs. And there's also a precedent
(the mmap_lock used by user-level emulation).
We can avoid the problem for now by heavily limiting the coarse-grained
mutexes we have---basically only the iothread mutex and this new lock.
We should aim at making locks fine-grained enough that we hardly have
any nesting, or use RCU so that the read-side is independent and the
write-side can just keep using the iothread mutex.
Still, in the long run it would be nice to push acquire/release pairs up
to all the users and avoid recursion...
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Paolo
next prev parent reply other threads:[~2013-10-09 10:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-10-09 9:55 [Qemu-devel] [PATCH 0/2] aio: add aio_context_acquire() and aio_context_release() Stefan Hajnoczi
2013-10-09 9:55 ` [Qemu-devel] [PATCH 1/2] rfifolock: add recursive FIFO lock Stefan Hajnoczi
2013-10-09 10:05 ` Paolo Bonzini
2013-10-09 11:26 ` Stefan Hajnoczi
2013-10-09 11:36 ` Paolo Bonzini
2013-10-11 8:55 ` Wenchao Xia
2013-10-11 13:35 ` Stefan Hajnoczi
2013-10-12 2:48 ` Wenchao Xia
2013-10-09 9:55 ` [Qemu-devel] [PATCH 2/2] aio: add aio_context_acquire() and aio_context_release() Stefan Hajnoczi
2013-10-11 8:52 ` Wenchao Xia
2013-10-09 10:16 ` Paolo Bonzini [this message]
2013-10-09 11:32 ` [Qemu-devel] [PATCH 0/2] " Stefan Hajnoczi
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=52552D0F.5010804@redhat.com \
--to=pbonzini@redhat.com \
--cc=kwolf@redhat.com \
--cc=mdroth@linux.vnet.ibm.com \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
--cc=xiawenc@linux.vnet.ibm.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 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).