[Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context

Fam Zheng posted 6 patches 8 years, 10 months ago
There is a newer version of this series
[Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Fam Zheng 8 years, 10 months ago
The fact that the bs->aio_context is changing can confuse the dataplane
iothread, because of the now fine granularity aio context lock.
bdrv_drain should rather be a bdrv_drained_begin/end pair, but since
bs->aio_context is changing, we can just use aio_disable_external and
block_job_pause.

Reported-by: Ed Swierk <eswierk@skyportsystems.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Fam Zheng <famz@redhat.com>
---
 block.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/block.c b/block.c
index b8a3011..512515a 100644
--- a/block.c
+++ b/block.c
@@ -4396,11 +4396,14 @@ void bdrv_attach_aio_context(BlockDriverState *bs,
 
 void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
 {
-    AioContext *ctx;
+    AioContext *ctx = bdrv_get_aio_context(bs);
 
+    aio_disable_external(ctx);
+    if (bs->job) {
+        block_job_pause(bs->job);
+    }
     bdrv_drain(bs); /* ensure there are no in-flight requests */
 
-    ctx = bdrv_get_aio_context(bs);
     while (aio_poll(ctx, false)) {
         /* wait for all bottom halves to execute */
     }
@@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
     aio_context_acquire(new_context);
     bdrv_attach_aio_context(bs, new_context);
     aio_context_release(new_context);
+    if (bs->job) {
+        block_job_resume(bs->job);
+    }
+    aio_enable_external(ctx);
 }
 
 void bdrv_add_aio_context_notifier(BlockDriverState *bs,
-- 
2.9.3


Re: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Stefan Hajnoczi 8 years, 10 months ago
On Fri, Apr 07, 2017 at 02:54:12PM +0800, Fam Zheng wrote:
> @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
>      aio_context_acquire(new_context);
>      bdrv_attach_aio_context(bs, new_context);
>      aio_context_release(new_context);
> +    if (bs->job) {
> +        block_job_resume(bs->job);
> +    }

Should this be called before aio_context_release(new_context)?
Re: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Fam Zheng 8 years, 10 months ago
On Fri, 04/07 13:50, Stefan Hajnoczi wrote:
> On Fri, Apr 07, 2017 at 02:54:12PM +0800, Fam Zheng wrote:
> > @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
> >      aio_context_acquire(new_context);
> >      bdrv_attach_aio_context(bs, new_context);
> >      aio_context_release(new_context);
> > +    if (bs->job) {
> > +        block_job_resume(bs->job);
> > +    }
> 
> Should this be called before aio_context_release(new_context)?

Yes, and I'm going to replace it with bdrv_parent_drained_begin() as Kevin
suggested.

Fam

Re: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Kevin Wolf 8 years, 10 months ago
Am 08.04.2017 um 05:43 hat Fam Zheng geschrieben:
> On Fri, 04/07 13:50, Stefan Hajnoczi wrote:
> > On Fri, Apr 07, 2017 at 02:54:12PM +0800, Fam Zheng wrote:
> > > @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
> > >      aio_context_acquire(new_context);
> > >      bdrv_attach_aio_context(bs, new_context);
> > >      aio_context_release(new_context);
> > > +    if (bs->job) {
> > > +        block_job_resume(bs->job);
> > > +    }
> > 
> > Should this be called before aio_context_release(new_context)?
> 
> Yes, and I'm going to replace it with bdrv_parent_drained_begin() as Kevin
> suggested.

I think at the moment bdrv_parent_drained_begin() can't replace it yet,
but you need both.

Kevin

Re: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Fam Zheng 8 years, 10 months ago
On Mon, 04/10 10:06, Kevin Wolf wrote:
> Am 08.04.2017 um 05:43 hat Fam Zheng geschrieben:
> > On Fri, 04/07 13:50, Stefan Hajnoczi wrote:
> > > On Fri, Apr 07, 2017 at 02:54:12PM +0800, Fam Zheng wrote:
> > > > @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
> > > >      aio_context_acquire(new_context);
> > > >      bdrv_attach_aio_context(bs, new_context);
> > > >      aio_context_release(new_context);
> > > > +    if (bs->job) {
> > > > +        block_job_resume(bs->job);
> > > > +    }
> > > 
> > > Should this be called before aio_context_release(new_context)?
> > 
> > Yes, and I'm going to replace it with bdrv_parent_drained_begin() as Kevin
> > suggested.
> 
> I think at the moment bdrv_parent_drained_begin() can't replace it yet,
> but you need both.

I think we have it already, see 600ac6a0e (blockjob: add devops to blockjob
backends):

    bdrv_parent_drained_begin
     -> blk_root_drained_begin
      -> block_job_drained_begin
       -> block_job_pause

Fam

Re: [Qemu-devel] [PATCH v2 4/6] block: Quiesce old aio context during bdrv_set_aio_context
Posted by Kevin Wolf 8 years, 10 months ago
Am 10.04.2017 um 10:45 hat Fam Zheng geschrieben:
> On Mon, 04/10 10:06, Kevin Wolf wrote:
> > Am 08.04.2017 um 05:43 hat Fam Zheng geschrieben:
> > > On Fri, 04/07 13:50, Stefan Hajnoczi wrote:
> > > > On Fri, Apr 07, 2017 at 02:54:12PM +0800, Fam Zheng wrote:
> > > > > @@ -4413,6 +4416,10 @@ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context)
> > > > >      aio_context_acquire(new_context);
> > > > >      bdrv_attach_aio_context(bs, new_context);
> > > > >      aio_context_release(new_context);
> > > > > +    if (bs->job) {
> > > > > +        block_job_resume(bs->job);
> > > > > +    }
> > > > 
> > > > Should this be called before aio_context_release(new_context)?
> > > 
> > > Yes, and I'm going to replace it with bdrv_parent_drained_begin() as Kevin
> > > suggested.
> > 
> > I think at the moment bdrv_parent_drained_begin() can't replace it yet,
> > but you need both.
> 
> I think we have it already, see 600ac6a0e (blockjob: add devops to blockjob
> backends):
> 
>     bdrv_parent_drained_begin
>      -> blk_root_drained_begin
>       -> block_job_drained_begin
>        -> block_job_pause

Ah, yes, you're right. Somehow I thought this was only for 2.10.

Kevin