* [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
@ 2016-04-11 14:14 Stefan Hajnoczi
2016-05-09 16:48 ` Paolo Bonzini
2016-05-17 10:52 ` Max Reitz
0 siblings, 2 replies; 9+ messages in thread
From: Stefan Hajnoczi @ 2016-04-11 14:14 UTC (permalink / raw)
To: qemu-devel; +Cc: Max Reitz, Kevin Wolf, Paolo Bonzini, Stefan Hajnoczi
blk_get/set_aio_context() delegate to BlockDriverState without storing
the AioContext pointer in BlockBackend.
There are two flaws:
1. BlockBackend falls back to the QEMU main loop AioContext when there
is no root BlockDriverState. This means the drive loses its
AioContext during media change and would break dataplane.
2. BlockBackend state used from multiple threads has no lock. Race
conditions will creep in as functionality is moved from
BlockDriverState to BlockBackend due to the absense of a lock. The
monitor cannot access BlockBackend state safely while an IOThread is
also accessing the state.
Both issue #1 and #2 are mostly theoretical at the moment. I haven't
figured out a way to trigger #1 with virtio-blk (does not support media
change) or virtio-scsi (blocks the eject operation). #2 may be possible
with block accounting statistics in BlockBackend but I'm not aware of a
crash that can be triggered.
This patch stores the AioContext pointer in BlockBackend and puts newly
inserted BlockDriverStates into the AioContext.
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
block/block-backend.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index d74f670..e39c583 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -30,6 +30,7 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
struct BlockBackend {
char *name;
int refcnt;
+ AioContext *aio_context;
BdrvChild *root;
DriveInfo *legacy_dinfo; /* null unless created by drive_new() */
QTAILQ_ENTRY(BlockBackend) link; /* for block_backends */
@@ -106,6 +107,7 @@ BlockBackend *blk_new(Error **errp)
blk = g_new0(BlockBackend, 1);
blk->refcnt = 1;
+ blk->aio_context = qemu_get_aio_context();
notifier_list_init(&blk->remove_bs_notifiers);
notifier_list_init(&blk->insert_bs_notifiers);
QTAILQ_INSERT_TAIL(&block_backends, blk, link);
@@ -433,6 +435,7 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
{
assert(!blk->root && !bs->blk);
bdrv_ref(bs);
+ bdrv_set_aio_context(bs, blk->aio_context);
blk->root = bdrv_root_attach_child(bs, "root", &child_root);
bs->blk = blk;
@@ -1348,13 +1351,7 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
AioContext *blk_get_aio_context(BlockBackend *blk)
{
- BlockDriverState *bs = blk_bs(blk);
-
- if (bs) {
- return bdrv_get_aio_context(bs);
- } else {
- return qemu_get_aio_context();
- }
+ return blk->aio_context;
}
static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
@@ -1367,6 +1364,8 @@ void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
{
BlockDriverState *bs = blk_bs(blk);
+ blk->aio_context = new_context;
+
if (bs) {
bdrv_set_aio_context(bs, new_context);
}
--
2.5.5
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-04-11 14:14 [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend Stefan Hajnoczi
@ 2016-05-09 16:48 ` Paolo Bonzini
2016-05-10 9:33 ` Stefan Hajnoczi
2016-05-17 10:52 ` Max Reitz
1 sibling, 1 reply; 9+ messages in thread
From: Paolo Bonzini @ 2016-05-09 16:48 UTC (permalink / raw)
To: Stefan Hajnoczi, qemu-devel; +Cc: Max Reitz, Kevin Wolf
On 11/04/2016 16:14, Stefan Hajnoczi wrote:
> 1. BlockBackend falls back to the QEMU main loop AioContext when there
> is no root BlockDriverState. This means the drive loses its
> AioContext during media change and would break dataplane.
>
> 2. BlockBackend state used from multiple threads has no lock. Race
> conditions will creep in as functionality is moved from
> BlockDriverState to BlockBackend due to the absense of a lock. The
> monitor cannot access BlockBackend state safely while an IOThread is
> also accessing the state.
>
> Both issue #1 and #2 are mostly theoretical at the moment. I haven't
> figured out a way to trigger #1 with virtio-blk (does not support media
> change) or virtio-scsi (blocks the eject operation). #2 may be possible
> with block accounting statistics in BlockBackend but I'm not aware of a
> crash that can be triggered.
I'm not sure I agree with #2, as we should move away for the
super-coarse AioContext lock (it is heavyweight and it doesn't play well
with multiqueue). Atomics can be used for statistics, while the
time-based accounting probably should be made optional because it's
heavy-weight and hard to scale.
But I do agree with #1, so the idea seems good.
Paolo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-05-09 16:48 ` Paolo Bonzini
@ 2016-05-10 9:33 ` Stefan Hajnoczi
2016-05-10 10:38 ` Paolo Bonzini
0 siblings, 1 reply; 9+ messages in thread
From: Stefan Hajnoczi @ 2016-05-10 9:33 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Stefan Hajnoczi, qemu-devel, Kevin Wolf, Max Reitz
[-- Attachment #1: Type: text/plain, Size: 1493 bytes --]
On Mon, May 09, 2016 at 06:48:12PM +0200, Paolo Bonzini wrote:
>
>
> On 11/04/2016 16:14, Stefan Hajnoczi wrote:
> > 1. BlockBackend falls back to the QEMU main loop AioContext when there
> > is no root BlockDriverState. This means the drive loses its
> > AioContext during media change and would break dataplane.
> >
> > 2. BlockBackend state used from multiple threads has no lock. Race
> > conditions will creep in as functionality is moved from
> > BlockDriverState to BlockBackend due to the absense of a lock. The
> > monitor cannot access BlockBackend state safely while an IOThread is
> > also accessing the state.
> >
> > Both issue #1 and #2 are mostly theoretical at the moment. I haven't
> > figured out a way to trigger #1 with virtio-blk (does not support media
> > change) or virtio-scsi (blocks the eject operation). #2 may be possible
> > with block accounting statistics in BlockBackend but I'm not aware of a
> > crash that can be triggered.
>
> I'm not sure I agree with #2, as we should move away for the
> super-coarse AioContext lock (it is heavyweight and it doesn't play well
> with multiqueue). Atomics can be used for statistics, while the
> time-based accounting probably should be made optional because it's
> heavy-weight and hard to scale.
>
> But I do agree with #1, so the idea seems good.
I agree that lightweight options are nicer. Should I resend without #2
in the commit description?
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-05-10 9:33 ` Stefan Hajnoczi
@ 2016-05-10 10:38 ` Paolo Bonzini
2016-05-11 13:24 ` Stefan Hajnoczi
0 siblings, 1 reply; 9+ messages in thread
From: Paolo Bonzini @ 2016-05-10 10:38 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: Stefan Hajnoczi, qemu-devel, Kevin Wolf, Max Reitz
On 10/05/2016 11:33, Stefan Hajnoczi wrote:
>> >
>> > I'm not sure I agree with #2, as we should move away for the
>> > super-coarse AioContext lock (it is heavyweight and it doesn't play well
>> > with multiqueue). Atomics can be used for statistics, while the
>> > time-based accounting probably should be made optional because it's
>> > heavy-weight and hard to scale.
>> >
>> > But I do agree with #1, so the idea seems good.
> I agree that lightweight options are nicer. Should I resend without #2
> in the commit description?
Well, it _is_ a valid concern until someone does the work. :)
Paolo
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-05-10 10:38 ` Paolo Bonzini
@ 2016-05-11 13:24 ` Stefan Hajnoczi
0 siblings, 0 replies; 9+ messages in thread
From: Stefan Hajnoczi @ 2016-05-11 13:24 UTC (permalink / raw)
To: Paolo Bonzini; +Cc: Stefan Hajnoczi, qemu-devel, Kevin Wolf, Max Reitz
[-- Attachment #1: Type: text/plain, Size: 760 bytes --]
On Tue, May 10, 2016 at 12:38:17PM +0200, Paolo Bonzini wrote:
> On 10/05/2016 11:33, Stefan Hajnoczi wrote:
> >> >
> >> > I'm not sure I agree with #2, as we should move away for the
> >> > super-coarse AioContext lock (it is heavyweight and it doesn't play well
> >> > with multiqueue). Atomics can be used for statistics, while the
> >> > time-based accounting probably should be made optional because it's
> >> > heavy-weight and hard to scale.
> >> >
> >> > But I do agree with #1, so the idea seems good.
> > I agree that lightweight options are nicer. Should I resend without #2
> > in the commit description?
>
> Well, it _is_ a valid concern until someone does the work. :)
Okay, then the patch is fine as-is.
Thanks,
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-04-11 14:14 [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend Stefan Hajnoczi
2016-05-09 16:48 ` Paolo Bonzini
@ 2016-05-17 10:52 ` Max Reitz
2016-05-17 11:07 ` Paolo Bonzini
1 sibling, 1 reply; 9+ messages in thread
From: Max Reitz @ 2016-05-17 10:52 UTC (permalink / raw)
To: Stefan Hajnoczi, qemu-devel; +Cc: Kevin Wolf, Paolo Bonzini
[-- Attachment #1: Type: text/plain, Size: 1955 bytes --]
On 11.04.2016 16:14, Stefan Hajnoczi wrote:
> blk_get/set_aio_context() delegate to BlockDriverState without storing
> the AioContext pointer in BlockBackend.
>
> There are two flaws:
>
> 1. BlockBackend falls back to the QEMU main loop AioContext when there
> is no root BlockDriverState. This means the drive loses its
> AioContext during media change and would break dataplane.
>
> 2. BlockBackend state used from multiple threads has no lock. Race
> conditions will creep in as functionality is moved from
> BlockDriverState to BlockBackend due to the absense of a lock. The
> monitor cannot access BlockBackend state safely while an IOThread is
> also accessing the state.
>
> Both issue #1 and #2 are mostly theoretical at the moment. I haven't
> figured out a way to trigger #1 with virtio-blk (does not support media
> change) or virtio-scsi (blocks the eject operation). #2 may be possible
> with block accounting statistics in BlockBackend but I'm not aware of a
> crash that can be triggered.
>
> This patch stores the AioContext pointer in BlockBackend and puts newly
> inserted BlockDriverStates into the AioContext.
>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> block/block-backend.c | 13 ++++++-------
> 1 file changed, 6 insertions(+), 7 deletions(-)
We can have multiple BBs per BDS tree, and in the future (after Kevin's
"block: Remove BlockDriverState.blk" series) we may even have multiple
BBs per BDS. Therefore, we have to make sure to propagate the AIO
context to all BBs attached to the BDS tree, just as the AIO context is
propagated to all BDSs in the BDS tree.
A trivial way to do this would be to query the BDS's AIO context in
blk_get_aio_context() and update the BB's context if they don't match.
The more correct way would probably be to make bdrv_attach_aio_context()
update its BB's (or BBs', in the future) AIO context.
Max
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-05-17 10:52 ` Max Reitz
@ 2016-05-17 11:07 ` Paolo Bonzini
2016-05-17 11:14 ` Max Reitz
0 siblings, 1 reply; 9+ messages in thread
From: Paolo Bonzini @ 2016-05-17 11:07 UTC (permalink / raw)
To: Max Reitz, Stefan Hajnoczi, qemu-devel; +Cc: Kevin Wolf
[-- Attachment #1: Type: text/plain, Size: 399 bytes --]
On 17/05/2016 12:52, Max Reitz wrote:
> A trivial way to do this would be to query the BDS's AIO context in
> blk_get_aio_context() and update the BB's context if they don't match.
> The more correct way would probably be to make bdrv_attach_aio_context()
> update its BB's (or BBs', in the future) AIO context.
That could be another BdrvChild member, couldn't it?
Thanks,
Paolo
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend
2016-05-17 11:07 ` Paolo Bonzini
@ 2016-05-17 11:14 ` Max Reitz
2016-05-17 11:37 ` Paolo Bonzini
0 siblings, 1 reply; 9+ messages in thread
From: Max Reitz @ 2016-05-17 11:14 UTC (permalink / raw)
To: Paolo Bonzini, Stefan Hajnoczi, qemu-devel; +Cc: Kevin Wolf
[-- Attachment #1: Type: text/plain, Size: 665 bytes --]
On 17.05.2016 13:07, Paolo Bonzini wrote:
>
>
> On 17/05/2016 12:52, Max Reitz wrote:
>> A trivial way to do this would be to query the BDS's AIO context in
>> blk_get_aio_context() and update the BB's context if they don't match.
>> The more correct way would probably be to make bdrv_attach_aio_context()
>> update its BB's (or BBs', in the future) AIO context.
>
> That could be another BdrvChild member, couldn't it?
I think it would rather require a new function pointer in BdrvChildRole
(after Kevin's series, that is). As a side effect, that would allow us
to propagate the context even up the BDS tree, which we currently do not.
Max
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 473 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2016-05-17 11:37 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-11 14:14 [Qemu-devel] [RFC for-2.7] block: keep AioContext pointer in BlockBackend Stefan Hajnoczi
2016-05-09 16:48 ` Paolo Bonzini
2016-05-10 9:33 ` Stefan Hajnoczi
2016-05-10 10:38 ` Paolo Bonzini
2016-05-11 13:24 ` Stefan Hajnoczi
2016-05-17 10:52 ` Max Reitz
2016-05-17 11:07 ` Paolo Bonzini
2016-05-17 11:14 ` Max Reitz
2016-05-17 11:37 ` Paolo Bonzini
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).