From nobody Sun May 4 17:42:52 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: <qemu-devel-bounces+importer=patchew.org@nongnu.org> Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1487681218610897.622284862779; Tue, 21 Feb 2017 04:46:58 -0800 (PST) Received: from localhost ([::1]:44224 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from <qemu-devel-bounces+importer=patchew.org@nongnu.org>) id 1cg9qK-0001E7-72 for importer@patchew.org; Tue, 21 Feb 2017 07:46:56 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:38792) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from <stefanha@redhat.com>) id 1cg94M-0006uf-AT for qemu-devel@nongnu.org; Tue, 21 Feb 2017 06:57:24 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from <stefanha@redhat.com>) id 1cg94J-0005VB-Us for qemu-devel@nongnu.org; Tue, 21 Feb 2017 06:57:22 -0500 Received: from mx1.redhat.com ([209.132.183.28]:33506) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from <stefanha@redhat.com>) id 1cg94J-0005Uu-MT for qemu-devel@nongnu.org; Tue, 21 Feb 2017 06:57:19 -0500 Received: from smtp.corp.redhat.com (int-mx16.intmail.prod.int.phx2.redhat.com [10.5.11.28]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BEF0761BBE; Tue, 21 Feb 2017 11:57:19 +0000 (UTC) Received: from localhost (ovpn-117-191.ams2.redhat.com [10.36.117.191]) by smtp.corp.redhat.com (Postfix) with ESMTP id C60371CDD69; Tue, 21 Feb 2017 11:57:18 +0000 (UTC) From: Stefan Hajnoczi <stefanha@redhat.com> To: <qemu-devel@nongnu.org> Date: Tue, 21 Feb 2017 11:56:35 +0000 Message-Id: <20170221115644.28264-16-stefanha@redhat.com> In-Reply-To: <20170221115644.28264-1-stefanha@redhat.com> References: <20170221115644.28264-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.74 on 10.5.11.28 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Tue, 21 Feb 2017 11:57:19 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL v2 15/24] block: explicitly acquire aiocontext in aio callbacks that need it X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: <qemu-devel.nongnu.org> List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-devel>, <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe> List-Archive: <http://lists.nongnu.org/archive/html/qemu-devel/> List-Post: <mailto:qemu-devel@nongnu.org> List-Help: <mailto:qemu-devel-request@nongnu.org?subject=help> List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-devel>, <mailto:qemu-devel-request@nongnu.org?subject=subscribe> Cc: Peter Maydell <peter.maydell@linaro.org>, Stefan Hajnoczi <stefanha@redhat.com>, Paolo Bonzini <pbonzini@redhat.com> Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" <qemu-devel-bounces+importer=patchew.org@nongnu.org> X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Reviewed-by: Fam Zheng <famz@redhat.com> Reviewed-by: Daniel P. Berrange <berrange@redhat.com> Message-id: 20170213135235.12274-16-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> --- block/archipelago.c | 3 --- block/block-backend.c | 7 ------- block/curl.c | 2 +- block/io.c | 6 +----- block/iscsi.c | 3 --- block/linux-aio.c | 5 +---- block/mirror.c | 12 +++++++++--- block/null.c | 8 -------- block/qed-cluster.c | 2 ++ block/qed-table.c | 12 ++++++++++-- block/qed.c | 4 ++-- block/rbd.c | 4 ---- block/win32-aio.c | 3 --- hw/block/virtio-blk.c | 12 +++++++++++- hw/scsi/scsi-disk.c | 15 +++++++++++++++ hw/scsi/scsi-generic.c | 20 +++++++++++++++++--- util/thread-pool.c | 4 +++- 17 files changed, 72 insertions(+), 50 deletions(-) diff --git a/block/archipelago.c b/block/archipelago.c index a624390..2449cfc 100644 --- a/block/archipelago.c +++ b/block/archipelago.c @@ -310,11 +310,8 @@ static void qemu_archipelago_complete_aio(void *opaque) { AIORequestData *reqdata =3D (AIORequestData *) opaque; ArchipelagoAIOCB *aio_cb =3D (ArchipelagoAIOCB *) reqdata->aio_cb; - AioContext *ctx =3D bdrv_get_aio_context(aio_cb->common.bs); =20 - aio_context_acquire(ctx); aio_cb->common.cb(aio_cb->common.opaque, aio_cb->ret); - aio_context_release(ctx); aio_cb->status =3D 0; =20 qemu_aio_unref(aio_cb); diff --git a/block/block-backend.c b/block/block-backend.c index bfc0e6b..819f272 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -939,12 +939,9 @@ int blk_make_zero(BlockBackend *blk, BdrvRequestFlags = flags) static void error_callback_bh(void *opaque) { struct BlockBackendAIOCB *acb =3D opaque; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); =20 bdrv_dec_in_flight(acb->common.bs); - aio_context_acquire(ctx); acb->common.cb(acb->common.opaque, acb->ret); - aio_context_release(ctx); qemu_aio_unref(acb); } =20 @@ -986,12 +983,8 @@ static void blk_aio_complete(BlkAioEmAIOCB *acb) static void blk_aio_complete_bh(void *opaque) { BlkAioEmAIOCB *acb =3D opaque; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); - assert(acb->has_returned); - aio_context_acquire(ctx); blk_aio_complete(acb); - aio_context_release(ctx); } =20 static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int byt= es, diff --git a/block/curl.c b/block/curl.c index f3f063b..2939cc7 100644 --- a/block/curl.c +++ b/block/curl.c @@ -854,11 +854,11 @@ static void curl_readv_bh_cb(void *p) curl_multi_socket_action(s->multi, CURL_SOCKET_TIMEOUT, 0, &running); =20 out: + aio_context_release(ctx); if (ret !=3D -EINPROGRESS) { acb->common.cb(acb->common.opaque, ret); qemu_aio_unref(acb); } - aio_context_release(ctx); } =20 static BlockAIOCB *curl_aio_readv(BlockDriverState *bs, diff --git a/block/io.c b/block/io.c index 8486e27..a5c7d36 100644 --- a/block/io.c +++ b/block/io.c @@ -813,7 +813,7 @@ static void bdrv_co_io_em_complete(void *opaque, int re= t) CoroutineIOCompletion *co =3D opaque; =20 co->ret =3D ret; - qemu_coroutine_enter(co->coroutine); + aio_co_wake(co->coroutine); } =20 static int coroutine_fn bdrv_driver_preadv(BlockDriverState *bs, @@ -2152,13 +2152,9 @@ static void bdrv_co_complete(BlockAIOCBCoroutine *ac= b) static void bdrv_co_em_bh(void *opaque) { BlockAIOCBCoroutine *acb =3D opaque; - BlockDriverState *bs =3D acb->common.bs; - AioContext *ctx =3D bdrv_get_aio_context(bs); =20 assert(!acb->need_bh); - aio_context_acquire(ctx); bdrv_co_complete(acb); - aio_context_release(ctx); } =20 static void bdrv_co_maybe_schedule_bh(BlockAIOCBCoroutine *acb) diff --git a/block/iscsi.c b/block/iscsi.c index 4fb43c2..2561be9 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -136,16 +136,13 @@ static void iscsi_bh_cb(void *p) { IscsiAIOCB *acb =3D p; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); =20 qemu_bh_delete(acb->bh); =20 g_free(acb->buf); acb->buf =3D NULL; =20 - aio_context_acquire(ctx); acb->common.cb(acb->common.opaque, acb->status); - aio_context_release(ctx); =20 if (acb->task !=3D NULL) { scsi_free_scsi_task(acb->task); diff --git a/block/linux-aio.c b/block/linux-aio.c index f7ae38a..88b8d55 100644 --- a/block/linux-aio.c +++ b/block/linux-aio.c @@ -75,7 +75,6 @@ static inline ssize_t io_event_ret(struct io_event *ev) */ static void qemu_laio_process_completion(struct qemu_laiocb *laiocb) { - LinuxAioState *s =3D laiocb->ctx; int ret; =20 ret =3D laiocb->ret; @@ -94,7 +93,6 @@ static void qemu_laio_process_completion(struct qemu_laio= cb *laiocb) } =20 laiocb->ret =3D ret; - aio_context_acquire(s->aio_context); if (laiocb->co) { /* If the coroutine is already entered it must be in ioq_submit() = and * will notice laio->ret has been filled in when it eventually runs @@ -102,13 +100,12 @@ static void qemu_laio_process_completion(struct qemu_= laiocb *laiocb) * that! */ if (!qemu_coroutine_entered(laiocb->co)) { - qemu_coroutine_enter(laiocb->co); + aio_co_wake(laiocb->co); } } else { laiocb->common.cb(laiocb->common.opaque, ret); qemu_aio_unref(laiocb); } - aio_context_release(s->aio_context); } =20 /** diff --git a/block/mirror.c b/block/mirror.c index 301ba92..698a54e 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -132,6 +132,8 @@ static void mirror_write_complete(void *opaque, int ret) { MirrorOp *op =3D opaque; MirrorBlockJob *s =3D op->s; + + aio_context_acquire(blk_get_aio_context(s->common.blk)); if (ret < 0) { BlockErrorAction action; =20 @@ -142,12 +144,15 @@ static void mirror_write_complete(void *opaque, int r= et) } } mirror_iteration_done(op, ret); + aio_context_release(blk_get_aio_context(s->common.blk)); } =20 static void mirror_read_complete(void *opaque, int ret) { MirrorOp *op =3D opaque; MirrorBlockJob *s =3D op->s; + + aio_context_acquire(blk_get_aio_context(s->common.blk)); if (ret < 0) { BlockErrorAction action; =20 @@ -158,10 +163,11 @@ static void mirror_read_complete(void *opaque, int re= t) } =20 mirror_iteration_done(op, ret); - return; + } else { + blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op-= >qiov, + 0, mirror_write_complete, op); } - blk_aio_pwritev(s->target, op->sector_num * BDRV_SECTOR_SIZE, &op->qio= v, - 0, mirror_write_complete, op); + aio_context_release(blk_get_aio_context(s->common.blk)); } =20 static inline void mirror_clip_sectors(MirrorBlockJob *s, diff --git a/block/null.c b/block/null.c index 5eb2038..b300390 100644 --- a/block/null.c +++ b/block/null.c @@ -134,22 +134,14 @@ static const AIOCBInfo null_aiocb_info =3D { static void null_bh_cb(void *opaque) { NullAIOCB *acb =3D opaque; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); - - aio_context_acquire(ctx); acb->common.cb(acb->common.opaque, 0); - aio_context_release(ctx); qemu_aio_unref(acb); } =20 static void null_timer_cb(void *opaque) { NullAIOCB *acb =3D opaque; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); - - aio_context_acquire(ctx); acb->common.cb(acb->common.opaque, 0); - aio_context_release(ctx); timer_deinit(&acb->timer); qemu_aio_unref(acb); } diff --git a/block/qed-cluster.c b/block/qed-cluster.c index c24e756..8f5da74 100644 --- a/block/qed-cluster.c +++ b/block/qed-cluster.c @@ -83,6 +83,7 @@ static void qed_find_cluster_cb(void *opaque, int ret) unsigned int index; unsigned int n; =20 + qed_acquire(s); if (ret) { goto out; } @@ -109,6 +110,7 @@ static void qed_find_cluster_cb(void *opaque, int ret) =20 out: find_cluster_cb->cb(find_cluster_cb->opaque, ret, offset, len); + qed_release(s); g_free(find_cluster_cb); } =20 diff --git a/block/qed-table.c b/block/qed-table.c index ed443e2..b12c298 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -31,6 +31,7 @@ static void qed_read_table_cb(void *opaque, int ret) { QEDReadTableCB *read_table_cb =3D opaque; QEDTable *table =3D read_table_cb->table; + BDRVQEDState *s =3D read_table_cb->s; int noffsets =3D read_table_cb->qiov.size / sizeof(uint64_t); int i; =20 @@ -40,13 +41,15 @@ static void qed_read_table_cb(void *opaque, int ret) } =20 /* Byteswap offsets */ + qed_acquire(s); for (i =3D 0; i < noffsets; i++) { table->offsets[i] =3D le64_to_cpu(table->offsets[i]); } + qed_release(s); =20 out: /* Completion */ - trace_qed_read_table_cb(read_table_cb->s, read_table_cb->table, ret); + trace_qed_read_table_cb(s, read_table_cb->table, ret); gencb_complete(&read_table_cb->gencb, ret); } =20 @@ -84,8 +87,9 @@ typedef struct { static void qed_write_table_cb(void *opaque, int ret) { QEDWriteTableCB *write_table_cb =3D opaque; + BDRVQEDState *s =3D write_table_cb->s; =20 - trace_qed_write_table_cb(write_table_cb->s, + trace_qed_write_table_cb(s, write_table_cb->orig_table, write_table_cb->flush, ret); @@ -97,8 +101,10 @@ static void qed_write_table_cb(void *opaque, int ret) if (write_table_cb->flush) { /* We still need to flush first */ write_table_cb->flush =3D false; + qed_acquire(s); bdrv_aio_flush(write_table_cb->s->bs, qed_write_table_cb, write_table_cb); + qed_release(s); return; } =20 @@ -213,6 +219,7 @@ static void qed_read_l2_table_cb(void *opaque, int ret) CachedL2Table *l2_table =3D request->l2_table; uint64_t l2_offset =3D read_l2_table_cb->l2_offset; =20 + qed_acquire(s); if (ret) { /* can't trust loaded L2 table anymore */ qed_unref_l2_cache_entry(l2_table); @@ -228,6 +235,7 @@ static void qed_read_l2_table_cb(void *opaque, int ret) request->l2_table =3D qed_find_l2_cache_entry(&s->l2_cache, l2_off= set); assert(request->l2_table !=3D NULL); } + qed_release(s); =20 gencb_complete(&read_l2_table_cb->gencb, ret); } diff --git a/block/qed.c b/block/qed.c index db8295d..0b62c77 100644 --- a/block/qed.c +++ b/block/qed.c @@ -745,7 +745,7 @@ static void qed_is_allocated_cb(void *opaque, int ret, = uint64_t offset, size_t l } =20 if (cb->co) { - qemu_coroutine_enter(cb->co); + aio_co_wake(cb->co); } } =20 @@ -1462,7 +1462,7 @@ static void coroutine_fn qed_co_pwrite_zeroes_cb(void= *opaque, int ret) cb->done =3D true; cb->ret =3D ret; if (cb->co) { - qemu_coroutine_enter(cb->co); + aio_co_wake(cb->co); } } =20 diff --git a/block/rbd.c b/block/rbd.c index 2cb2cb4..a57b3e3 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -413,7 +413,6 @@ shutdown: static void qemu_rbd_complete_aio(RADOSCB *rcb) { RBDAIOCB *acb =3D rcb->acb; - AioContext *ctx =3D bdrv_get_aio_context(acb->common.bs); int64_t r; =20 r =3D rcb->ret; @@ -446,10 +445,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb) qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size); } qemu_vfree(acb->bounce); - - aio_context_acquire(ctx); acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); - aio_context_release(ctx); =20 qemu_aio_unref(acb); } diff --git a/block/win32-aio.c b/block/win32-aio.c index c3f8f1a..3be8f45 100644 --- a/block/win32-aio.c +++ b/block/win32-aio.c @@ -87,10 +87,7 @@ static void win32_aio_process_completion(QEMUWin32AIOSta= te *s, qemu_vfree(waiocb->buf); } =20 - - aio_context_acquire(s->aio_ctx); waiocb->common.cb(waiocb->common.opaque, ret); - aio_context_release(s->aio_ctx); qemu_aio_unref(waiocb); } =20 diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index de3cf7b..843bd2f 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -89,7 +89,9 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req= , int error, static void virtio_blk_rw_complete(void *opaque, int ret) { VirtIOBlockReq *next =3D opaque; + VirtIOBlock *s =3D next->dev; =20 + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); while (next) { VirtIOBlockReq *req =3D next; next =3D req->mr_next; @@ -122,21 +124,27 @@ static void virtio_blk_rw_complete(void *opaque, int = ret) block_acct_done(blk_get_stats(req->dev->blk), &req->acct); virtio_blk_free_request(req); } + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); } =20 static void virtio_blk_flush_complete(void *opaque, int ret) { VirtIOBlockReq *req =3D opaque; + VirtIOBlock *s =3D req->dev; =20 + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); if (ret) { if (virtio_blk_handle_rw_error(req, -ret, 0)) { - return; + goto out; } } =20 virtio_blk_req_complete(req, VIRTIO_BLK_S_OK); block_acct_done(blk_get_stats(req->dev->blk), &req->acct); virtio_blk_free_request(req); + +out: + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); } =20 #ifdef __linux__ @@ -183,8 +191,10 @@ static void virtio_blk_ioctl_complete(void *opaque, in= t status) virtio_stl_p(vdev, &scsi->data_len, hdr->dxfer_len); =20 out: + aio_context_acquire(blk_get_aio_context(s->conf.conf.blk)); virtio_blk_req_complete(req, status); virtio_blk_free_request(req); + aio_context_release(blk_get_aio_context(s->conf.conf.blk)); g_free(ioctl_req); } =20 diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index cc06fe5..bbfb5dc 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -207,6 +207,7 @@ static void scsi_aio_complete(void *opaque, int ret) =20 assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -215,6 +216,7 @@ static void scsi_aio_complete(void *opaque, int ret) scsi_req_complete(&r->req, GOOD); =20 done: + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); scsi_req_unref(&r->req); } =20 @@ -290,12 +292,14 @@ static void scsi_dma_complete(void *opaque, int ret) assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_dma_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 static void scsi_read_complete(void * opaque, int ret) @@ -306,6 +310,7 @@ static void scsi_read_complete(void * opaque, int ret) =20 assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -320,6 +325,7 @@ static void scsi_read_complete(void * opaque, int ret) =20 done: scsi_req_unref(&r->req); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 /* Actually issue a read to the block device. */ @@ -364,12 +370,14 @@ static void scsi_do_read_cb(void *opaque, int ret) assert (r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_do_read(opaque, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 /* Read more data from scsi device into buffer. */ @@ -489,12 +497,14 @@ static void scsi_write_complete(void * opaque, int re= t) assert (r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (ret < 0) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } else { block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); } scsi_write_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 static void scsi_write_data(SCSIRequest *req) @@ -1625,11 +1635,14 @@ static void scsi_unmap_complete(void *opaque, int r= et) { UnmapCBData *data =3D opaque; SCSIDiskReq *r =3D data->r; + SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, r->req.dev); =20 assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); scsi_unmap_complete_noio(data, ret); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 static void scsi_disk_emulate_unmap(SCSIDiskReq *r, uint8_t *inbuf) @@ -1696,6 +1709,7 @@ static void scsi_write_same_complete(void *opaque, in= t ret) =20 assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); if (scsi_disk_req_check_error(r, ret, true)) { goto done; } @@ -1724,6 +1738,7 @@ done: scsi_req_unref(&r->req); qemu_vfree(data->iov.iov_base); g_free(data); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); } =20 static void scsi_disk_emulate_write_same(SCSIDiskReq *r, uint8_t *inbuf) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 92f091a..2933119 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -143,10 +143,14 @@ done: static void scsi_command_complete(void *opaque, int ret) { SCSIGenericReq *r =3D (SCSIGenericReq *)opaque; + SCSIDevice *s =3D r->req.dev; =20 assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; + + aio_context_acquire(blk_get_aio_context(s->conf.blk)); scsi_command_complete_noio(r, ret); + aio_context_release(blk_get_aio_context(s->conf.blk)); } =20 static int execute_command(BlockBackend *blk, @@ -182,9 +186,11 @@ static void scsi_read_complete(void * opaque, int ret) assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + if (ret || r->req.io_canceled) { scsi_command_complete_noio(r, ret); - return; + goto done; } =20 len =3D r->io_header.dxfer_len - r->io_header.resid; @@ -193,7 +199,7 @@ static void scsi_read_complete(void * opaque, int ret) r->len =3D -1; if (len =3D=3D 0) { scsi_command_complete_noio(r, 0); - return; + goto done; } =20 /* Snoop READ CAPACITY output to set the blocksize. */ @@ -237,6 +243,9 @@ static void scsi_read_complete(void * opaque, int ret) } scsi_req_data(&r->req, len); scsi_req_unref(&r->req); + +done: + aio_context_release(blk_get_aio_context(s->conf.blk)); } =20 /* Read more data from scsi device into buffer. */ @@ -272,9 +281,11 @@ static void scsi_write_complete(void * opaque, int ret) assert(r->req.aiocb !=3D NULL); r->req.aiocb =3D NULL; =20 + aio_context_acquire(blk_get_aio_context(s->conf.blk)); + if (ret || r->req.io_canceled) { scsi_command_complete_noio(r, ret); - return; + goto done; } =20 if (r->req.cmd.buf[0] =3D=3D MODE_SELECT && r->req.cmd.buf[4] =3D=3D 1= 2 && @@ -284,6 +295,9 @@ static void scsi_write_complete(void * opaque, int ret) } =20 scsi_command_complete_noio(r, ret); + +done: + aio_context_release(blk_get_aio_context(s->conf.blk)); } =20 /* Write data to a scsi device. Returns nonzero on failure. diff --git a/util/thread-pool.c b/util/thread-pool.c index 7c9cec5..ce6cd30 100644 --- a/util/thread-pool.c +++ b/util/thread-pool.c @@ -185,7 +185,9 @@ restart: */ qemu_bh_schedule(pool->completion_bh); =20 + aio_context_release(pool->ctx); elem->common.cb(elem->common.opaque, elem->ret); + aio_context_acquire(pool->ctx); qemu_aio_unref(elem); goto restart; } else { @@ -269,7 +271,7 @@ static void thread_pool_co_cb(void *opaque, int ret) ThreadPoolCo *co =3D opaque; =20 co->ret =3D ret; - qemu_coroutine_enter(co->co); + aio_co_wake(co->co); } =20 int coroutine_fn thread_pool_submit_co(ThreadPool *pool, ThreadPoolFunc *f= unc, --=20 2.9.3