Received: by 2002:a05:7412:31a9:b0:e2:908c:2ebd with SMTP id et41csp1117774rdb; Sat, 9 Sep 2023 09:25:57 -0700 (PDT) X-Google-Smtp-Source: AGHT+IES/eFWiR6hM1A3zao3fTBlE6i1/EYOySBkQR/5k3M/ThX4Q64ZXVdLSm8/5iZLb5AOlROT X-Received: by 2002:a17:907:2ccb:b0:9a9:ee3d:48e3 with SMTP id hg11-20020a1709072ccb00b009a9ee3d48e3mr4389111ejc.12.1694276757305; Sat, 09 Sep 2023 09:25:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1694276757; cv=none; d=google.com; s=arc-20160816; b=qqHsPfpS1jPMf+/Q2jE+zLErs7GwmMHoGNIMKMJ2GLgLH9y09GHap4VR8SpzFvPCdG 6R7lhHtFp+XhsRmVPD/aWhuokWcUGVQc7Bsri8UVONBTt4tRg+i+UyQ5bwgdhidds2BF G2zsIQYYXC3GqtJ9IFdGYPX/Am2z4e+wIpT3dN061cAiUVXw1cNQfbzTO7VHtmbDNKEk 6qagiqDjN7aYtzT3Ft+FWol4DO+s04nIB+rCXkT5utVbi+hJOtOS9GHg4w6Kmy0ldhEE aLqqn/0j56tYBQplX0kgWPhEXhutkOpGULSZ6gRKZ5WrKHjXnn/BRpEKE4R++rrevJD3 4ZDg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:user-agent:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=aY0o6GYcvhgn1nQN+f0PdIkspT8SI1sUQTsBD7kEl6U=; fh=SU8r6/al2aH+0KcZ8j8i3AY0hIfx7qqh/EwZJ10sdLY=; b=HmY0OCSjDtxs9F5R3LiU7nx6v4DNa/8Tfpv0LKonHzlBSdMSrVpBqao7Qyhz1DdcmC yG4rwDlfdYMJDFbSWMGw9XTnzHGsouERGzVIZTzPAV+TRpVoGV34rswDCB5iJObCDs4O dyWLNy5LEra5x7gdHQJkLm1yfRLajB6I4iHvm+fBlh6kSqdBOBoX7KVKsEsK9t5dPwxW Q4DLGIYoVD+YSJ6XDHGGcFKtVQgwdH6TuJVWicjKO7X6rEyWQekH5KZZ7C8yUe5Qjv03 r6pszuOiw3HjdfmLzfMAL57yMTjf4iG/FkjNsSmPFbnEfMnmQQGwD6+MS/992xkjglCI lBcw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j9-20020a170906410900b009877bb42154si3626842ejk.465.2023.09.09.09.25.29; Sat, 09 Sep 2023 09:25:57 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345047AbjIILaN (ORCPT + 99 others); Sat, 9 Sep 2023 07:30:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45746 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233881AbjIILaM (ORCPT ); Sat, 9 Sep 2023 07:30:12 -0400 Received: from verein.lst.de (verein.lst.de [213.95.11.211]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2BD1E46; Sat, 9 Sep 2023 04:30:07 -0700 (PDT) Received: by verein.lst.de (Postfix, from userid 2407) id 054DC68B05; Sat, 9 Sep 2023 13:30:01 +0200 (CEST) Date: Sat, 9 Sep 2023 13:30:00 +0200 From: Christoph Hellwig To: David Howells Cc: Jens Axboe , Al Viro , Christoph Hellwig , Matthew Wilcox , Christian Brauner , David Hildenbrand , John Hubbard , Jeff Layton , Linus Torvalds , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org, linux-kselftest@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 2/3] iov_iter: Kunit tests for copying to/from an iterator Message-ID: <20230909113000.GB12045@lst.de> References: <20230908160322.1714302-1-dhowells@redhat.com> <20230908160322.1714302-3-dhowells@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20230908160322.1714302-3-dhowells@redhat.com> User-Agent: Mutt/1.5.17 (2007-11-01) X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > +/* I/O iterator tests. This can only test kernel-backed iterator types. kernel comments start with a: /* and nothing else on the line. (for brevity I'm not going to repeat the comment for the rest of this series) > +static const struct kvec_test_range kvec_test_ranges[] = { > + { 0x00002, 0x00002 }, > + { 0x00027, 0x03000 }, > + { 0x05193, 0x18794 }, > + { 0x20000, 0x20000 }, > + { 0x20000, 0x24000 }, > + { 0x24000, 0x27001 }, > + { 0x29000, 0xffffb }, > + { 0xffffd, 0xffffe }, How were these values picked? Should there be a comment explaining them? > + buffer = vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer); The KUNIT_ASSERT_NOT_ERR_OR_NULL seems misindented. > + */ > +static void __init iov_kunit_copy_to_bvec(struct kunit *test) > +{ > + const struct bvec_test_range *pr; > + struct iov_iter iter; > + struct bio_vec bvec[8]; > + struct page **spages, **bpages; > + u8 *scratch, *buffer; > + size_t bufsize, npages, size, copied; > + int i, b, patt; > + > + bufsize = 0x100000; > + npages = bufsize / PAGE_SIZE; > + > + scratch = iov_kunit_create_buffer(test, &spages, npages); > + for (i = 0; i < bufsize; i++) > + scratch[i] = pattern(i); > + > + buffer = iov_kunit_create_buffer(test, &bpages, npages); > + memset(buffer, 0, bufsize); > + > + iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec), > + bpages, npages, bufsize, bvec_test_ranges); > + size = iter.count; > + > + copied = copy_to_iter(scratch, size, &iter); > + > + KUNIT_EXPECT_EQ(test, copied, size); > + KUNIT_EXPECT_EQ(test, iter.count, 0); > + KUNIT_EXPECT_EQ(test, iter.nr_segs, 0); > + > + /* Build the expected image in the scratch buffer. */ > + b = 0; > + patt = 0; > + memset(scratch, 0, bufsize); > + for (pr = bvec_test_ranges; pr->from >= 0; pr++, b++) { > + u8 *p = scratch + pr->page * PAGE_SIZE; > + > + for (i = pr->from; i < pr->to; i++) > + p[i] = pattern(patt++); > + } > + > + /* Compare the images */ > + for (i = 0; i < bufsize; i++) { > + KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i); > + if (buffer[i] != scratch[i]) > + return; > + } > + > + KUNIT_SUCCEED(); > +} > + > +/* > + * Test copying from a ITER_BVEC-type iterator. > + */ > +static void __init iov_kunit_copy_from_bvec(struct kunit *test) > +{ > + const struct bvec_test_range *pr; > + struct iov_iter iter; > + struct bio_vec bvec[8]; > + struct page **spages, **bpages; > + u8 *scratch, *buffer; > + size_t bufsize, npages, size, copied; > + int i, j; > + > + bufsize = 0x100000; > + npages = bufsize / PAGE_SIZE; > + > + buffer = iov_kunit_create_buffer(test, &bpages, npages); > + for (i = 0; i < bufsize; i++) > + buffer[i] = pattern(i); > + > + scratch = iov_kunit_create_buffer(test, &spages, npages); > + memset(scratch, 0, bufsize); > + > + iov_kunit_load_bvec(test, &iter, WRITE, bvec, ARRAY_SIZE(bvec), > + bpages, npages, bufsize, bvec_test_ranges); > + size = iter.count; > + > + copied = copy_from_iter(scratch, size, &iter); > + > + KUNIT_EXPECT_EQ(test, copied, size); > + KUNIT_EXPECT_EQ(test, iter.count, 0); > + KUNIT_EXPECT_EQ(test, iter.nr_segs, 0); > + > + /* Build the expected image in the main buffer. */ > + i = 0; > + memset(buffer, 0, bufsize); > + for (pr = bvec_test_ranges; pr->from >= 0; pr++) { > + size_t patt = pr->page * PAGE_SIZE; > + > + for (j = pr->from; j < pr->to; j++) { > + buffer[i++] = pattern(patt + j); > + if (i >= bufsize) > + goto stop; > + } > + } > +stop: > + > + /* Compare the images */ > + for (i = 0; i < bufsize; i++) { > + KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i); > + if (scratch[i] != buffer[i]) > + return; > + } > + > + KUNIT_SUCCEED(); > +} > + > +static void iov_kunit_destroy_xarray(void *data) > +{ > + struct xarray *xarray = data; > + > + xa_destroy(xarray); > + kfree(xarray); > +} > + > +static void __init iov_kunit_load_xarray(struct kunit *test, > + struct iov_iter *iter, int dir, > + struct xarray *xarray, > + struct page **pages, size_t npages) > +{ > + size_t size = 0; > + int i; > + > + for (i = 0; i < npages; i++) { > + void *x = xa_store(xarray, i, pages[i], GFP_KERNEL); > + > + KUNIT_ASSERT_FALSE(test, xa_is_err(x)); > + size += PAGE_SIZE; > + } > + iov_iter_xarray(iter, dir, xarray, 0, size); > +} > + > +static struct xarray *iov_kunit_create_xarray(struct kunit *test) > +{ > + struct xarray *xarray; > + > + xarray = kzalloc(sizeof(struct xarray), GFP_KERNEL); > + xa_init(xarray); > + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xarray); > + kunit_add_action_or_reset(test, iov_kunit_destroy_xarray, xarray); > + return xarray; > +} > + > +/* > + * Test copying to a ITER_XARRAY-type iterator. > + */ > +static void __init iov_kunit_copy_to_xarray(struct kunit *test) > +{ > + const struct kvec_test_range *pr; > + struct iov_iter iter; > + struct xarray *xarray; > + struct page **spages, **bpages; > + u8 *scratch, *buffer; > + size_t bufsize, npages, size, copied; > + int i, patt; > + > + bufsize = 0x100000; > + npages = bufsize / PAGE_SIZE; > + > + xarray = iov_kunit_create_xarray(test); > + > + scratch = iov_kunit_create_buffer(test, &spages, npages); > + for (i = 0; i < bufsize; i++) > + scratch[i] = pattern(i); > + > + buffer = iov_kunit_create_buffer(test, &bpages, npages); > + memset(buffer, 0, bufsize); > + > + iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages); > + > + i = 0; > + for (pr = kvec_test_ranges; pr->from >= 0; pr++) { > + size = pr->to - pr->from; > + KUNIT_ASSERT_LE(test, pr->to, bufsize); > + > + iov_iter_xarray(&iter, READ, xarray, pr->from, size); > + copied = copy_to_iter(scratch + i, size, &iter); > + > + KUNIT_EXPECT_EQ(test, copied, size); > + KUNIT_EXPECT_EQ(test, iter.count, 0); > + KUNIT_EXPECT_EQ(test, iter.iov_offset, size); > + i += size; > + } > + > + /* Build the expected image in the scratch buffer. */ > + patt = 0; > + memset(scratch, 0, bufsize); > + for (pr = kvec_test_ranges; pr->from >= 0; pr++) > + for (i = pr->from; i < pr->to; i++) > + scratch[i] = pattern(patt++); > + > + /* Compare the images */ > + for (i = 0; i < bufsize; i++) { > + KUNIT_EXPECT_EQ_MSG(test, buffer[i], scratch[i], "at i=%x", i); > + if (buffer[i] != scratch[i]) > + return; > + } > + > + KUNIT_SUCCEED(); > +} > + > +/* > + * Test copying from a ITER_XARRAY-type iterator. > + */ > +static void __init iov_kunit_copy_from_xarray(struct kunit *test) > +{ > + const struct kvec_test_range *pr; > + struct iov_iter iter; > + struct xarray *xarray; > + struct page **spages, **bpages; > + u8 *scratch, *buffer; > + size_t bufsize, npages, size, copied; > + int i, j; > + > + bufsize = 0x100000; > + npages = bufsize / PAGE_SIZE; > + > + xarray = iov_kunit_create_xarray(test); > + > + buffer = iov_kunit_create_buffer(test, &bpages, npages); > + for (i = 0; i < bufsize; i++) > + buffer[i] = pattern(i); > + > + scratch = iov_kunit_create_buffer(test, &spages, npages); > + memset(scratch, 0, bufsize); > + > + iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages); > + > + i = 0; > + for (pr = kvec_test_ranges; pr->from >= 0; pr++) { > + size = pr->to - pr->from; > + KUNIT_ASSERT_LE(test, pr->to, bufsize); > + > + iov_iter_xarray(&iter, WRITE, xarray, pr->from, size); > + copied = copy_from_iter(scratch + i, size, &iter); > + > + KUNIT_EXPECT_EQ(test, copied, size); > + KUNIT_EXPECT_EQ(test, iter.count, 0); > + KUNIT_EXPECT_EQ(test, iter.iov_offset, size); > + i += size; > + } > + > + /* Build the expected image in the main buffer. */ > + i = 0; > + memset(buffer, 0, bufsize); > + for (pr = kvec_test_ranges; pr->from >= 0; pr++) { > + for (j = pr->from; j < pr->to; j++) { > + buffer[i++] = pattern(j); > + if (i >= bufsize) > + goto stop; > + } > + } > +stop: > + > + /* Compare the images */ > + for (i = 0; i < bufsize; i++) { > + KUNIT_EXPECT_EQ_MSG(test, scratch[i], buffer[i], "at i=%x", i); > + if (scratch[i] != buffer[i]) > + return; > + } > + > + KUNIT_SUCCEED(); > +} > + > +static struct kunit_case __refdata iov_kunit_cases[] = { > + KUNIT_CASE(iov_kunit_copy_to_kvec), > + KUNIT_CASE(iov_kunit_copy_from_kvec), > + KUNIT_CASE(iov_kunit_copy_to_bvec), > + KUNIT_CASE(iov_kunit_copy_from_bvec), > + KUNIT_CASE(iov_kunit_copy_to_xarray), > + KUNIT_CASE(iov_kunit_copy_from_xarray), > + {} > +}; > + > +static struct kunit_suite iov_kunit_suite = { > + .name = "iov_iter", > + .test_cases = iov_kunit_cases, > +}; > + > +kunit_test_suites(&iov_kunit_suite); ---end quoted text---