qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: Stefan Hajnoczi <stefanha@gmail.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>,
	qemu-devel@nongnu.org, famz@redhat.com, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] [Qemu-block] [PATCH 1/4] block: Expect graph changes in bdrv_parent_drained_begin/end
Date: Wed, 29 Nov 2017 14:55:28 +0100	[thread overview]
Message-ID: <20171129135528.GD3753@localhost.localdomain> (raw)
In-Reply-To: <20171129134408.GB4281@stefanha-x1.localdomain>

[-- Attachment #1: Type: text/plain, Size: 3217 bytes --]

Am 29.11.2017 um 14:44 hat Stefan Hajnoczi geschrieben:
> On Wed, Nov 29, 2017 at 11:25:10AM +0100, Paolo Bonzini wrote:
> > From: Kevin Wolf <kwolf@redhat.com>
> > 
> > The .drained_begin/end callbacks can (directly or indirectly via
> > aio_poll()) cause block nodes to be removed or the current BdrvChild to
> > point to a different child node.
> > 
> > Use QLIST_FOREACH_SAFE() to make sure we don't access invalid
> > BlockDriverStates or accidentally continue iterating the parents of the
> > new child node instead of the node we actually came from.
> > 
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > Tested-by: Jeff Cody <jcody@redhat.com>
> > Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
> > Reviewed-by: Jeff Cody <jcody@redhat.com>
> > ---
> >  block/io.c | 8 ++++----
> >  1 file changed, 4 insertions(+), 4 deletions(-)
> > 
> > diff --git a/block/io.c b/block/io.c
> > index 4fdf93a014..6773926fc1 100644
> > --- a/block/io.c
> > +++ b/block/io.c
> > @@ -42,9 +42,9 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,
> >  
> >  void bdrv_parent_drained_begin(BlockDriverState *bs)
> >  {
> > -    BdrvChild *c;
> > +    BdrvChild *c, *next;
> >  
> > -    QLIST_FOREACH(c, &bs->parents, next_parent) {
> > +    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
> >          if (c->role->drained_begin) {
> >              c->role->drained_begin(c);
> >          }
> > @@ -53,9 +53,9 @@ void bdrv_parent_drained_begin(BlockDriverState *bs)
> >  
> >  void bdrv_parent_drained_end(BlockDriverState *bs)
> >  {
> > -    BdrvChild *c;
> > +    BdrvChild *c, *next;
> >  
> > -    QLIST_FOREACH(c, &bs->parents, next_parent) {
> > +    QLIST_FOREACH_SAFE(c, &bs->parents, next_parent, next) {
> >          if (c->role->drained_end) {
> >              c->role->drained_end(c);
> >          }
> 
> Hmm...not sure if this patch is enough.

Depends on what you have in mind, but generally, no, it's certainly not
enough to fix all bad things that can happen during drain...

> Thinking about this more, if this sub-graph changes then
> .drained_begin() callbacks are not necessarily paired with
> .drained_end() callbacks.
> 
> In other words, all of the following are possible:
> 
> 1. Only .drained_begin() is called
> 2. .drained_begin() is called, then .drained_end()
> 3. Only .drained_end() is called

bdrv_replace_child_noperm() makes sure to call .drained_end() and
.drained_begin() depending on whether the old and new child node are
currently drained. So I think this might actually work.

> It makes me wonder if we need to either:
> 
> Take references and ensure .drained_end() gets called if and only if
> .drained_begin() was also called.
> 
> OR
> 
> Document that .drained_begin/end() calls may not be paired and audit
> existing code to check that this is safe.

How would the latter even possibly work? If the .drained_end is missing,
the parent would never know that it can send new requests again. A
missing .drained_begin could be ignored in the .drained_end callback,
but it wouldn't be safe because the parent wouldn't actually stop to
send new requests.

Kevin

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 801 bytes --]

  reply	other threads:[~2017-11-29 13:55 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-29 10:25 [Qemu-devel] [PATCH 0/4] blockjob: reinstate busy=false/busy=true in block_job_sleep_ns Paolo Bonzini
2017-11-29 10:25 ` [Qemu-devel] [PATCH 1/4] block: Expect graph changes in bdrv_parent_drained_begin/end Paolo Bonzini
2017-11-29 12:27   ` [Qemu-devel] [Qemu-block] " Alberto Garcia
2017-11-29 13:44   ` Stefan Hajnoczi
2017-11-29 13:55     ` Kevin Wolf [this message]
2017-12-01 10:13       ` Stefan Hajnoczi
2017-11-29 10:25 ` [Qemu-devel] [PATCH 2/4] blockjob: remove clock argument from block_job_sleep_ns Paolo Bonzini
2017-11-29 12:45   ` [Qemu-devel] [Qemu-block] " Alberto Garcia
2017-11-29 13:14   ` [Qemu-devel] " Jeff Cody
2017-11-29 13:55   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-11-29 10:25 ` [Qemu-devel] [PATCH 3/4] blockjob: introduce block_job_do_yield Paolo Bonzini
2017-11-29 13:30   ` Jeff Cody
2017-11-29 13:55   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-11-29 10:25 ` [Qemu-devel] [PATCH 4/4] blockjob: reimplement block_job_sleep_ns to allow cancellation Paolo Bonzini
2017-11-29 12:54   ` Kevin Wolf
2017-11-29 13:52     ` Jeff Cody
2017-11-29 13:56   ` Jeff Cody
2017-11-29 14:21     ` Kevin Wolf
2017-11-29 14:25       ` Jeff Cody
2017-11-29 14:07   ` [Qemu-devel] [Qemu-block] " Stefan Hajnoczi
2017-11-29 21:12   ` [Qemu-devel] " Eric Blake
2017-11-29 13:13 ` [Qemu-devel] [PATCH 0/4] blockjob: reinstate busy=false/busy=true in block_job_sleep_ns Jeff Cody
2017-11-29 13:14 ` Fam Zheng

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=20171129135528.GD3753@localhost.localdomain \
    --to=kwolf@redhat.com \
    --cc=famz@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@gmail.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).