tools/testing/selftests/mm/split_huge_page_test.c

Source file repositories/reference/linux-study-clean/tools/testing/selftests/mm/split_huge_page_test.c

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/mm/split_huge_page_test.c
Extension
.c
Size
21441 bytes
Lines
827
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

if (status == 1) {
			vaddr += psize();
			continue;
		}

		/* all order-0 pages with possible false postive (non folio) */
		if (!(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
			orders[0]++;
			vaddr += psize();
			continue;
		}

		/* skip non thp compound pages */
		if (!(page_flags & KPF_THP)) {
			vaddr += psize();
			continue;
		}

		/* vpn points to part of a THP at this point */
		if (page_flags & KPF_COMPOUND_HEAD)
			cur_order = 1;
		else {
			vaddr += psize();
			continue;
		}

		next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));

		if (next_folio_vaddr >= vaddr_start + len)
			break;

		while ((status = vaddr_pageflags_get(next_folio_vaddr,
						     pagemap_fd, kpageflags_fd,
						     &page_flags)) >= 0) {
			/*
			 * non present vaddr, next compound head page, or
			 * order-0 page
			 */
			if (status == 1 ||
			    (page_flags & KPF_COMPOUND_HEAD) ||
			    !(page_flags & (KPF_COMPOUND_HEAD | KPF_COMPOUND_TAIL))) {
				if (cur_order < nr_orders) {
					orders[cur_order]++;
					cur_order = -1;
					vaddr = next_folio_vaddr;
				}
				break;
			}

			cur_order++;
			next_folio_vaddr = vaddr + (1UL << (cur_order + pshift()));
		}

		if (status < 0)
			return status;
	}
	if (cur_order > 0 && cur_order < nr_orders)
		orders[cur_order]++;
	return 0;
}

static int check_after_split_folio_orders(char *vaddr_start, size_t len,
		int pagemap_fd, int kpageflags_fd, int orders[], int nr_orders)
{
	int *vaddr_orders;
	int status;
	int i;

	vaddr_orders = (int *)malloc(sizeof(int) * nr_orders);

	if (!vaddr_orders)
		ksft_exit_fail_msg("Cannot allocate memory for vaddr_orders");

	memset(vaddr_orders, 0, sizeof(int) * nr_orders);
	status = gather_after_split_folio_orders(vaddr_start, len, pagemap_fd,
				     kpageflags_fd, vaddr_orders, nr_orders);
	if (status)
		ksft_exit_fail_msg("gather folio info failed\n");

	for (i = 0; i < nr_orders; i++)
		if (vaddr_orders[i] != orders[i]) {
			ksft_print_msg("order %d: expected: %d got %d\n", i,
				       orders[i], vaddr_orders[i]);
			status = -1;
		}

	free(vaddr_orders);
	return status;
}

Annotation

Implementation Notes