> +/* 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---