lib/tests/kunit_iov_iter.c

Source file repositories/reference/linux-study-clean/lib/tests/kunit_iov_iter.c

File Facts

System
Linux kernel
Corpus path
lib/tests/kunit_iov_iter.c
Extension
.c
Size
31480 bytes
Lines
1252
Domain
Kernel Services
Bucket
lib
Inferred role
Kernel Services: implementation source
Status
source implementation candidate

Why This File Exists

Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.

Dependency Surface

Detected Declarations

Annotated Snippet

struct kvec_test_range {
	int	from, to;
};

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 },
	{ -1 }
};

static inline u8 pattern(unsigned long x)
{
	return (u8)x + (u8)(x >> 8) + (u8)(x >> 16);
}

static void iov_kunit_unmap(void *data)
{
	vfree(data);
}

static void *__init iov_kunit_create_buffer(struct kunit *test,
					    struct page ***ppages,
					    size_t npages)
{
	struct page **pages;
	unsigned long got, last;
	void *buffer;
	unsigned int i;

	pages = kzalloc_objs(struct page *, npages, GFP_KERNEL);
	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pages);
	*ppages = pages;

	got = 0;
	while (true) {
		last = got;
		got = alloc_pages_bulk(GFP_KERNEL, npages, pages);

		if (last == got || got == npages)
			break;
	}

	if (got != npages) {
		release_pages(pages, got);
		kvfree(pages);
		KUNIT_ASSERT_EQ(test, got, npages);
	}
	/* Make sure that we don't get a physically contiguous buffer. */
	for (i = 0; i < npages / 4; ++i)
		swap(pages[i], pages[i + npages / 2]);

	buffer = vmap(pages, npages, VM_MAP | VM_MAP_PUT_PAGES, PAGE_KERNEL);
	if (buffer == NULL) {
		release_pages(pages, got);
		kvfree(pages);
	}
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, buffer);

	kunit_add_action_or_reset(test, iov_kunit_unmap, buffer);
	return buffer;
}

static void __init iov_kunit_load_kvec(struct kunit *test,
				       struct iov_iter *iter, int dir,
				       struct kvec *kvec, unsigned int kvmax,
				       void *buffer, size_t bufsize,
				       const struct kvec_test_range *pr)
{
	size_t size = 0;
	int i;

	for (i = 0; i < kvmax; i++, pr++) {
		if (pr->from < 0)
			break;
		KUNIT_ASSERT_GE(test, pr->to, pr->from);
		KUNIT_ASSERT_LE(test, pr->to, bufsize);
		kvec[i].iov_base = buffer + pr->from;
		kvec[i].iov_len = pr->to - pr->from;
		size += pr->to - pr->from;
	}
	KUNIT_ASSERT_LE(test, size, bufsize);

	iov_iter_kvec(iter, dir, kvec, i, size);
}

Annotation

Implementation Notes