Skip to content

Commit a3c57ab

Browse files
dhowellstorvalds
authored andcommitted
iov_iter: Kunit tests for page extraction
Add some kunit tests for page extraction for ITER_BVEC, ITER_KVEC and ITER_XARRAY type iterators. ITER_UBUF and ITER_IOVEC aren't dealt with as they require userspace VM interaction. ITER_DISCARD isn't dealt with either as that can't be extracted. Signed-off-by: David Howells <[email protected]> Cc: Christoph Hellwig <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Jens Axboe <[email protected]> Cc: Al Viro <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: John Hubbard <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2d71340 commit a3c57ab

File tree

1 file changed

+240
-0
lines changed

1 file changed

+240
-0
lines changed

lib/kunit_iov_iter.c

Lines changed: 240 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,13 +519,253 @@ static void __init iov_kunit_copy_from_xarray(struct kunit *test)
519519
KUNIT_SUCCEED();
520520
}
521521

522+
/*
523+
* Test the extraction of ITER_KVEC-type iterators.
524+
*/
525+
static void __init iov_kunit_extract_pages_kvec(struct kunit *test)
526+
{
527+
const struct kvec_test_range *pr;
528+
struct iov_iter iter;
529+
struct page **bpages, *pagelist[8], **pages = pagelist;
530+
struct kvec kvec[8];
531+
u8 *buffer;
532+
ssize_t len;
533+
size_t bufsize, size = 0, npages;
534+
int i, from;
535+
536+
bufsize = 0x100000;
537+
npages = bufsize / PAGE_SIZE;
538+
539+
buffer = iov_kunit_create_buffer(test, &bpages, npages);
540+
541+
iov_kunit_load_kvec(test, &iter, READ, kvec, ARRAY_SIZE(kvec),
542+
buffer, bufsize, kvec_test_ranges);
543+
size = iter.count;
544+
545+
pr = kvec_test_ranges;
546+
from = pr->from;
547+
do {
548+
size_t offset0 = LONG_MAX;
549+
550+
for (i = 0; i < ARRAY_SIZE(pagelist); i++)
551+
pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
552+
553+
len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
554+
ARRAY_SIZE(pagelist), 0, &offset0);
555+
KUNIT_EXPECT_GE(test, len, 0);
556+
if (len < 0)
557+
break;
558+
KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
559+
KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
560+
KUNIT_EXPECT_LE(test, len, size);
561+
KUNIT_EXPECT_EQ(test, iter.count, size - len);
562+
size -= len;
563+
564+
if (len == 0)
565+
break;
566+
567+
for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
568+
struct page *p;
569+
ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
570+
int ix;
571+
572+
KUNIT_ASSERT_GE(test, part, 0);
573+
while (from == pr->to) {
574+
pr++;
575+
from = pr->from;
576+
if (from < 0)
577+
goto stop;
578+
}
579+
ix = from / PAGE_SIZE;
580+
KUNIT_ASSERT_LT(test, ix, npages);
581+
p = bpages[ix];
582+
KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
583+
KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
584+
from += part;
585+
len -= part;
586+
KUNIT_ASSERT_GE(test, len, 0);
587+
if (len == 0)
588+
break;
589+
offset0 = 0;
590+
}
591+
592+
if (test->status == KUNIT_FAILURE)
593+
break;
594+
} while (iov_iter_count(&iter) > 0);
595+
596+
stop:
597+
KUNIT_EXPECT_EQ(test, size, 0);
598+
KUNIT_EXPECT_EQ(test, iter.count, 0);
599+
KUNIT_SUCCEED();
600+
}
601+
602+
/*
603+
* Test the extraction of ITER_BVEC-type iterators.
604+
*/
605+
static void __init iov_kunit_extract_pages_bvec(struct kunit *test)
606+
{
607+
const struct bvec_test_range *pr;
608+
struct iov_iter iter;
609+
struct page **bpages, *pagelist[8], **pages = pagelist;
610+
struct bio_vec bvec[8];
611+
ssize_t len;
612+
size_t bufsize, size = 0, npages;
613+
int i, from;
614+
615+
bufsize = 0x100000;
616+
npages = bufsize / PAGE_SIZE;
617+
618+
iov_kunit_create_buffer(test, &bpages, npages);
619+
iov_kunit_load_bvec(test, &iter, READ, bvec, ARRAY_SIZE(bvec),
620+
bpages, npages, bufsize, bvec_test_ranges);
621+
size = iter.count;
622+
623+
pr = bvec_test_ranges;
624+
from = pr->from;
625+
do {
626+
size_t offset0 = LONG_MAX;
627+
628+
for (i = 0; i < ARRAY_SIZE(pagelist); i++)
629+
pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
630+
631+
len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
632+
ARRAY_SIZE(pagelist), 0, &offset0);
633+
KUNIT_EXPECT_GE(test, len, 0);
634+
if (len < 0)
635+
break;
636+
KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
637+
KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
638+
KUNIT_EXPECT_LE(test, len, size);
639+
KUNIT_EXPECT_EQ(test, iter.count, size - len);
640+
size -= len;
641+
642+
if (len == 0)
643+
break;
644+
645+
for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
646+
struct page *p;
647+
ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
648+
int ix;
649+
650+
KUNIT_ASSERT_GE(test, part, 0);
651+
while (from == pr->to) {
652+
pr++;
653+
from = pr->from;
654+
if (from < 0)
655+
goto stop;
656+
}
657+
ix = pr->page + from / PAGE_SIZE;
658+
KUNIT_ASSERT_LT(test, ix, npages);
659+
p = bpages[ix];
660+
KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
661+
KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
662+
from += part;
663+
len -= part;
664+
KUNIT_ASSERT_GE(test, len, 0);
665+
if (len == 0)
666+
break;
667+
offset0 = 0;
668+
}
669+
670+
if (test->status == KUNIT_FAILURE)
671+
break;
672+
} while (iov_iter_count(&iter) > 0);
673+
674+
stop:
675+
KUNIT_EXPECT_EQ(test, size, 0);
676+
KUNIT_EXPECT_EQ(test, iter.count, 0);
677+
KUNIT_SUCCEED();
678+
}
679+
680+
/*
681+
* Test the extraction of ITER_XARRAY-type iterators.
682+
*/
683+
static void __init iov_kunit_extract_pages_xarray(struct kunit *test)
684+
{
685+
const struct kvec_test_range *pr;
686+
struct iov_iter iter;
687+
struct xarray *xarray;
688+
struct page **bpages, *pagelist[8], **pages = pagelist;
689+
ssize_t len;
690+
size_t bufsize, size = 0, npages;
691+
int i, from;
692+
693+
bufsize = 0x100000;
694+
npages = bufsize / PAGE_SIZE;
695+
696+
xarray = iov_kunit_create_xarray(test);
697+
698+
iov_kunit_create_buffer(test, &bpages, npages);
699+
iov_kunit_load_xarray(test, &iter, READ, xarray, bpages, npages);
700+
701+
for (pr = kvec_test_ranges; pr->from >= 0; pr++) {
702+
from = pr->from;
703+
size = pr->to - from;
704+
KUNIT_ASSERT_LE(test, pr->to, bufsize);
705+
706+
iov_iter_xarray(&iter, WRITE, xarray, from, size);
707+
708+
do {
709+
size_t offset0 = LONG_MAX;
710+
711+
for (i = 0; i < ARRAY_SIZE(pagelist); i++)
712+
pagelist[i] = (void *)(unsigned long)0xaa55aa55aa55aa55ULL;
713+
714+
len = iov_iter_extract_pages(&iter, &pages, 100 * 1024,
715+
ARRAY_SIZE(pagelist), 0, &offset0);
716+
KUNIT_EXPECT_GE(test, len, 0);
717+
if (len < 0)
718+
break;
719+
KUNIT_EXPECT_LE(test, len, size);
720+
KUNIT_EXPECT_EQ(test, iter.count, size - len);
721+
if (len == 0)
722+
break;
723+
size -= len;
724+
KUNIT_EXPECT_GE(test, (ssize_t)offset0, 0);
725+
KUNIT_EXPECT_LT(test, offset0, PAGE_SIZE);
726+
727+
for (i = 0; i < ARRAY_SIZE(pagelist); i++) {
728+
struct page *p;
729+
ssize_t part = min_t(ssize_t, len, PAGE_SIZE - offset0);
730+
int ix;
731+
732+
KUNIT_ASSERT_GE(test, part, 0);
733+
ix = from / PAGE_SIZE;
734+
KUNIT_ASSERT_LT(test, ix, npages);
735+
p = bpages[ix];
736+
KUNIT_EXPECT_PTR_EQ(test, pagelist[i], p);
737+
KUNIT_EXPECT_EQ(test, offset0, from % PAGE_SIZE);
738+
from += part;
739+
len -= part;
740+
KUNIT_ASSERT_GE(test, len, 0);
741+
if (len == 0)
742+
break;
743+
offset0 = 0;
744+
}
745+
746+
if (test->status == KUNIT_FAILURE)
747+
goto stop;
748+
} while (iov_iter_count(&iter) > 0);
749+
750+
KUNIT_EXPECT_EQ(test, size, 0);
751+
KUNIT_EXPECT_EQ(test, iter.count, 0);
752+
KUNIT_EXPECT_EQ(test, iter.iov_offset, pr->to - pr->from);
753+
}
754+
755+
stop:
756+
KUNIT_SUCCEED();
757+
}
758+
522759
static struct kunit_case __refdata iov_kunit_cases[] = {
523760
KUNIT_CASE(iov_kunit_copy_to_kvec),
524761
KUNIT_CASE(iov_kunit_copy_from_kvec),
525762
KUNIT_CASE(iov_kunit_copy_to_bvec),
526763
KUNIT_CASE(iov_kunit_copy_from_bvec),
527764
KUNIT_CASE(iov_kunit_copy_to_xarray),
528765
KUNIT_CASE(iov_kunit_copy_from_xarray),
766+
KUNIT_CASE(iov_kunit_extract_pages_kvec),
767+
KUNIT_CASE(iov_kunit_extract_pages_bvec),
768+
KUNIT_CASE(iov_kunit_extract_pages_xarray),
529769
{}
530770
};
531771

0 commit comments

Comments
 (0)