From nobody Sun Apr 13 18:15:26 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: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488215454664427.30143989925944; Mon, 27 Feb 2017 09:10:54 -0800 (PST) Received: from localhost ([::1]:54404 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciOp2-0005DW-5C for importer@patchew.org; Mon, 27 Feb 2017 12:10:52 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45922) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ciOGK-0007rh-7p for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:35:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ciOGG-0008Pr-4T for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:35:00 -0500 Received: from mx1.redhat.com ([209.132.183.28]:52568) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1ciOGF-0008Pf-Rr for qemu-devel@nongnu.org; Mon, 27 Feb 2017 11:34:56 -0500 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 03AA380F8E; Mon, 27 Feb 2017 16:34:56 +0000 (UTC) Received: from localhost (ovpn-117-188.ams2.redhat.com [10.36.117.188]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id v1RGYs6b029640; Mon, 27 Feb 2017 11:34:55 -0500 From: Stefan Hajnoczi To: Date: Mon, 27 Feb 2017 16:34:46 +0000 Message-Id: <20170227163447.20428-4-stefanha@redhat.com> In-Reply-To: <20170227163447.20428-1-stefanha@redhat.com> References: <20170227163447.20428-1-stefanha@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 27 Feb 2017 16:34:56 +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 3/4] iscsi: do not use aio_context_acquire/release X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Peter Maydell , Stefan Hajnoczi , Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" 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 Now that all bottom halves and callbacks take care of taking the AioContext lock, we can migrate some users away from it and to a specific QemuMutex or CoMutex. Protect libiscsi calls with a QemuMutex. Callbacks are invoked using bottom halves, so we don't even have to drop it around callback invocations. Reviewed-by: Stefan Hajnoczi Signed-off-by: Paolo Bonzini Message-id: 20170222180725.28611-4-pbonzini@redhat.com Signed-off-by: Stefan Hajnoczi --- block/iscsi.c | 83 +++++++++++++++++++++++++++++++++++++++++++++----------= ---- 1 file changed, 64 insertions(+), 19 deletions(-) diff --git a/block/iscsi.c b/block/iscsi.c index c4f813b..76319a1 100644 --- a/block/iscsi.c +++ b/block/iscsi.c @@ -58,6 +58,7 @@ typedef struct IscsiLun { int events; QEMUTimer *nop_timer; QEMUTimer *event_timer; + QemuMutex mutex; struct scsi_inquiry_logical_block_provisioning lbp; struct scsi_inquiry_block_limits bl; unsigned char *zeroblock; @@ -252,6 +253,7 @@ static int iscsi_translate_sense(struct scsi_sense *sen= se) return ret; } =20 +/* Called (via iscsi_service) with QemuMutex held. */ static void iscsi_co_generic_cb(struct iscsi_context *iscsi, int status, void *command_data, void *opaque) @@ -352,6 +354,7 @@ static const AIOCBInfo iscsi_aiocb_info =3D { static void iscsi_process_read(void *arg); static void iscsi_process_write(void *arg); =20 +/* Called with QemuMutex held. */ static void iscsi_set_events(IscsiLun *iscsilun) { @@ -395,10 +398,10 @@ iscsi_process_read(void *arg) IscsiLun *iscsilun =3D arg; struct iscsi_context *iscsi =3D iscsilun->iscsi; =20 - aio_context_acquire(iscsilun->aio_context); + qemu_mutex_lock(&iscsilun->mutex); iscsi_service(iscsi, POLLIN); iscsi_set_events(iscsilun); - aio_context_release(iscsilun->aio_context); + qemu_mutex_unlock(&iscsilun->mutex); } =20 static void @@ -407,10 +410,10 @@ iscsi_process_write(void *arg) IscsiLun *iscsilun =3D arg; struct iscsi_context *iscsi =3D iscsilun->iscsi; =20 - aio_context_acquire(iscsilun->aio_context); + qemu_mutex_lock(&iscsilun->mutex); iscsi_service(iscsi, POLLOUT); iscsi_set_events(iscsilun); - aio_context_release(iscsilun->aio_context); + qemu_mutex_unlock(&iscsilun->mutex); } =20 static int64_t sector_lun2qemu(int64_t sector, IscsiLun *iscsilun) @@ -589,6 +592,7 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sec= tor_num, int nb_sectors, uint64_t lba; uint32_t num_sectors; bool fua =3D flags & BDRV_REQ_FUA; + int r =3D 0; =20 if (fua) { assert(iscsilun->dpofua); @@ -604,6 +608,7 @@ iscsi_co_writev_flags(BlockDriverState *bs, int64_t sec= tor_num, int nb_sectors, lba =3D sector_qemu2lun(sector_num, iscsilun); num_sectors =3D sector_qemu2lun(nb_sectors, iscsilun); iscsi_co_init_iscsitask(iscsilun, &iTask); + qemu_mutex_lock(&iscsilun->mutex); retry: if (iscsilun->use_16_for_rw) { #if LIBISCSI_API_VERSION >=3D (20160603) @@ -640,7 +645,9 @@ retry: #endif while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.task !=3D NULL) { @@ -655,12 +662,15 @@ retry: =20 if (iTask.status !=3D SCSI_STATUS_GOOD) { iscsi_allocmap_set_invalid(iscsilun, sector_num, nb_sectors); - return iTask.err_code; + r =3D iTask.err_code; + goto out_unlock; } =20 iscsi_allocmap_set_allocated(iscsilun, sector_num, nb_sectors); =20 - return 0; +out_unlock: + qemu_mutex_unlock(&iscsilun->mutex); + return r; } =20 =20 @@ -693,18 +703,21 @@ static int64_t coroutine_fn iscsi_co_get_block_status= (BlockDriverState *bs, goto out; } =20 + qemu_mutex_lock(&iscsilun->mutex); retry: if (iscsi_get_lba_status_task(iscsilun->iscsi, iscsilun->lun, sector_qemu2lun(sector_num, iscsilun), 8 + 16, iscsi_co_generic_cb, &iTask) =3D=3D NULL) { ret =3D -ENOMEM; - goto out; + goto out_unlock; } =20 while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.do_retry) { @@ -721,20 +734,20 @@ retry: * because the device is busy or the cmd is not * supported) we pretend all blocks are allocated * for backwards compatibility */ - goto out; + goto out_unlock; } =20 lbas =3D scsi_datain_unmarshall(iTask.task); if (lbas =3D=3D NULL) { ret =3D -EIO; - goto out; + goto out_unlock; } =20 lbasd =3D &lbas->descriptors[0]; =20 if (sector_qemu2lun(sector_num, iscsilun) !=3D lbasd->lba) { ret =3D -EIO; - goto out; + goto out_unlock; } =20 *pnum =3D sector_lun2qemu(lbasd->num_blocks, iscsilun); @@ -756,6 +769,8 @@ retry: if (*pnum > nb_sectors) { *pnum =3D nb_sectors; } +out_unlock: + qemu_mutex_unlock(&iscsilun->mutex); out: if (iTask.task !=3D NULL) { scsi_free_scsi_task(iTask.task); @@ -818,6 +833,7 @@ static int coroutine_fn iscsi_co_readv(BlockDriverState= *bs, num_sectors =3D sector_qemu2lun(nb_sectors, iscsilun); =20 iscsi_co_init_iscsitask(iscsilun, &iTask); + qemu_mutex_lock(&iscsilun->mutex); retry: if (iscsilun->use_16_for_rw) { #if LIBISCSI_API_VERSION >=3D (20160603) @@ -855,7 +871,9 @@ retry: #endif while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.task !=3D NULL) { @@ -867,6 +885,7 @@ retry: iTask.complete =3D 0; goto retry; } + qemu_mutex_unlock(&iscsilun->mutex); =20 if (iTask.status !=3D SCSI_STATUS_GOOD) { return iTask.err_code; @@ -881,6 +900,7 @@ static int coroutine_fn iscsi_co_flush(BlockDriverState= *bs) struct IscsiTask iTask; =20 iscsi_co_init_iscsitask(iscsilun, &iTask); + qemu_mutex_lock(&iscsilun->mutex); retry: if (iscsi_synchronizecache10_task(iscsilun->iscsi, iscsilun->lun, 0, 0= , 0, 0, iscsi_co_generic_cb, &iTask) =3D= =3D NULL) { @@ -889,7 +909,9 @@ retry: =20 while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.task !=3D NULL) { @@ -901,6 +923,7 @@ retry: iTask.complete =3D 0; goto retry; } + qemu_mutex_unlock(&iscsilun->mutex); =20 if (iTask.status !=3D SCSI_STATUS_GOOD) { return iTask.err_code; @@ -910,6 +933,7 @@ retry: } =20 #ifdef __linux__ +/* Called (via iscsi_service) with QemuMutex held. */ static void iscsi_aio_ioctl_cb(struct iscsi_context *iscsi, int status, void *command_data, void *opaque) @@ -1034,6 +1058,7 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *= bs, acb->task->expxferlen =3D acb->ioh->dxfer_len; =20 data.size =3D 0; + qemu_mutex_lock(&iscsilun->mutex); if (acb->task->xfer_dir =3D=3D SCSI_XFER_WRITE) { if (acb->ioh->iovec_count =3D=3D 0) { data.data =3D acb->ioh->dxferp; @@ -1049,6 +1074,7 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *= bs, iscsi_aio_ioctl_cb, (data.size > 0) ? &data : NULL, acb) !=3D 0) { + qemu_mutex_unlock(&iscsilun->mutex); scsi_free_scsi_task(acb->task); qemu_aio_unref(acb); return NULL; @@ -1068,6 +1094,7 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *= bs, } =20 iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); =20 return &acb->common; } @@ -1092,6 +1119,7 @@ coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, = int64_t offset, int count) IscsiLun *iscsilun =3D bs->opaque; struct IscsiTask iTask; struct unmap_list list; + int r =3D 0; =20 if (!is_byte_request_lun_aligned(offset, count, iscsilun)) { return -ENOTSUP; @@ -1106,15 +1134,19 @@ coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs= , int64_t offset, int count) list.num =3D count / iscsilun->block_size; =20 iscsi_co_init_iscsitask(iscsilun, &iTask); + qemu_mutex_lock(&iscsilun->mutex); retry: if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1, iscsi_co_generic_cb, &iTask) =3D=3D NULL) { - return -ENOMEM; + r =3D -ENOMEM; + goto out_unlock; } =20 while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.task !=3D NULL) { @@ -1131,17 +1163,20 @@ retry: /* the target might fail with a check condition if it is not happy with the alignment of the UNMAP request we silently fail in this case */ - return 0; + goto out_unlock; } =20 if (iTask.status !=3D SCSI_STATUS_GOOD) { - return iTask.err_code; + r =3D iTask.err_code; + goto out_unlock; } =20 iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS); =20 - return 0; +out_unlock: + qemu_mutex_unlock(&iscsilun->mutex); + return r; } =20 static int @@ -1153,6 +1188,7 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState = *bs, int64_t offset, uint64_t lba; uint32_t nb_blocks; bool use_16_for_ws =3D iscsilun->use_16_for_rw; + int r =3D 0; =20 if (!is_byte_request_lun_aligned(offset, count, iscsilun)) { return -ENOTSUP; @@ -1186,6 +1222,7 @@ coroutine_fn iscsi_co_pwrite_zeroes(BlockDriverState = *bs, int64_t offset, } } =20 + qemu_mutex_lock(&iscsilun->mutex); iscsi_co_init_iscsitask(iscsilun, &iTask); retry: if (use_16_for_ws) { @@ -1205,7 +1242,9 @@ retry: =20 while (!iTask.complete) { iscsi_set_events(iscsilun); + qemu_mutex_unlock(&iscsilun->mutex); qemu_coroutine_yield(); + qemu_mutex_lock(&iscsilun->mutex); } =20 if (iTask.status =3D=3D SCSI_STATUS_CHECK_CONDITION && @@ -1215,7 +1254,8 @@ retry: /* WRITE SAME is not supported by the target */ iscsilun->has_write_same =3D false; scsi_free_scsi_task(iTask.task); - return -ENOTSUP; + r =3D -ENOTSUP; + goto out_unlock; } =20 if (iTask.task !=3D NULL) { @@ -1231,7 +1271,8 @@ retry: if (iTask.status !=3D SCSI_STATUS_GOOD) { iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS); - return iTask.err_code; + r =3D iTask.err_code; + goto out_unlock; } =20 if (flags & BDRV_REQ_MAY_UNMAP) { @@ -1242,7 +1283,9 @@ retry: count >> BDRV_SECTOR_BITS); } =20 - return 0; +out_unlock: + qemu_mutex_unlock(&iscsilun->mutex); + return r; } =20 static void apply_chap(struct iscsi_context *iscsi, QemuOpts *opts, @@ -1331,7 +1374,7 @@ static void iscsi_nop_timed_event(void *opaque) { IscsiLun *iscsilun =3D opaque; =20 - aio_context_acquire(iscsilun->aio_context); + qemu_mutex_lock(&iscsilun->mutex); if (iscsi_get_nops_in_flight(iscsilun->iscsi) >=3D MAX_NOP_FAILURES) { error_report("iSCSI: NOP timeout. Reconnecting..."); iscsilun->request_timed_out =3D true; @@ -1344,7 +1387,7 @@ static void iscsi_nop_timed_event(void *opaque) iscsi_set_events(iscsilun); =20 out: - aio_context_release(iscsilun->aio_context); + qemu_mutex_unlock(&iscsilun->mutex); } =20 static void iscsi_readcapacity_sync(IscsiLun *iscsilun, Error **errp) @@ -1890,6 +1933,7 @@ static int iscsi_open(BlockDriverState *bs, QDict *op= tions, int flags, scsi_free_scsi_task(task); task =3D NULL; =20 + qemu_mutex_init(&iscsilun->mutex); iscsi_attach_aio_context(bs, iscsilun->aio_context); =20 /* Guess the internal cluster (page) size of the iscsi target by the m= eans @@ -1935,6 +1979,7 @@ static void iscsi_close(BlockDriverState *bs) iscsi_destroy_context(iscsi); g_free(iscsilun->zeroblock); iscsi_allocmap_free(iscsilun); + qemu_mutex_destroy(&iscsilun->mutex); memset(iscsilun, 0, sizeof(IscsiLun)); } =20 --=20 2.9.3