From nobody Fri Nov 7 18:54:09 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 1549472161494978.9785218208049; Wed, 6 Feb 2019 08:56:01 -0800 (PST) Received: from localhost ([127.0.0.1]:53856 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1grQUI-0002OT-E0 for importer@patchew.org; Wed, 06 Feb 2019 11:55:50 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48345) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1grQSL-00010I-97 for qemu-devel@nongnu.org; Wed, 06 Feb 2019 11:53:50 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1grQSK-00027r-8O for qemu-devel@nongnu.org; Wed, 06 Feb 2019 11:53:49 -0500 Received: from relay.sw.ru ([185.231.240.75]:38120) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1grQSI-00025f-Dl; Wed, 06 Feb 2019 11:53:46 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1grQSE-0002UR-Gk; Wed, 06 Feb 2019 19:53:42 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Wed, 6 Feb 2019 19:53:41 +0300 Message-Id: <20190206165342.219192-2-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190206165342.219192-1-vsementsov@virtuozzo.com> References: <20190206165342.219192-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 v2 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, mreitz@redhat.com, stefanha@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 | 47 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 5f433c7768..3753b63558 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -133,10 +133,53 @@ size_t iov_discard_back(struct iovec *iov, unsigned i= nt *iov_cnt, 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. + * + * @nalloc is valid always and is -1 both for embedded and external + * cases. It included into union only to make appropriate padding for + * @size field avoiding creation of 0-length array in the worst case. + */ + union { + struct { + int nalloc; + struct iovec local_iov; + }; + struct { + char __pad[sizeof(int) + offsetof(struct iovec, iov_len)]; + size_t size; + }; + }; } QEMUIOVector; =20 +QEMU_BUILD_BUG_ON(offsetof(QEMUIOVector, size) !=3D + offsetof(QEMUIOVector, 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), /* cast away const */ \ + .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:54:09 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) 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=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) 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 1549472198076265.11019559215185; Wed, 6 Feb 2019 08:56:38 -0800 (PST) Received: from localhost ([127.0.0.1]:53858 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1grQUy-0002wF-0I for importer@patchew.org; Wed, 06 Feb 2019 11:56:32 -0500 Received: from eggs.gnu.org ([209.51.188.92]:48357) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1grQSL-00010j-Q6 for qemu-devel@nongnu.org; Wed, 06 Feb 2019 11:53:51 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1grQSK-000283-9i for qemu-devel@nongnu.org; Wed, 06 Feb 2019 11:53:49 -0500 Received: from relay.sw.ru ([185.231.240.75]:38124) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1grQSI-00025g-FN; Wed, 06 Feb 2019 11:53:47 -0500 Received: from [10.28.8.145] (helo=kvm.sw.ru) by relay.sw.ru with esmtp (Exim 4.91) (envelope-from ) id 1grQSE-0002UR-KE; Wed, 06 Feb 2019 19:53:42 +0300 From: Vladimir Sementsov-Ogievskiy To: qemu-devel@nongnu.org, qemu-block@nongnu.org Date: Wed, 6 Feb 2019 19:53:42 +0300 Message-Id: <20190206165342.219192-3-vsementsov@virtuozzo.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20190206165342.219192-1-vsementsov@virtuozzo.com> References: <20190206165342.219192-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 v2 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, mreitz@redhat.com, stefanha@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 Reviewed-by: Eric Blake --- block/io.c | 90 +++++++++++++----------------------------------------- 1 file changed, 21 insertions(+), 69 deletions(-) diff --git a/block/io.c b/block/io.c index bd9d688f8b..4c4fd17d89 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, buf, 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,8 @@ 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); + pnum =3D MIN(pnum, MAX_BOUNCE_BUFFER); + qemu_iovec_init_buf(&local_qiov, bounce_buffer, pnum); =20 ret =3D bdrv_driver_preadv(bs, cluster_offset, pnum, &local_qiov, 0); @@ -1476,7 +1455,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 +1525,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 +1541,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 +1554,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 +1740,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 +1751,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 +1857,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 +1891,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 +1899,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 +2428,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 +2447,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