qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe
@ 2018-03-06 10:53 Stefan Hajnoczi
  2018-03-06 11:01 ` Paolo Bonzini
  2018-03-06 11:08 ` Kevin Wolf
  0 siblings, 2 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2018-03-06 10:53 UTC (permalink / raw)
  To: qemu-devel
  Cc: Paolo Bonzini, Kevin Wolf, fuweiwei (C), Max Reitz, qemu-block,
	Stefan Hajnoczi

Nested BDRV_POLL_WHILE() calls can occur.  Currently
assert(!bs_->wakeup) will fail when this happens.

This patch converts bs->wakeup from bool to a counter.

Nesting works correctly because outer BDRV_POLL_WHILE() callers evaluate
the condition again after the inner caller completes (invoking the inner
caller counts as aio_poll() progress).

Reported-by: "fuweiwei (C)" <fuweiwei2@huawei.com>
Cc: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
Fu Weiwei: Please retest and let us know if this fixes the assertion
failure you hit.  Thanks!
---
 include/block/block.h     | 7 +++----
 include/block/block_int.h | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/block/block.h b/include/block/block.h
index fac401ba3e..990b97f0ad 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -385,9 +385,8 @@ void bdrv_drain_all(void);
          * other I/O threads' AioContexts (see for example \
          * block_job_defer_to_main_loop for how to do it). \
          */                                                \
-        assert(!bs_->wakeup);                              \
-        /* Set bs->wakeup before evaluating cond.  */      \
-        atomic_mb_set(&bs_->wakeup, true);                 \
+        /* Increment bs->wakeup before evaluating cond. */ \
+        atomic_inc(&bs_->wakeup);                          \
         while (busy_) {                                    \
             if ((cond)) {                                  \
                 waited_ = busy_ = true;                    \
@@ -399,7 +398,7 @@ void bdrv_drain_all(void);
                 waited_ |= busy_;                          \
             }                                              \
         }                                                  \
