tools/testing/selftests/mm/thuge-gen.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/mm/thuge-gen.c
Extension
.c
Size
6069 bytes
Lines
235
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 (errno == EPERM) {
			ksft_test_result_skip("shmget requires root privileges: %s\n",
					      strerror(errno));
			return;
		}
		ksft_exit_fail_msg("shmget: %s\n", strerror(errno));
	}

	if (shmctl(id, SHM_INFO, (void *)&i) < 0)
		ksft_exit_fail_msg("shmctl: %s\n", strerror(errno));

	map = shmat(id, NULL, 0600);
	if (map == MAP_FAILED)
		ksft_exit_fail_msg("shmat: %s\n", strerror(errno));

	shmctl(id, IPC_RMID, NULL);

	memset(map, 0xff, size*NUM_PAGES);
	after = read_free(size);

	show(size);
	ksft_test_result(size == getpagesize() || (before - after) == NUM_PAGES,
			 "%s: mmap %lu %x\n", __func__, size, flags);
	if (shmdt(map))
		ksft_exit_fail_msg("%s: shmdt: %s\n", __func__, strerror(errno));
}

void find_pagesizes(void)
{
	unsigned long largest = getpagesize();
	unsigned long shmmax_val = 0;
	int i;
	glob_t g;

	glob("/sys/kernel/mm/hugepages/hugepages-*kB", 0, NULL, &g);
	assert(g.gl_pathc <= NUM_PAGESIZES);
	for (i = 0; (i < g.gl_pathc) && (num_page_sizes < NUM_PAGESIZES); i++) {
		sscanf(g.gl_pathv[i], "/sys/kernel/mm/hugepages/hugepages-%lukB",
				&page_sizes[num_page_sizes]);
		page_sizes[num_page_sizes] <<= 10;
		ksft_print_msg("Found %luMB\n", page_sizes[i] >> 20);

		if (page_sizes[num_page_sizes] > largest)
			largest = page_sizes[i];

		if (read_free(page_sizes[num_page_sizes]) >= NUM_PAGES)
			num_page_sizes++;
		else
			ksft_print_msg("SKIP for size %lu MB as not enough huge pages, need %u\n",
				       page_sizes[num_page_sizes] >> 20, NUM_PAGES);
	}
	globfree(&g);

	read_sysfs("/proc/sys/kernel/shmmax", &shmmax_val);
	if (shmmax_val < NUM_PAGES * largest) {
		ksft_print_msg("WARNING: shmmax is too small to run this test.\n");
		ksft_print_msg("Please run the following command to increase shmmax:\n");
		ksft_print_msg("echo %lu > /proc/sys/kernel/shmmax\n", largest * NUM_PAGES);
		ksft_exit_skip("Test skipped due to insufficient shmmax value.\n");
	}

#if defined(__x86_64__)
	if (largest != 1U<<30) {
		ksft_exit_skip("No GB pages available on x86-64\n"
				   "Please boot with hugepagesz=1G hugepages=%d\n", NUM_PAGES);
	}
#endif
}

int main(void)
{
	unsigned default_hps = default_huge_page_size();
	int i;

	ksft_print_header();

	find_pagesizes();

	if (!num_page_sizes)
		ksft_finished();

	ksft_set_plan(2 * num_page_sizes + 3);

	for (i = 0; i < num_page_sizes; i++) {
		unsigned long ps = page_sizes[i];
		int arg = ilog2(ps) << MAP_HUGE_SHIFT;

		ksft_print_msg("Testing %luMB mmap with shift %x\n", ps >> 20, arg);
		test_mmap(ps, MAP_HUGETLB | arg);
	}

Annotation

Implementation Notes