* [Qemu-devel] [PATCH v2 0/2] block, virtio-scsi: Fix blk_set_aio_context @ 2015-02-15 2:40 Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 2/2] virtio-scsi-dataplane: Call blk_set_aio_context within BQL Fam Zheng 0 siblings, 2 replies; 4+ messages in thread From: Fam Zheng @ 2015-02-15 2:40 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, Paolo Bonzini, stefanha This is the simplified fix of: [PATCH 0/3] virtio-scsi: Fix unsafe bdrv_set_aio_context calls I included the original patch 1 - the function header comment update for bdrv_set_aio_context and added Paolo's rev-by. Fam Zheng (2): block: Forbid bdrv_set_aio_context outside BQL virtio-scsi-dataplane: Call blk_set_aio_context within BQL hw/scsi/virtio-scsi.c | 15 +++++++-------- include/block/block.h | 3 +-- 2 files changed, 8 insertions(+), 10 deletions(-) -- 2.1.0 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL 2015-02-15 2:40 [Qemu-devel] [PATCH v2 0/2] block, virtio-scsi: Fix blk_set_aio_context Fam Zheng @ 2015-02-15 2:40 ` Fam Zheng 2015-02-15 3:05 ` Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 2/2] virtio-scsi-dataplane: Call blk_set_aio_context within BQL Fam Zheng 1 sibling, 1 reply; 4+ messages in thread From: Fam Zheng @ 2015-02-15 2:40 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, Paolo Bonzini, stefanha Even if the caller has the old #AioContext, there can be a deadlock, due to the leading bdrv_drain_all: Suppose there are three io threads (a, b, c) with each owning a BDS (bds_a, bds_b, bds_c), and a and b want to move their own BDS to c at the same time: iothread a iothread b -------------------------------------------------------------------------- bdrv_set_aio_context(bds_a, c) bdrv_set_aio_context(bds_b, c) -> bdrv_drain_all() -> bdrv_drain_all() -> acquire a (OK, already has) -> acquire a (blocked) -> acquire b (blocked) -> acquire b -> acquire c -> acquire c Current caller of bdrv_set_aio_context outside BQL is virtio-scsi-dataplane, which will be fixed in the next patches. Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> --- include/block/block.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/block/block.h b/include/block/block.h index 321295e..4fce25d 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -546,8 +546,7 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs); * Changes the #AioContext used for fd handlers, timers, and BHs by this * BlockDriverState and all its children. * - * This function must be called from the old #AioContext or with a lock held so - * the old #AioContext is not executing. + * This function must be called with iothread lock held. */ void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context); -- 2.1.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL Fam Zheng @ 2015-02-15 3:05 ` Fam Zheng 0 siblings, 0 replies; 4+ messages in thread From: Fam Zheng @ 2015-02-15 3:05 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, Paolo Bonzini, stefanha On Sun, 02/15 10:40, Fam Zheng wrote: > Even if the caller has the old #AioContext, there can be a deadlock, due > to the leading bdrv_drain_all: > > Suppose there are three io threads (a, b, c) with each owning a BDS > (bds_a, bds_b, bds_c), and a and b want to move their own BDS to c at > the same time: > > iothread a iothread b > -------------------------------------------------------------------------- > bdrv_set_aio_context(bds_a, c) bdrv_set_aio_context(bds_b, c) > -> bdrv_drain_all() -> bdrv_drain_all() > -> acquire a (OK, already has) -> acquire a (blocked) > -> acquire b (blocked) -> acquire b > -> acquire c -> acquire c This doesn't recap the essence of the bug because one may argue that aio_context_acquire(c) is needed before either thread calling bdrv_set_aio_context. Actually it doesn't matter in this case, because iothread b can as well do bdrv_set_aio_context(bds_b, d). I'll update the commit log with v3. Fam > > Current caller of bdrv_set_aio_context outside BQL is > virtio-scsi-dataplane, which will be fixed in the next patches. > > Signed-off-by: Fam Zheng <famz@redhat.com> > Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> > --- > include/block/block.h | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/include/block/block.h b/include/block/block.h > index 321295e..4fce25d 100644 > --- a/include/block/block.h > +++ b/include/block/block.h > @@ -546,8 +546,7 @@ AioContext *bdrv_get_aio_context(BlockDriverState *bs); > * Changes the #AioContext used for fd handlers, timers, and BHs by this > * BlockDriverState and all its children. > * > - * This function must be called from the old #AioContext or with a lock held so > - * the old #AioContext is not executing. > + * This function must be called with iothread lock held. > */ > void bdrv_set_aio_context(BlockDriverState *bs, AioContext *new_context); > > -- > 2.1.0 > > ^ permalink raw reply [flat|nested] 4+ messages in thread
* [Qemu-devel] [PATCH v2 2/2] virtio-scsi-dataplane: Call blk_set_aio_context within BQL 2015-02-15 2:40 [Qemu-devel] [PATCH v2 0/2] block, virtio-scsi: Fix blk_set_aio_context Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL Fam Zheng @ 2015-02-15 2:40 ` Fam Zheng 1 sibling, 0 replies; 4+ messages in thread From: Fam Zheng @ 2015-02-15 2:40 UTC (permalink / raw) To: qemu-devel; +Cc: kwolf, Paolo Bonzini, stefanha It's not safe to call blk_set_aio_context from outside BQL because of the bdrv_drain_all there. Let's put it in the hotplug callback which will be called by qdev device realization for each scsi device attached to the bus. Signed-off-by: Fam Zheng <famz@redhat.com> --- hw/scsi/virtio-scsi.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 9e2c718..8c437dd 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -254,10 +254,8 @@ static int virtio_scsi_do_tmf(VirtIOSCSI *s, VirtIOSCSIReq *req) int target; int ret = 0; - if (s->dataplane_started && blk_get_aio_context(d->conf.blk) != s->ctx) { - aio_context_acquire(s->ctx); - blk_set_aio_context(d->conf.blk, s->ctx); - aio_context_release(s->ctx); + if (s->dataplane_started) { + assert(blk_get_aio_context(d->conf.blk) == s->ctx); } /* Here VIRTIO_SCSI_S_OK means "FUNCTION COMPLETE". */ req->resp.tmf.response = VIRTIO_SCSI_S_OK; @@ -540,10 +538,8 @@ bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req) virtio_scsi_complete_cmd_req(req); return false; } - if (s->dataplane_started && blk_get_aio_context(d->conf.blk) != s->ctx) { - aio_context_acquire(s->ctx); - blk_set_aio_context(d->conf.blk, s->ctx); - aio_context_release(s->ctx); + if (s->dataplane_started) { + assert(blk_get_aio_context(d->conf.blk) == s->ctx); } req->sreq = scsi_req_new(d, req->req.cmd.tag, virtio_scsi_get_lun(req->req.cmd.lun), @@ -767,6 +763,9 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, return; } blk_op_block_all(sd->conf.blk, s->blocker); + aio_context_acquire(s->ctx); + blk_set_aio_context(sd->conf.blk, s->ctx); + aio_context_release(s->ctx); } if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) { -- 2.1.0 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2015-02-15 3:05 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-02-15 2:40 [Qemu-devel] [PATCH v2 0/2] block, virtio-scsi: Fix blk_set_aio_context Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 1/2] block: Forbid bdrv_set_aio_context outside BQL Fam Zheng 2015-02-15 3:05 ` Fam Zheng 2015-02-15 2:40 ` [Qemu-devel] [PATCH v2 2/2] virtio-scsi-dataplane: Call blk_set_aio_context within BQL Fam Zheng
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).