-        atomic_set(&bs_->wakeup, false);                   \
+        atomic_dec(&bs_->wakeup);                          \
     }                                                      \
     waited_; })
 
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 5ea63f8fa8..0f360c0ed5 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -712,7 +712,7 @@ struct BlockDriverState {
     /* Internal to BDRV_POLL_WHILE and bdrv_wakeup.  Accessed with atomic
      * ops.
      */
-    bool wakeup;
+    unsigned wakeup;
 
     /* counter for nested bdrv_io_plug.
      * Accessed with atomic ops.
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe
  2018-03-06 10:53 [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe Stefan Hajnoczi
@ 2018-03-06 11:01 ` Paolo Bonzini
  2018-03-06 11:08 ` Kevin Wolf
  1 sibling, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2018-03-06 11:01 UTC (permalink / raw)
  To: Stefan Hajnoczi, qemu-devel
  Cc: Kevin Wolf, fuweiwei (C), Max Reitz, qemu-block

On 06/03/2018 11:53, Stefan Hajnoczi wrote:
> Nested BDRV_POLL_WHILE() calls can occur.  Currently
> assert(!bs_->wakeup) will fail when this happens.
> 
> This patch converts bs->wakeup from bool to a counter.
> 
> Nesting works correctly because outer BDRV_POLL_WHILE() callers evaluate
> the condition again after the inner caller completes (invoking the inner
> caller counts as aio_poll() progress).
> 
> Reported-by: "fuweiwei (C)" <fuweiwei2@huawei.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> ---
> Fu Weiwei: Please retest and let us know if this fixes the assertion
> failure you hit.  Thanks!
> ---
>  include/block/block.h     | 7 +++----
>  include/block/block_int.h | 2 +-
>  2 files changed, 4 insertions(+), 5 deletions(-)
> 
> diff --git a/include/block/block.h b/include/block/block.h
> index fac401ba3e..990b97f0ad 100644
> --- a/include/block/block.h
> +++ b/include/block/block.h
> @@ -385,9 +385,8 @@ void bdrv_drain_all(void);
>           * other I/O threads' AioContexts (see for example \
>           * block_job_defer_to_main_loop for how to do it). \
>           */                                                \
> -        assert(!bs_->wakeup);                              \
> -        /* Set bs->wakeup before evaluating cond.  */      \
> -        atomic_mb_set(&bs_->wakeup, true);                 \
> +        /* Increment bs->wakeup before evaluating cond. */ \
> +        atomic_inc(&bs_->wakeup);                          \
>          while (busy_) {                                    \
>              if ((cond)) {                                  \
>                  waited_ = busy_ = true;                    \
> @@ -399,7 +398,7 @@ void bdrv_drain_all(void);
>                  waited_ |= busy_;                          \
>              }                                              \
>          }                                                  \
> -        atomic_set(&bs_->wakeup, false);                   \
> +        atomic_dec(&bs_->wakeup);                          \
>      }                                                      \
>      waited_; })
>  
> diff --git a/include/block/block_int.h b/include/block/block_int.h
> index 5ea63f8fa8..0f360c0ed5 100644
> --- a/include/block/block_int.h
> +++ b/include/block/block_int.h
> @@ -712,7 +712,7 @@ struct BlockDriverState {
>      /* Internal to BDRV_POLL_WHILE and bdrv_wakeup.  Accessed with atomic
>       * ops.
>       */
> -    bool wakeup;
> +    unsigned wakeup;
>  
>      /* counter for nested bdrv_io_plug.
>       * Accessed with atomic ops.
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

At least, the assertion made it fail fast. :)

Paolo

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe
  2018-03-06 10:53 [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe Stefan Hajnoczi
  2018-03-06 11:01 ` Paolo Bonzini
@ 2018-03-06 11:08 ` Kevin Wolf
  2018-03-07 11:35   ` Stefan Hajnoczi
  1 sibling, 1 reply; 4+ messages in thread
From: Kevin Wolf @ 2018-03-06 11:08 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, Paolo Bonzini, fuweiwei (C), Max Reitz, qemu-block

Am 06.03.2018 um 11:53 hat Stefan Hajnoczi geschrieben:
> Nested BDRV_POLL_WHILE() calls can occur.  Currently
> assert(!bs_->wakeup) will fail when this happens.
> 
> This patch converts bs->wakeup from bool to a counter.
> 
> Nesting works correctly because outer BDRV_POLL_WHILE() callers evaluate
> the condition again after the inner caller completes (invoking the inner
> caller counts as aio_poll() progress).
> 
> Reported-by: "fuweiwei (C)" <fuweiwei2@huawei.com>
> Cc: Paolo Bonzini <pbonzini@redhat.com>
> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>

Doesn't this conflict with your own AIO_WAIT_WHILE() patch?

Kevin

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe
  2018-03-06 11:08 ` Kevin Wolf
@ 2018-03-07 11:35   ` Stefan Hajnoczi
  0 siblings, 0 replies; 4+ messages in thread
From: Stefan Hajnoczi @ 2018-03-07 11:35 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel, Paolo Bonzini, fuweiwei (C), Max Reitz, qemu-block

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

On Tue, Mar 06, 2018 at 12:08:44PM +0100, Kevin Wolf wrote:
> Am 06.03.2018 um 11:53 hat Stefan Hajnoczi geschrieben:
> > Nested BDRV_POLL_WHILE() calls can occur.  Currently
> > assert(!bs_->wakeup) will fail when this happens.
> > 
> > This patch converts bs->wakeup from bool to a counter.
> > 
> > Nesting works correctly because outer BDRV_POLL_WHILE() callers evaluate
> > the condition again after the inner caller completes (invoking the inner
> > caller counts as aio_poll() progress).
> > 
> > Reported-by: "fuweiwei (C)" <fuweiwei2@huawei.com>
> > Cc: Paolo Bonzini <pbonzini@redhat.com>
> > Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
> 
> Doesn't this conflict with your own AIO_WAIT_WHILE() patch?

Yes, I wanted this patch to be easy for Weiwei to test without
dependencies.

AIO_WAIT_WHILE() has just hit qemu.git/master, so I'll rebase and send a
v2.

Stefan

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

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-03-07 11:35 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-03-06 10:53 [Qemu-devel] [PATCH] block: make BDRV_POLL_WHILE() re-entrancy safe Stefan Hajnoczi
2018-03-06 11:01 ` Paolo Bonzini
2018-03-06 11:08 ` Kevin Wolf
2018-03-07 11:35   ` 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).