From nobody Sun Apr 5 18:18:41 2026 Received: from cae.in-ulm.de (cae.in-ulm.de [217.10.14.231]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9888537D116 for ; Mon, 23 Mar 2026 21:34:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.10.14.231 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774301654; cv=none; b=uHSRNUeqxaHZWvY3sQ7Emfy/LtapbJVxwurtYcmbue87tzey3gvjtMMnmRLgfLjibqhEwQtJI8kIzmmdDlSPaPmknWV+FhMgfENPE2CS7LuIPScLkPsekTuqCcXzTZ7y4M1ylbQeOtSF3ij6pVR8+ivDZYsw89dBseY5XW6zKsc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774301654; c=relaxed/simple; bh=QXHgGAoosmB6rRU5PS3q9dGMjqAmqlHwGmjTU5nxlVU=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Dtp8t9yTVkm4Y0i9h/HpR4IFweWJTyzL61J0MGmGx4EDlVA1E3erETb/UHcvO09K3REVcV8Kva/CKtHbQbf6zH6LH4BWd4mv6kv3EgH6Q6D+/aoddESe25iSLn+kSbZ7QXgH3dY82J6vNFCLDi3dbccvryTgn6K1BirCV32BR1k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de; spf=pass smtp.mailfrom=c--e.de; arc=none smtp.client-ip=217.10.14.231 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=c--e.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=c--e.de Received: by cae.in-ulm.de (Postfix, from userid 1000) id 1AAEF14008B; Mon, 23 Mar 2026 22:24:01 +0100 (CET) From: "Christian A. Ehrhardt" To: linux-kernel@vger.kernel.org, Andrew Morton , David Howells Cc: "Christian A. Ehrhardt" , Kees Cook , Petr Mladek , David Gow Subject: [PATCH RESEND 2/3] lib: kunit_iov_iter: Add tests for extract_iter_to_sg Date: Mon, 23 Mar 2026 22:23:49 +0100 Message-Id: <20260323212350.807118-3-lk@c--e.de> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20260323212350.807118-1-lk@c--e.de> References: <20260323212350.807118-1-lk@c--e.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add test cases that test extract_iter_to_sg. For each iterator type an iterator is loaded with a kernel buffer. The iterator is then extracted to a scatterlist and the scatterlist is copied into a scratch buffer. The test passes if the scratch buffer compares equal to the original buffer. The new tests demostrate a bug in extract_iter_to_sg for kvec iterators and one of the tests will fail. This is fixed in the next commit. Cc: David Howells Cc: Andrew Morton Signed-off-by: Christian A. Ehrhardt --- lib/tests/kunit_iov_iter.c | 140 +++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) diff --git a/lib/tests/kunit_iov_iter.c b/lib/tests/kunit_iov_iter.c index c32fbdbb2544..aa6a19ca6dad 100644 --- a/lib/tests/kunit_iov_iter.c +++ b/lib/tests/kunit_iov_iter.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include =20 @@ -1014,6 +1015,141 @@ static void __init iov_kunit_extract_pages_xarray(s= truct kunit *test) KUNIT_SUCCEED(test); } =20 +struct iov_kunit_iter_to_sg_data { + struct sg_table sgt; + u8 *buffer, *scratch; + struct page **pages; + size_t npages; +}; + +static void __init +iov_kunit_iter_to_sg_init(struct kunit *test, size_t bufsize, + struct iov_kunit_iter_to_sg_data *data) +{ + struct page **spages; + struct scatterlist *sg; + size_t i; + + data->npages =3D bufsize / PAGE_SIZE; + sg =3D kunit_kmalloc_array(test, data->npages, sizeof(*sg), GFP_KERNEL); + sg_init_table(sg, data->npages); + memset(&data->sgt, 0, sizeof(data->sgt)); + data->sgt.orig_nents =3D data->npages; + data->sgt.sgl =3D sg; + + data->buffer =3D iov_kunit_create_buffer(test, &data->pages, + data->npages); + data->scratch =3D iov_kunit_create_buffer(test, &spages, data->npages); + for (i =3D 0; i < bufsize; ++i) + data->buffer[i] =3D pattern(i); + memset(data->scratch, 0, bufsize); +} + +static void __init +iov_kunit_iter_to_sg_check(struct kunit *test, struct iov_iter *iter, + size_t bufsize, + struct iov_kunit_iter_to_sg_data *data) +{ + size_t i; + + i =3D extract_iter_to_sg(iter, bufsize, &data->sgt, + data->npages, 0); + + KUNIT_EXPECT_EQ(test, i, bufsize); + KUNIT_EXPECT_LE(test, data->sgt.nents, data->npages); + + i =3D sg_copy_to_buffer(data->sgt.sgl, data->sgt.nents, + data->scratch, bufsize); + KUNIT_EXPECT_EQ(test, i, bufsize); + + for (i =3D 0; i < bufsize; ++i) { + KUNIT_EXPECT_EQ_MSG(test, data->buffer[i], data->scratch[i], + "at i=3D%zx", i); + if (data->buffer[i] !=3D data->scratch[i]) + break; + } + + KUNIT_EXPECT_EQ(test, i, bufsize); +} + +static void __init iov_kunit_iter_to_sg_kvec(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct iov_iter iter; + struct kvec kvec; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, &data); + + kvec.iov_base =3D data.buffer; + kvec.iov_len =3D bufsize; + iov_iter_kvec(&iter, READ, &kvec, 1, bufsize); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_bvec(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct page *p, *can_merge =3D NULL; + size_t i, k, bufsize; + struct bio_vec *bvec; + struct iov_iter iter; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, &data); + + bvec =3D kunit_kmalloc_array(test, data.npages, sizeof(*bvec), + GFP_KERNEL); + k =3D 0; + for (i =3D 0; i < data.npages; ++i) { + p =3D data.pages[i]; + if (p =3D=3D can_merge) + bvec[k-1].bv_len +=3D PAGE_SIZE; + else + bvec_set_page(&bvec[k++], p, PAGE_SIZE, 0); + can_merge =3D p + 1; + } + iov_iter_bvec(&iter, READ, bvec, k, bufsize); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_folioq(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct folio_queue *folioq; + struct iov_iter iter; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, &data); + + folioq =3D iov_kunit_create_folioq(test); + iov_kunit_load_folioq(test, &iter, READ, folioq, data.pages, + data.npages); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + +static void __init iov_kunit_iter_to_sg_xarray(struct kunit *test) +{ + struct iov_kunit_iter_to_sg_data data; + struct xarray *xarray; + struct iov_iter iter; + size_t bufsize; + + bufsize =3D 0x100000; + iov_kunit_iter_to_sg_init(test, bufsize, &data); + + xarray =3D iov_kunit_create_xarray(test); + iov_kunit_load_xarray(test, &iter, READ, xarray, data.pages, + data.npages); + + iov_kunit_iter_to_sg_check(test, &iter, bufsize, &data); +} + static struct kunit_case __refdata iov_kunit_cases[] =3D { KUNIT_CASE(iov_kunit_copy_to_kvec), KUNIT_CASE(iov_kunit_copy_from_kvec), @@ -1027,6 +1163,10 @@ static struct kunit_case __refdata iov_kunit_cases[]= =3D { KUNIT_CASE(iov_kunit_extract_pages_bvec), KUNIT_CASE(iov_kunit_extract_pages_folioq), KUNIT_CASE(iov_kunit_extract_pages_xarray), + KUNIT_CASE(iov_kunit_iter_to_sg_kvec), + KUNIT_CASE(iov_kunit_iter_to_sg_bvec), + KUNIT_CASE(iov_kunit_iter_to_sg_folioq), + KUNIT_CASE(iov_kunit_iter_to_sg_xarray), {} }; =20 --=20 2.43.0