Welcome! Share code as fast as possible.

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdbool.h>
#include <sys/mman.h>

void write_to_file(const char *path, bool mthp_enabled) {
	int fd = open(path, O_WRONLY);
	if (fd < 0) {
		perror("Failed to open file");
		return;
	}

	if (mthp_enabled) {
		if (write(fd, "always", 6) != 6) {
			perror("Failed to write to file");
		}
	} else {
		if (write(fd, "never", 5) != 5) {
			perror("Failed to write to file");
		}
	}

	close(fd);
}

void find_and_modify(const char *base_path, bool mthp_enabled) {
	struct dirent *entry;
	DIR *dp = opendir(base_path);

	if (dp == NULL) {
		perror("Unable to open directory");
		return;
	}

	char path[1024];
	while ((entry = readdir(dp))) {
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
			continue;
		if (strcmp(entry->d_name, "hugepages-2048kB") == 0 && mthp_enabled == 1)
			continue;

		snprintf(path, sizeof(path), "%s/%s", base_path, entry->d_name);

		if (entry->d_type == DT_DIR) {
			find_and_modify(path, mthp_enabled);
		} else if (strcmp(entry->d_name, "enabled") == 0) {
			write_to_file(path, mthp_enabled);
		}
	}

	closedir(dp);
}

int main()
{
	const char *base_path = "/sys/kernel/mm/transparent_hugepage";
	unsigned long addr_hint = (10UL << 30);
	unsigned long pagesize = 4UL << 10;
	unsigned long border = 32UL << 10;
	size_t size = 1UL << 30;

	for (int j = 0; j < 1; ++j) {

		/* echo "never" into top level and subdirectories */
		find_and_modify(base_path, 0);
		char *ptr = mmap((void *)addr_hint, size, PROT_READ | PROT_WRITE,
				 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0);
		if (ptr == MAP_FAILED) {
			perror("mmap");
			return 1;
		}

		/* Make only 16K mTHP succeed */
		for (unsigned long i = 1; (i * border) < size; ++i) {
			ptr[i * border - 1] = 3;
		}

		if (madvise(ptr, size, MADV_HUGEPAGE)) {
			perror("madvise");
			return 1;
		}
		/*
		 * echo "always" into top level and subdirectories, except 
		 * hugepages-2048kB
		 */
		find_and_modify(base_path, 1);

		/* kernel will try to find contiguous PTEs */
		for (unsigned long i = 0; i * pagesize < size; ++i)
			ptr[i * pagesize] = 7;

		munmap(ptr, size);
	}

	return 0;
}