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
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)?
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
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
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
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
© 2016 - 2026 Red Hat, Inc.