From nobody Fri Mar 29 06:36:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1679075469; cv=none; d=zohomail.com; s=zohoarc; b=OyP2dbMTfzRVQZ4DsUm4vZpVH1sNvYKSWUARZFV+V79P2kZiQQ6puSnrWhkF+abwEOw1scY5XBN+CfT9wSHOSYGAYMoZfQ91LsieUjneZvulJsr6g6lUrjytlFt2x5Hn9LFUc8fD/1JZPQCrUXZ7H3/duHVg2aEPp3bUrL85bcc= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679075469; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=gXSDZczhbqycwTTz4MRBKi4g7FLVsqztQDeIOyD/jsk=; b=I2Y7OuvY43xMHtf/pSfwGAL+UBtk/lnJCXoeSOlwOfM9agNgXhx8x+gzDI/1AvMCf7wNMmpclvMfuoVyKxNPpVtTzO9uJ3ozSRXzjy5i3IAckjUQ4YF6Svpna1mbtg6G/6UT2ez+DvUb6tWJwfZN78LDpaXof8JtPtxgyRuH/S4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1679075469796462.0401205669623; Fri, 17 Mar 2023 10:51:09 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pdEDm-0003Fp-Ga; Fri, 17 Mar 2023 13:50:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDk-0003Ee-SL for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:28 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDi-0001q0-8G for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:28 -0400 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-287-Fbjc6r2XO6KOAzdg5Y6g-A-1; Fri, 17 Mar 2023 13:50:23 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0EB423822DE7; Fri, 17 Mar 2023 17:50:23 +0000 (UTC) Received: from localhost (unknown [10.39.193.108]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A8A792166B26; Fri, 17 Mar 2023 17:50:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679075425; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gXSDZczhbqycwTTz4MRBKi4g7FLVsqztQDeIOyD/jsk=; b=HobjXExNFxbxGi6R+IPwF/kmQdQNLMU3wp0FN2wd1URkth6QWIoaAJlNZlITs9t1IJ3diB Vvl//OvwQ2L2B9z64LaatorvGHOAvcjUzS8Wb9ICt2npHjJl81pnZY1mTa94I8pAAAni/r Axr479e58bZ8fCAQc4vulwDATPGHa4g= X-MC-Unique: Fbjc6r2XO6KOAzdg5Y6g-A-1 From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Vladimir Sementsov-Ogievskiy , Eric Blake , Kevin Wolf , Stefan Hajnoczi , Fam Zheng Subject: [PATCH 1/4] util/iov: Make qiov_slice() public Date: Fri, 17 Mar 2023 18:50:16 +0100 Message-Id: <20230317175019.10857-2-hreitz@redhat.com> In-Reply-To: <20230317175019.10857-1-hreitz@redhat.com> References: <20230317175019.10857-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1679075471956100003 Content-Type: text/plain; charset="utf-8" We want to inline qemu_iovec_init_extended() in block/io.c for padding requests, and having access to qiov_slice() is useful for this. (We will need to count the number of I/O vector elements of a slice there, and then later process this slice. Without qiov_slice(), we would need to call qemu_iovec_subvec_niov(), and all further IOV-processing functions may need to skip prefixing elements to accomodate for a qiov_offset. Because qemu_iovec_subvec_niov() internally calls qiov_slice(), we can just have the block/io.c code call qiov_slice() itself, thus get the number of elements, and also create an iovec array with the superfluous prefixing elements stripped, so the following processing functions no longer need to skip them.) Signed-off-by: Hanna Czenczek Acked-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/qemu/iov.h | 3 +++ util/iov.c | 14 +++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 9330746680..46fadfb27a 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -229,6 +229,9 @@ int qemu_iovec_init_extended( void *tail_buf, size_t tail_len); void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, size_t offset, size_t len); +struct iovec *qemu_iovec_slice(QEMUIOVector *qiov, + size_t offset, size_t len, + size_t *head, size_t *tail, int *niov); int qemu_iovec_subvec_niov(QEMUIOVector *qiov, size_t offset, size_t len); void qemu_iovec_add(QEMUIOVector *qiov, void *base, size_t len); void qemu_iovec_concat(QEMUIOVector *dst, diff --git a/util/iov.c b/util/iov.c index b4be580022..65a70449da 100644 --- a/util/iov.c +++ b/util/iov.c @@ -378,15 +378,15 @@ static struct iovec *iov_skip_offset(struct iovec *io= v, size_t offset, } =20 /* - * qiov_slice + * qemu_iovec_slice * * Find subarray of iovec's, containing requested range. @head would * be offset in first iov (returned by the function), @tail would be * count of extra bytes in last iovec (returned iov + @niov - 1). */ -static struct iovec *qiov_slice(QEMUIOVector *qiov, - size_t offset, size_t len, - size_t *head, size_t *tail, int *niov) +struct iovec *qemu_iovec_slice(QEMUIOVector *qiov, + size_t offset, size_t len, + size_t *head, size_t *tail, int *niov) { struct iovec *iov, *end_iov; =20 @@ -411,7 +411,7 @@ int qemu_iovec_subvec_niov(QEMUIOVector *qiov, size_t o= ffset, size_t len) size_t head, tail; int niov; =20 - qiov_slice(qiov, offset, len, &head, &tail, &niov); + qemu_iovec_slice(qiov, offset, len, &head, &tail, &niov); =20 return niov; } @@ -439,8 +439,8 @@ int qemu_iovec_init_extended( } =20 if (mid_len) { - mid_iov =3D qiov_slice(mid_qiov, mid_offset, mid_len, - &mid_head, &mid_tail, &mid_niov); + mid_iov =3D qemu_iovec_slice(mid_qiov, mid_offset, mid_len, + &mid_head, &mid_tail, &mid_niov); } =20 total_niov =3D !!head_len + mid_niov + !!tail_len; --=20 2.39.1 From nobody Fri Mar 29 06:36:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1679075519; cv=none; d=zohomail.com; s=zohoarc; b=PuXlQZyDBHi8zHEC4u8wbt8PBbKD5QuPF1FyHvcAWZtaJ6cjMZaGu6B5a9LeuJ8ZqioKItSsyfPbSucFSbhyZ2DsvZlaUxoRzoc1NsBf9IBA1TfdRqu9uzjUJncKclp5zrFTafmNUSRLVeL3qPPtNs1zxhvZj6XRl+xVyrCM3tI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679075519; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=S/jAFkdZ7WZ79Kvz2BeV4bdrEywjIaJlPC+Z//RsStw=; b=NjYxR9vy06n0naKzhB4pocrqtkkERW+MHq6IRQFpVQZqmGJyDRpHG7280c84Q7PMrI5BN89d2E+L8qO9A2bUXAoYII/13e2/G0SYXbYHyAxScTvIjEghRHwDXkvkUn4yIKMtkJCfUiZL+owuqBVOIW11CvLd7sm+pTi0hAFKnzM= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1679075519549849.3467638143063; Fri, 17 Mar 2023 10:51:59 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pdEDp-0003HU-19; Fri, 17 Mar 2023 13:50:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDn-0003Fu-4d for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:31 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDl-0001rx-01 for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:30 -0400 Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-82-ITzzXOnlOTWjuUKf-_njBA-1; Fri, 17 Mar 2023 13:50:25 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D0E4128237CC; Fri, 17 Mar 2023 17:50:24 +0000 (UTC) Received: from localhost (unknown [10.39.193.108]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4C2C02166B26; Fri, 17 Mar 2023 17:50:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679075428; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S/jAFkdZ7WZ79Kvz2BeV4bdrEywjIaJlPC+Z//RsStw=; b=VcNjsuJVsQEhkzA+2qbnsgQp2KaL2ALzI84EBSd6AZ8yw8g3CmulpcvQEgWTwX6iuO3ig4 YFPF55iddA693HKwb4NmMtZCvJI16xVRayiRj16OfJcv2401OcXyLcRiIQ23J9LTWe9t1C iESVjLVeXqxoR62t7P19vPNMLNNUvNw= X-MC-Unique: ITzzXOnlOTWjuUKf-_njBA-1 From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Vladimir Sementsov-Ogievskiy , Eric Blake , Kevin Wolf , Stefan Hajnoczi , Fam Zheng Subject: [PATCH 2/4] block: Split padded I/O vectors exceeding IOV_MAX Date: Fri, 17 Mar 2023 18:50:17 +0100 Message-Id: <20230317175019.10857-3-hreitz@redhat.com> In-Reply-To: <20230317175019.10857-1-hreitz@redhat.com> References: <20230317175019.10857-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=170.10.133.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1679075519859100001 Content-Type: text/plain; charset="utf-8" When processing vectored guest requests that are not aligned to the storage request alignment, we pad them by adding head and/or tail buffers for a read-modify-write cycle. The guest can submit I/O vectors up to IOV_MAX (1024) in length, but with this padding, the vector can exceed that limit. As of 4c002cef0e9abe7135d7916c51abce47f7fc1ee2 ("util/iov: make qemu_iovec_init_extended() honest"), we refuse to pad vectors beyond the limit, instead returning an error to the guest. To the guest, this appears as a random I/O error. We should not return an I/O error to the guest when it issued a perfectly valid request. Before 4c002cef0e9abe7135d7916c51abce47f7fc1ee2, we just made the vector longer than IOV_MAX, which generally seems to work (because the guest assumes a smaller alignment than we really have, file-posix's raw_co_prw() will generally see bdrv_qiov_is_aligned() return false, and so emulate the request, so that the IOV_MAX does not matter). However, that does not seem exactly great. I see two ways to fix this problem: 1. We split such long requests into two requests. 2. We join some elements of the vector into new buffers to make it shorter. I am wary of (1), because it seems like it may have unintended side effects. (2) on the other hand seems relatively simple to implement, with hopefully few side effects, so this patch does that. To do this, the use of qemu_iovec_init_extended() in bdrv_pad_request() is effectively replaced by the new function bdrv_create_padded_qiov(), which not only wraps the request IOV with padding head/tail, but also ensures that the resulting vector will not have more than IOV_MAX elements. Putting that functionality into qemu_iovec_init_extended() is infeasible because it requires allocating a bounce buffer; doing so would require many more parameters (buffer alignment, how to initialize the buffer, and out parameters like the buffer, its length, and the original elements), which is not reasonable. Conversely, it is not difficult to move qemu_iovec_init_extended()'s functionality into bdrv_create_padded_qiov() by using public qemu_iovec_* functions, so that is what this patch does. Because bdrv_pad_request() was the only "serious" user of qemu_iovec_init_extended(), the next patch will remove the latter function, so the functionality is not implemented twice. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D2141964 Signed-off-by: Hanna Czenczek Acked-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/io.c | 153 +++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 143 insertions(+), 10 deletions(-) diff --git a/block/io.c b/block/io.c index 8974d46941..1e9cdba17a 100644 --- a/block/io.c +++ b/block/io.c @@ -1435,6 +1435,14 @@ out: * @merge_reads is true for small requests, * if @buf_len =3D=3D @head + bytes + @tail. In this case it is possible t= hat both * head and tail exist but @buf_len =3D=3D align and @tail_buf =3D=3D @buf. + * + * @write is true for write requests, false for read requests. + * + * If padding makes the vector too long (exceeding IOV_MAX), then we need = to + * merge existing vector elements into a single one. @collapse_bounce_buf= acts + * as the bounce buffer in such cases. @pre_collapse_qiov has the pre-col= lapse + * I/O vector elements so for read requests, the data can be copied back a= fter + * the read is done. */ typedef struct BdrvRequestPadding { uint8_t *buf; @@ -1443,11 +1451,17 @@ typedef struct BdrvRequestPadding { size_t head; size_t tail; bool merge_reads; + bool write; QEMUIOVector local_qiov; + + uint8_t *collapse_bounce_buf; + size_t collapse_len; + QEMUIOVector pre_collapse_qiov; } BdrvRequestPadding; =20 static bool bdrv_init_padding(BlockDriverState *bs, int64_t offset, int64_t bytes, + bool write, BdrvRequestPadding *pad) { int64_t align =3D bs->bl.request_alignment; @@ -1479,6 +1493,8 @@ static bool bdrv_init_padding(BlockDriverState *bs, pad->tail_buf =3D pad->buf + pad->buf_len - align; } =20 + pad->write =3D write; + return true; } =20 @@ -1545,6 +1561,18 @@ zero_mem: =20 static void bdrv_padding_destroy(BdrvRequestPadding *pad) { + if (pad->collapse_bounce_buf) { + if (!pad->write) { + /* + * If padding required elements in the vector to be collapsed = into a + * bounce buffer, copy the bounce buffer content back + */ + qemu_iovec_from_buf(&pad->pre_collapse_qiov, 0, + pad->collapse_bounce_buf, pad->collapse_le= n); + } + qemu_vfree(pad->collapse_bounce_buf); + qemu_iovec_destroy(&pad->pre_collapse_qiov); + } if (pad->buf) { qemu_vfree(pad->buf); qemu_iovec_destroy(&pad->local_qiov); @@ -1552,6 +1580,101 @@ static void bdrv_padding_destroy(BdrvRequestPadding= *pad) memset(pad, 0, sizeof(*pad)); } =20 +/* + * Create pad->local_qiov by wrapping @iov in the padding head and tail, w= hile + * ensuring that the resulting vector will not exceed IOV_MAX elements. + * + * To ensure this, when necessary, the first couple of elements (up to thr= ee) + * of @iov are merged into pad->collapse_bounce_buf and replaced by a refe= rence + * to that bounce buffer in pad->local_qiov. + * + * After performing a read request, the data from the bounce buffer must be + * copied back into pad->pre_collapse_qiov (e.g. by bdrv_padding_destroy()= ). + */ +static int bdrv_create_padded_qiov(BlockDriverState *bs, + BdrvRequestPadding *pad, + struct iovec *iov, int niov, + size_t iov_offset, size_t bytes) +{ + int padded_niov, surplus_count, collapse_count; + + /* Assert this invariant */ + assert(niov <=3D IOV_MAX); + + /* + * Cannot pad if resulting length would exceed SIZE_MAX. Returning an= error + * to the guest is not ideal, but there is little else we can do. At = least + * this will practically never happen on 64-bit systems. + */ + if (SIZE_MAX - pad->head < bytes || + SIZE_MAX - pad->head - bytes < pad->tail) + { + return -EINVAL; + } + + /* Length of the resulting IOV if we just concatenated everything */ + padded_niov =3D !!pad->head + niov + !!pad->tail; + + qemu_iovec_init(&pad->local_qiov, MIN(padded_niov, IOV_MAX)); + + if (pad->head) { + qemu_iovec_add(&pad->local_qiov, pad->buf, pad->head); + } + + /* + * If padded_niov > IOV_MAX, we cannot just concatenate everything. + * Instead, merge the first couple of elements of @iov to reduce the n= umber + * of vector elements as necessary. + */ + if (padded_niov > IOV_MAX) { + /* + * Only head and tail can have lead to the number of entries excee= ding + * IOV_MAX, so we can exceed it by the head and tail at most. We = need + * to reduce the number of elements by `surplus_count`, so we merg= e that + * many elements plus one into one element. + */ + surplus_count =3D padded_niov - IOV_MAX; + assert(surplus_count <=3D !!pad->head + !!pad->tail); + collapse_count =3D surplus_count + 1; + + /* + * Move the elements to collapse into `pad->pre_collapse_qiov`, th= en + * advance `iov` (and associated variables) by those elements. + */ + qemu_iovec_init(&pad->pre_collapse_qiov, collapse_count); + qemu_iovec_concat_iov(&pad->pre_collapse_qiov, iov, + collapse_count, iov_offset, SIZE_MAX); + iov +=3D collapse_count; + iov_offset =3D 0; + niov -=3D collapse_count; + bytes -=3D pad->pre_collapse_qiov.size; + + /* + * Construct the bounce buffer to match the length of the to-colla= pse + * vector elements, and for write requests, initialize it with the= data + * from those elements. Then add it to `pad->local_qiov`. + */ + pad->collapse_len =3D pad->pre_collapse_qiov.size; + pad->collapse_bounce_buf =3D qemu_blockalign(bs, pad->collapse_len= ); + if (pad->write) { + qemu_iovec_to_buf(&pad->pre_collapse_qiov, 0, + pad->collapse_bounce_buf, pad->collapse_len); + } + qemu_iovec_add(&pad->local_qiov, + pad->collapse_bounce_buf, pad->collapse_len); + } + + qemu_iovec_concat_iov(&pad->local_qiov, iov, niov, iov_offset, bytes); + + if (pad->tail) { + qemu_iovec_add(&pad->local_qiov, + pad->buf + pad->buf_len - pad->tail, pad->tail); + } + + assert(pad->local_qiov.niov =3D=3D MIN(padded_niov, IOV_MAX)); + return 0; +} + /* * bdrv_pad_request * @@ -1559,6 +1682,8 @@ static void bdrv_padding_destroy(BdrvRequestPadding *= pad) * read of padding, bdrv_padding_rmw_read() should be called separately if * needed. * + * @write is true for write requests, false for read requests. + * * Request parameters (@qiov, &qiov_offset, &offset, &bytes) are in-out: * - on function start they represent original request * - on failure or when padding is not needed they are unchanged @@ -1567,24 +1692,32 @@ static void bdrv_padding_destroy(BdrvRequestPadding= *pad) static int bdrv_pad_request(BlockDriverState *bs, QEMUIOVector **qiov, size_t *qiov_offset, int64_t *offset, int64_t *bytes, + bool write, BdrvRequestPadding *pad, bool *padded, BdrvRequestFlags *flags) { int ret; + struct iovec *sliced_iov; + int sliced_niov; + size_t sliced_head, sliced_tail; =20 bdrv_check_qiov_request(*offset, *bytes, *qiov, *qiov_offset, &error_a= bort); =20 - if (!bdrv_init_padding(bs, *offset, *bytes, pad)) { + if (!bdrv_init_padding(bs, *offset, *bytes, write, pad)) { if (padded) { *padded =3D false; } return 0; } =20 - ret =3D qemu_iovec_init_extended(&pad->local_qiov, pad->buf, pad->head, - *qiov, *qiov_offset, *bytes, - pad->buf + pad->buf_len - pad->tail, - pad->tail); + sliced_iov =3D qemu_iovec_slice(*qiov, *qiov_offset, *bytes, + &sliced_head, &sliced_tail, + &sliced_niov); + + /* Guaranteed by bdrv_check_qiov_request() */ + assert(*bytes <=3D SIZE_MAX); + ret =3D bdrv_create_padded_qiov(bs, pad, sliced_iov, sliced_niov, + sliced_head, *bytes); if (ret < 0) { bdrv_padding_destroy(pad); return ret; @@ -1653,8 +1786,8 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child, flags |=3D BDRV_REQ_COPY_ON_READ; } =20 - ret =3D bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, &pa= d, - NULL, &flags); + ret =3D bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes, fal= se, + &pad, NULL, &flags); if (ret < 0) { goto fail; } @@ -1996,7 +2129,7 @@ bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t off= set, int64_t bytes, /* This flag doesn't make sense for padding or zero writes */ flags &=3D ~BDRV_REQ_REGISTERED_BUF; =20 - padding =3D bdrv_init_padding(bs, offset, bytes, &pad); + padding =3D bdrv_init_padding(bs, offset, bytes, true, &pad); if (padding) { assert(!(flags & BDRV_REQ_NO_WAIT)); bdrv_make_request_serialising(req, align); @@ -2112,8 +2245,8 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *chil= d, * bdrv_co_do_zero_pwritev() does aligning by itself, so, we do * alignment only if there is no ZERO flag. */ - ret =3D bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes,= &pad, - &padded, &flags); + ret =3D bdrv_pad_request(bs, &qiov, &qiov_offset, &offset, &bytes,= true, + &pad, &padded, &flags); if (ret < 0) { return ret; } --=20 2.39.1 From nobody Fri Mar 29 06:36:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1679075487; cv=none; d=zohomail.com; s=zohoarc; b=RJwxW4nSHVLWZ4EGX3VriSdR7rZx8JdbUVSk0gXKCanwatKFsRiUh/aLhs9E7GNudsB4C0ECp7aWrX/pFzsK9+SWI52Wd9itcxrIZTTrPPbaeFaX26TTwQ26gWk5nOAkBMA8SZnS55jCyyEDaP0U/C+yk0A6jGfmqc8gBLkOWtY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679075487; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=cfyG5xA2cYgdiI5VTO99mBxf6pd4N6F8raBJRO/Vw+Q=; b=mOm99ApsDVoYqyBAr4xdsQpJoaMuHWqCenzUH+4SvHM/Bk9tJAKWutLjdexPiMSguqpyByw9hz+HdsTs3lAXoCbHqlgKPWmGxvWEPnYZyAscE6rYgT6UzHRm+eT9Qux/LLWvuTbSYQ21CojvNP6q0a9Vb7ks5b9eLYwUioKbNy8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1679075487829516.1846791641943; Fri, 17 Mar 2023 10:51:27 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pdEDq-0003ID-HZ; Fri, 17 Mar 2023 13:50:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDo-0003HT-Ux for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:32 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDn-0001sm-C1 for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:32 -0400 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-219-pLi-0wJqNIitjd4fEfttWQ-1; Fri, 17 Mar 2023 13:50:26 -0400 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 80692101A54F; Fri, 17 Mar 2023 17:50:26 +0000 (UTC) Received: from localhost (unknown [10.39.193.108]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3B5ED40D1C8; Fri, 17 Mar 2023 17:50:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679075430; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cfyG5xA2cYgdiI5VTO99mBxf6pd4N6F8raBJRO/Vw+Q=; b=hS3WKg6sNf57N1vXwTz4iHA2aA8Yhl/mW6eRtGddjZnRnY9W57lX57mKtg7Cu2kh1ThIvA 9Li5crGh0VcG1TG5uXIH19/sG/my6JvzuBoWgT6ayrvGbybOWHnU8qI7R9c6kxE3DcCiW9 rFC8X7uCuP8u0IEO8BaFTbLsLGmTbiw= X-MC-Unique: pLi-0wJqNIitjd4fEfttWQ-1 From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Vladimir Sementsov-Ogievskiy , Eric Blake , Kevin Wolf , Stefan Hajnoczi , Fam Zheng Subject: [PATCH 3/4] util/iov: Remove qemu_iovec_init_extended() Date: Fri, 17 Mar 2023 18:50:18 +0100 Message-Id: <20230317175019.10857-4-hreitz@redhat.com> In-Reply-To: <20230317175019.10857-1-hreitz@redhat.com> References: <20230317175019.10857-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1679075489599100003 Content-Type: text/plain; charset="utf-8" bdrv_pad_request() was the main user of qemu_iovec_init_extended(). HEAD^ has removed that use, so we can remove qemu_iovec_init_extended() now. The only remaining user is qemu_iovec_init_slice(), which can easily inline the small part it really needs. Note that qemu_iovec_init_extended() offered a memcpy() optimization to initialize the new I/O vector. qemu_iovec_concat_iov(), which is used to replace its functionality, does not, but calls qemu_iovec_add() for every single element. If we decide this optimization was important, we will need to re-implement it in qemu_iovec_concat_iov(), which might also benefit its pre-existing users. Signed-off-by: Hanna Czenczek Acked-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- include/qemu/iov.h | 5 --- util/iov.c | 79 +++++++--------------------------------------- 2 files changed, 11 insertions(+), 73 deletions(-) diff --git a/include/qemu/iov.h b/include/qemu/iov.h index 46fadfb27a..63a1c01965 100644 --- a/include/qemu/iov.h +++ b/include/qemu/iov.h @@ -222,11 +222,6 @@ static inline void *qemu_iovec_buf(QEMUIOVector *qiov) =20 void qemu_iovec_init(QEMUIOVector *qiov, int alloc_hint); void qemu_iovec_init_external(QEMUIOVector *qiov, struct iovec *iov, int n= iov); -int qemu_iovec_init_extended( - QEMUIOVector *qiov, - void *head_buf, size_t head_len, - QEMUIOVector *mid_qiov, size_t mid_offset, size_t mid_len, - void *tail_buf, size_t tail_len); void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, size_t offset, size_t len); struct iovec *qemu_iovec_slice(QEMUIOVector *qiov, diff --git a/util/iov.c b/util/iov.c index 65a70449da..866fb577f3 100644 --- a/util/iov.c +++ b/util/iov.c @@ -416,70 +416,6 @@ int qemu_iovec_subvec_niov(QEMUIOVector *qiov, size_t = offset, size_t len) return niov; } =20 -/* - * Compile new iovec, combining @head_buf buffer, sub-qiov of @mid_qiov, - * and @tail_buf buffer into new qiov. - */ -int qemu_iovec_init_extended( - QEMUIOVector *qiov, - void *head_buf, size_t head_len, - QEMUIOVector *mid_qiov, size_t mid_offset, size_t mid_len, - void *tail_buf, size_t tail_len) -{ - size_t mid_head, mid_tail; - int total_niov, mid_niov =3D 0; - struct iovec *p, *mid_iov =3D NULL; - - assert(mid_qiov->niov <=3D IOV_MAX); - - if (SIZE_MAX - head_len < mid_len || - SIZE_MAX - head_len - mid_len < tail_len) - { - return -EINVAL; - } - - if (mid_len) { - mid_iov =3D qemu_iovec_slice(mid_qiov, mid_offset, mid_len, - &mid_head, &mid_tail, &mid_niov); - } - - total_niov =3D !!head_len + mid_niov + !!tail_len; - if (total_niov > IOV_MAX) { - return -EINVAL; - } - - if (total_niov =3D=3D 1) { - qemu_iovec_init_buf(qiov, NULL, 0); - p =3D &qiov->local_iov; - } else { - qiov->niov =3D qiov->nalloc =3D total_niov; - qiov->size =3D head_len + mid_len + tail_len; - p =3D qiov->iov =3D g_new(struct iovec, qiov->niov); - } - - if (head_len) { - p->iov_base =3D head_buf; - p->iov_len =3D head_len; - p++; - } - - assert(!mid_niov =3D=3D !mid_len); - if (mid_niov) { - memcpy(p, mid_iov, mid_niov * sizeof(*p)); - p[0].iov_base =3D (uint8_t *)p[0].iov_base + mid_head; - p[0].iov_len -=3D mid_head; - p[mid_niov - 1].iov_len -=3D mid_tail; - p +=3D mid_niov; - } - - if (tail_len) { - p->iov_base =3D tail_buf; - p->iov_len =3D tail_len; - } - - return 0; -} - /* * Check if the contents of subrange of qiov data is all zeroes. */ @@ -511,14 +447,21 @@ bool qemu_iovec_is_zero(QEMUIOVector *qiov, size_t of= fset, size_t bytes) void qemu_iovec_init_slice(QEMUIOVector *qiov, QEMUIOVector *source, size_t offset, size_t len) { - int ret; + struct iovec *slice_iov; + int slice_niov; + size_t slice_head, slice_tail; =20 assert(source->size >=3D len); assert(source->size - len >=3D offset); =20 - /* We shrink the request, so we can't overflow neither size_t nor MAX_= IOV */ - ret =3D qemu_iovec_init_extended(qiov, NULL, 0, source, offset, len, N= ULL, 0); - assert(ret =3D=3D 0); + slice_iov =3D qemu_iovec_slice(source, offset, len, + &slice_head, &slice_tail, &slice_niov); + if (slice_niov =3D=3D 1) { + qemu_iovec_init_buf(qiov, slice_iov[0].iov_base + slice_head, len); + } else { + qemu_iovec_init(qiov, slice_niov); + qemu_iovec_concat_iov(qiov, slice_iov, slice_niov, slice_head, len= ); + } } =20 void qemu_iovec_destroy(QEMUIOVector *qiov) --=20 2.39.1 From nobody Fri Mar 29 06:36:55 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1679075495; cv=none; d=zohomail.com; s=zohoarc; b=kMysORVAMoq466ikYVGNkfUJAPVmxgAxd/PTerUr1uPt78v5QC16SwcE0SxCwy81sCFYb7GcxYC3AF00tgIDAl9Pv64tVOWC18XNuIHV4nSBIQrcfqqReBJ+5D9QBCv4W/ruyX5EHve7qQHptOsaGg+MkYJO+IDYIEqyJUwNsRg= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1679075495; h=Content-Type:Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=dxbujlmIm17bJAmGAy2mXMVgq8Bq8dCuw5A2QqXTsy0=; b=SCDh06A41RPcB273z4OCss81qn+bNLJPEOnhMZSghjh6gu2Acygbo14bAdjMYSpA/wLNAU0KMVfX8xURBvWc9q2D1F/6f3/Xl187o5uwE3JzLqXi3zE0upiRKvdIXM5fH620DxW1mI52mEzNXQ5ppKMickpBRmy4vjL8sKdjBxs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1679075495042550.8708378168861; Fri, 17 Mar 2023 10:51:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1pdEDt-0003JB-IE; Fri, 17 Mar 2023 13:50:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDr-0003IY-HJ for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1pdEDp-0001tQ-CX for qemu-devel@nongnu.org; Fri, 17 Mar 2023 13:50:35 -0400 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-341-PjazCVtYPs26mmUMUXBHZg-1; Fri, 17 Mar 2023 13:50:28 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.rdu2.redhat.com [10.11.54.8]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 13DF785A588; Fri, 17 Mar 2023 17:50:28 +0000 (UTC) Received: from localhost (unknown [10.39.193.108]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B6965C15BA0; Fri, 17 Mar 2023 17:50:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1679075431; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dxbujlmIm17bJAmGAy2mXMVgq8Bq8dCuw5A2QqXTsy0=; b=XEoQyIR8khuBCnqDy/u4Ey9lAr4OllxstxAw0NgoX00wxKmsi4FY5GtHdxX10of2T6cKLH lLC3cT68HTW5UgGggYeaz+9/HP4d8xOAxEdsSlEqFNP7ZUchjnPIOO5zmEKX0h9tSKf2aD 6esUJWxvbZe9dVJC++itcQJcfXZprmg= X-MC-Unique: PjazCVtYPs26mmUMUXBHZg-1 From: Hanna Czenczek To: qemu-block@nongnu.org Cc: qemu-devel@nongnu.org, Hanna Czenczek , Vladimir Sementsov-Ogievskiy , Eric Blake , Kevin Wolf , Stefan Hajnoczi , Fam Zheng Subject: [PATCH 4/4] iotests/iov-padding: New test Date: Fri, 17 Mar 2023 18:50:19 +0100 Message-Id: <20230317175019.10857-5-hreitz@redhat.com> In-Reply-To: <20230317175019.10857-1-hreitz@redhat.com> References: <20230317175019.10857-1-hreitz@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-Scanned-By: MIMEDefang 3.1 on 10.11.54.8 Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=170.10.129.124; envelope-from=hreitz@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=-0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1679075496097100001 Content-Type: text/plain; charset="utf-8" Test that even vectored IO requests with 1024 vector elements that are not aligned to the device's request alignment will succeed. Signed-off-by: Hanna Czenczek Acked-by: Stefan Hajnoczi Reviewed-by: Eric Blake Reviewed-by: Vladimir Sementsov-Ogievskiy --- tests/qemu-iotests/tests/iov-padding | 85 ++++++++++++++++++++++++ tests/qemu-iotests/tests/iov-padding.out | 59 ++++++++++++++++ 2 files changed, 144 insertions(+) create mode 100755 tests/qemu-iotests/tests/iov-padding create mode 100644 tests/qemu-iotests/tests/iov-padding.out diff --git a/tests/qemu-iotests/tests/iov-padding b/tests/qemu-iotests/test= s/iov-padding new file mode 100755 index 0000000000..b9604900c7 --- /dev/null +++ b/tests/qemu-iotests/tests/iov-padding @@ -0,0 +1,85 @@ +#!/usr/bin/env bash +# group: rw quick +# +# Check the interaction of request padding (to fit alignment restrictions)= with +# vectored I/O from the guest +# +# Copyright Red Hat +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# + +seq=3D$(basename $0) +echo "QA output created by $seq" + +status=3D1 # failure is the default! + +_cleanup() +{ + _cleanup_test_img +} +trap "_cleanup; exit \$status" 0 1 2 3 15 + +# get standard environment, filters and checks +cd .. +. ./common.rc +. ./common.filter + +_supported_fmt raw +_supported_proto file + +_make_test_img 1M + +IMGSPEC=3D"driver=3Dblkdebug,align=3D4096,image.driver=3Dfile,image.filena= me=3D$TEST_IMG" + +# Four combinations: +# - Offset 4096, length 1023 * 512 + 512: Fully aligned to 4k +# - Offset 4096, length 1023 * 512 + 4096: Head is aligned, tail is not +# - Offset 512, length 1023 * 512 + 512: Neither head nor tail are aligned +# - Offset 512, length 1023 * 512 + 4096: Tail is aligned, head is not +for start_offset in 4096 512; do + for last_element_length in 512 4096; do + length=3D$((1023 * 512 + $last_element_length)) + + echo + echo "=3D=3D performing 1024-element vectored requests to image (o= ffset: $start_offset; length: $length) =3D=3D" + + # Fill with data for testing + $QEMU_IO -c 'write -P 1 0 1M' "$TEST_IMG" | _filter_qemu_io + + # 1023 512-byte buffers, and then one with length $last_element_le= ngth + cmd_params=3D"-P 2 $start_offset $(yes 512 | head -n 1023 | tr '\n= ' ' ') $last_element_length" + QEMU_IO_OPTIONS=3D"$QEMU_IO_OPTIONS_NO_FMT" $QEMU_IO \ + -c "writev $cmd_params" \ + --image-opts \ + "$IMGSPEC" \ + | _filter_qemu_io + + # Read all patterns -- read the part we just wrote with writev twi= ce, + # once "normally", and once with a readv, so we see that that work= s, too + QEMU_IO_OPTIONS=3D"$QEMU_IO_OPTIONS_NO_FMT" $QEMU_IO \ + -c "read -P 1 0 $start_offset" \ + -c "read -P 2 $start_offset $length" \ + -c "readv $cmd_params" \ + -c "read -P 1 $((start_offset + length)) $((1024 * 1024 - leng= th - start_offset))" \ + --image-opts \ + "$IMGSPEC" \ + | _filter_qemu_io + done +done + +# success, all done +echo "*** done" +rm -f $seq.full +status=3D0 diff --git a/tests/qemu-iotests/tests/iov-padding.out b/tests/qemu-iotests/= tests/iov-padding.out new file mode 100644 index 0000000000..e07a91fac7 --- /dev/null +++ b/tests/qemu-iotests/tests/iov-padding.out @@ -0,0 +1,59 @@ +QA output created by iov-padding +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D1048576 + +=3D=3D performing 1024-element vectored requests to image (offset: 4096; l= ength: 524288) =3D=3D +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 524288/524288 bytes at offset 4096 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 524288/524288 bytes at offset 4096 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 524288/524288 bytes at offset 4096 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 520192/520192 bytes at offset 528384 +508 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D performing 1024-element vectored requests to image (offset: 4096; l= ength: 527872) =3D=3D +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 527872/527872 bytes at offset 4096 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 527872/527872 bytes at offset 4096 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 527872/527872 bytes at offset 4096 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 516608/516608 bytes at offset 531968 +504.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D performing 1024-element vectored requests to image (offset: 512; le= ngth: 524288) =3D=3D +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 524288/524288 bytes at offset 512 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 524288/524288 bytes at offset 512 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 524288/524288 bytes at offset 512 +512 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 523776/523776 bytes at offset 524800 +511.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) + +=3D=3D performing 1024-element vectored requests to image (offset: 512; le= ngth: 527872) =3D=3D +wrote 1048576/1048576 bytes at offset 0 +1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +wrote 527872/527872 bytes at offset 512 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 527872/527872 bytes at offset 512 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 527872/527872 bytes at offset 512 +515.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +read 520192/520192 bytes at offset 528384 +508 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +*** done --=20 2.39.1