tools/testing/selftests/mm/hugetlb_madv_vs_map.c

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

File Facts

System
Linux kernel
Corpus path
tools/testing/selftests/mm/hugetlb_madv_vs_map.c
Extension
.c
Size
2840 bytes
Lines
127
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 ((long)ptr != -1) {
			/* Touching the other page now will cause a SIGBUG
			 * huge_ptr[0] = '1';
			 */
			return ptr;
		}
	}

	return NULL;
}

int main(void)
{
	pthread_t thread1, thread2, thread3;
	unsigned long free_hugepages;
	void *ret;

	/*
	 * On kernel 6.7, we are able to reproduce the problem with ~10
	 * interactions
	 */
	int max = 10;

	free_hugepages = get_free_hugepages();

	if (free_hugepages != 1) {
		ksft_exit_skip("This test needs one and only one page to execute. Got %lu\n",
			       free_hugepages);
	}

	mmap_size = default_huge_page_size();

	while (max--) {
		huge_ptr = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE,
				MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
				-1, 0);

		if ((unsigned long)huge_ptr == -1) {
			ksft_test_result_fail("Failed to allocate huge page\n");
			return KSFT_FAIL;
		}

		pthread_create(&thread1, NULL, madv, NULL);
		pthread_create(&thread2, NULL, touch, NULL);
		pthread_create(&thread3, NULL, map_extra, NULL);

		pthread_join(thread1, NULL);
		pthread_join(thread2, NULL);
		pthread_join(thread3, &ret);

		if (ret) {
			ksft_test_result_fail("Unexpected huge page allocation\n");
			return KSFT_FAIL;
		}

		/* Unmap and restart */
		munmap(huge_ptr, mmap_size);
	}

	return KSFT_PASS;
}

Annotation

Implementation Notes