From nobody Fri Nov 7 18:48:28 2025 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548778406682298.1173146186784; Tue, 29 Jan 2019 08:13:26 -0800 (PST) Received: from localhost ([127.0.0.1]:50764 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goV0z-00042q-Ao for importer@patchew.org; Tue, 29 Jan 2019 10:09:29 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49812) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goUqN-0006Fb-1m for qemu-devel@nongnu.org; Tue, 29 Jan 2019 09:58:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1goUXr-00007e-OV for qemu-devel@nongnu.org; Tue, 29 Jan 2019 09:39:29 -0500 Received: from relay.sw.ru ([185.231.240.75]:48914) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1goUX0-0008Tp-18; Tue, 29 Jan 2019 09:39:14 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1goUWY-0003io-4E; Tue, 29 Jan 2019 17:38:02 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Tue, 29 Jan 2019 17:37:59 +0300 Message-Id: <20190129143800.88563-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190129143800.88563-1-vsementsov@virtuozzo.com> References: <20190129143800.88563-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH 1/2] block: enhance QEMUIOVector structure 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, stefanha@redhat.com, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add a possibility of embedded iovec, for cases when we need only one local iov. Signed-off-by: Vladimir Sementsov-Ogievskiy --- include/qemu/iov.h | 41 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 5f433c7768..f739cff97d 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -134,9 +134,48 @@ typedef struct QEMUIOVector { struct iovec *iov; int niov; int nalloc; - size_t size; + + /* + * For external @iov (qemu_iovec_init_external()) or allocated @iov + * (qemu_iovec_init()) @size is the cumulative size of iovecs and + * @local_iov is invalid and unused. + * + * For embedded @iov (QEMU_IOVEC_INIT_BUF() or qemu_iovec_init_buf()), + * @iov is equal to &@local_iov, and @size is valid, as it has same + * offset and type as @local_iov.iov_len, which is guaranteed by + * static assertions below. + */ + union { + struct { + void *__unused_iov_base; + size_t size; + }; + struct iovec local_iov; + }; } QEMUIOVector; =20 +G_STATIC_ASSERT(offsetof(QEMUIOVector, size) =3D=3D + offsetof(QEMUIOVector, local_iov.iov_len)); +G_STATIC_ASSERT(sizeof(((QEMUIOVector *)NULL)->size) =3D=3D + sizeof(((QEMUIOVector *)NULL)->local_iov.iov_len)); + +#define QEMU_IOVEC_INIT_BUF(self, buf, len) \ +{ \ + .iov =3D &(self).local_iov, \ + .niov =3D 1, \ + .nalloc =3D -1, \ + .local_iov =3D { \ + .iov_base =3D (void *)(buf), \ + .iov_len =3D len \ + } \ +} + +static inline void qemu_iovec_init_buf(QEMUIOVector *qiov, + void *buf, size_t len) +{ + *qiov =3D (QEMUIOVector) QEMU_IOVEC_INIT_BUF(*qiov, buf, len); +} + void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int n= iov); void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); --=20 2.18.0 From nobody Fri Nov 7 18:48:28 2025 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=virtuozzo.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1548774138926129.87785353431502; Tue, 29 Jan 2019 07:02:18 -0800 (PST) Received: from localhost ([127.0.0.1]:50657 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goUtf-0008BO-Vz for importer@patchew.org; Tue, 29 Jan 2019 10:01:56 -0500 Received: from eggs.gnu.org ([209.51.188.92]:49850) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1goUqN-0006ME-2s for qemu-devel@nongnu.org; Tue, 29 Jan 2019 09:58:38 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1goUXn-00007P-0Q for qemu-devel@nongnu.org; Tue, 29 Jan 2019 09:39:29 -0500 Received: from relay.sw.ru ([185.231.240.75]:48908) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1goUXQ-0008Te-JA; Tue, 29 Jan 2019 09:39:09 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1goUWY-0003io-8n; Tue, 29 Jan 2019 17:38:02 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-block@nongnu.org, qemu-devel@nongnu.org Date: Tue, 29 Jan 2019 17:38:00 +0300 Message-Id: <20190129143800.88563-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190129143800.88563-1-vsementsov@virtuozzo.com> References: <20190129143800.88563-1-vsementsov@virtuozzo.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 185.231.240.75 Subject: [Qemu-devel] [PATCH 2/2] block/io: use qemu_iovec_init_buf 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: kwolf@redhat.com, fam@euphon.net, vsementsov@virtuozzo.com, stefanha@redhat.com, mreitz@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Use new qemu_iovec_init_buf() instead of qemu_iovec_init_external( ... , 1), which simplifies the code. Signed-off-by: Vladimir Sementsov-Ogievskiy --- block/io.c | 89 ++++++++++++------------------------------------------ 1 file changed, 20 insertions(+), 69 deletions(-) diff --git a/block/io.c b/block/io.c index bd9d688f8b..80961910a6 100644 --- a/block/io.c +++ b/block/io.c @@ -842,17 +842,13 @@ static int bdrv_prwv_co(BdrvChild *child, int64_t off= set, static int bdrv_rw_co(BdrvChild *child, int64_t sector_num, uint8_t *buf, int nb_sectors, bool is_write, BdrvRequestFlags flag= s) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D (void *)buf, - .iov_len =3D nb_sectors * BDRV_SECTOR_SIZE, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, buf, + nb_sectors * BDRV_SECTOR_SIZE); =20 if (nb_sectors < 0 || nb_sectors > BDRV_REQUEST_MAX_SECTORS) { return -EINVAL; } =20 - qemu_iovec_init_external(&qiov, &iov, 1); return bdrv_prwv_co(child, sector_num << BDRV_SECTOR_BITS, &qiov, is_write, flags); } @@ -879,13 +875,8 @@ int bdrv_write(BdrvChild *child, int64_t sector_num, int bdrv_pwrite_zeroes(BdrvChild *child, int64_t offset, int bytes, BdrvRequestFlags flags) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D NULL, - .iov_len =3D bytes, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, NULL, bytes); =20 - qemu_iovec_init_external(&qiov, &iov, 1); return bdrv_prwv_co(child, offset, &qiov, true, BDRV_REQ_ZERO_WRITE | flags); } @@ -949,17 +940,12 @@ int bdrv_preadv(BdrvChild *child, int64_t offset, QEM= UIOVector *qiov) =20 int bdrv_pread(BdrvChild *child, int64_t offset, void *buf, int bytes) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D (void *)buf, - .iov_len =3D bytes, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, buf, bytes); =20 if (bytes < 0) { return -EINVAL; } =20 - qemu_iovec_init_external(&qiov, &iov, 1); return bdrv_preadv(child, offset, &qiov); } =20 @@ -977,17 +963,12 @@ int bdrv_pwritev(BdrvChild *child, int64_t offset, QE= MUIOVector *qiov) =20 int bdrv_pwrite(BdrvChild *child, int64_t offset, const void *buf, int byt= es) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D (void *) buf, - .iov_len =3D bytes, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, NULL, bytes); =20 if (bytes < 0) { return -EINVAL; } =20 - qemu_iovec_init_external(&qiov, &iov, 1); return bdrv_pwritev(child, offset, &qiov); } =20 @@ -1164,7 +1145,6 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, void *bounce_buffer; =20 BlockDriver *drv =3D bs->drv; - struct iovec iov; QEMUIOVector local_qiov; int64_t cluster_offset; int64_t cluster_bytes; @@ -1229,9 +1209,7 @@ static int coroutine_fn bdrv_co_do_copy_on_readv(Bdrv= Child *child, =20 if (ret <=3D 0) { /* Must copy-on-read; use the bounce buffer */ - iov.iov_base =3D bounce_buffer; - iov.iov_len =3D pnum =3D MIN(pnum, MAX_BOUNCE_BUFFER); - qemu_iovec_init_external(&local_qiov, &iov, 1); + qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum); =20 ret =3D bdrv_driver_preadv(bs, cluster_offset, pnum, &local_qiov, 0); @@ -1476,7 +1454,7 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(Bloc= kDriverState *bs, { BlockDriver *drv =3D bs->drv; QEMUIOVector qiov; - struct iovec iov =3D {0}; + void *buf =3D NULL; int ret =3D 0; bool need_flush =3D false; int head =3D 0; @@ -1546,16 +1524,15 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(Bl= ockDriverState *bs, need_flush =3D true; } num =3D MIN(num, max_transfer); - iov.iov_len =3D num; - if (iov.iov_base =3D=3D NULL) { - iov.iov_base =3D qemu_try_blockalign(bs, num); - if (iov.iov_base =3D=3D NULL) { + if (buf =3D=3D NULL) { + buf =3D qemu_try_blockalign(bs, num); + if (buf =3D=3D NULL) { ret =3D -ENOMEM; goto fail; } - memset(iov.iov_base, 0, num); + memset(buf, 0, num); } - qemu_iovec_init_external(&qiov, &iov, 1); + qemu_iovec_init_buf(&qiov, buf, num); =20 ret =3D bdrv_driver_pwritev(bs, offset, num, &qiov, write_flag= s); =20 @@ -1563,8 +1540,8 @@ static int coroutine_fn bdrv_co_do_pwrite_zeroes(Bloc= kDriverState *bs, * all future requests. */ if (num < max_transfer) { - qemu_vfree(iov.iov_base); - iov.iov_base =3D NULL; + qemu_vfree(buf); + buf =3D NULL; } } =20 @@ -1576,7 +1553,7 @@ fail: if (ret =3D=3D 0 && need_flush) { ret =3D bdrv_co_flush(bs); } - qemu_vfree(iov.iov_base); + qemu_vfree(buf); return ret; } =20 @@ -1762,7 +1739,6 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(BdrvC= hild *child, BlockDriverState *bs =3D child->bs; uint8_t *buf =3D NULL; QEMUIOVector local_qiov; - struct iovec iov; uint64_t align =3D bs->bl.request_alignment; unsigned int head_padding_bytes, tail_padding_bytes; int ret =3D 0; @@ -1774,11 +1750,7 @@ static int coroutine_fn bdrv_co_do_zero_pwritev(Bdrv= Child *child, assert(flags & BDRV_REQ_ZERO_WRITE); if (head_padding_bytes || tail_padding_bytes) { buf =3D qemu_blockalign(bs, align); - iov =3D (struct iovec) { - .iov_base =3D buf, - .iov_len =3D align, - }; - qemu_iovec_init_external(&local_qiov, &iov, 1); + qemu_iovec_init_buf(&local_qiov, buf, align); } if (head_padding_bytes) { uint64_t zero_bytes =3D MIN(bytes, align - head_padding_bytes); @@ -1884,17 +1856,12 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, =20 if (offset & (align - 1)) { QEMUIOVector head_qiov; - struct iovec head_iov; =20 mark_request_serialising(&req, align); wait_serialising_requests(&req); =20 head_buf =3D qemu_blockalign(bs, align); - head_iov =3D (struct iovec) { - .iov_base =3D head_buf, - .iov_len =3D align, - }; - qemu_iovec_init_external(&head_qiov, &head_iov, 1); + qemu_iovec_init_buf(&head_qiov, head_buf, align); =20 bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_HEAD); ret =3D bdrv_aligned_preadv(child, &req, offset & ~(align - 1), al= ign, @@ -1923,7 +1890,6 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, =20 if ((offset + bytes) & (align - 1)) { QEMUIOVector tail_qiov; - struct iovec tail_iov; size_t tail_bytes; bool waited; =20 @@ -1932,11 +1898,7 @@ int coroutine_fn bdrv_co_pwritev(BdrvChild *child, assert(!waited || !use_local_qiov); =20 tail_buf =3D qemu_blockalign(bs, align); - tail_iov =3D (struct iovec) { - .iov_base =3D tail_buf, - .iov_len =3D align, - }; - qemu_iovec_init_external(&tail_qiov, &tail_iov, 1); + qemu_iovec_init_buf(&tail_qiov, tail_buf, align); =20 bdrv_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL); ret =3D bdrv_aligned_preadv(child, &req, (offset + bytes) & ~(alig= n - 1), @@ -2465,15 +2427,9 @@ bdrv_rw_vmstate(BlockDriverState *bs, QEMUIOVector *= qiov, int64_t pos, int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D (void *) buf, - .iov_len =3D size, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, buf, size); int ret; =20 - qemu_iovec_init_external(&qiov, &iov, 1); - ret =3D bdrv_writev_vmstate(bs, &qiov, pos); if (ret < 0) { return ret; @@ -2490,14 +2446,9 @@ int bdrv_writev_vmstate(BlockDriverState *bs, QEMUIO= Vector *qiov, int64_t pos) int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size) { - QEMUIOVector qiov; - struct iovec iov =3D { - .iov_base =3D buf, - .iov_len =3D size, - }; + QEMUIOVector qiov =3D QEMU_IOVEC_INIT_BUF(qiov, buf, size); int ret; =20 - qemu_iovec_init_external(&qiov, &iov, 1); ret =3D bdrv_readv_vmstate(bs, &qiov, pos); if (ret < 0) { return ret; --=20 2.18.0