// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE

#include <linux/limits.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include "../kselftest.h"
#include "cgroup_util.h"

#define ADDR ((void *)(0x0UL))
#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
/* mapping 8 MBs == 4 hugepages */
#define LENGTH (8UL*1024*1024)
#define PROTECTION (PROT_READ | PROT_WRITE)

/* borrowed from mm/hmm-tests.c */
static long get_hugepage_size(void)
{
	int fd;
	char buf[2048];
	int len;
	char *p, *q, *path = "/proc/meminfo", *tag = "Hugepagesize:";
	long val;

	fd = open(path, O_RDONLY);
	if (fd < 0) {
		/* Error opening the file */
		return -1;
	}

	len = read(fd, buf, sizeof(buf));
	close(fd);
	if (len < 0) {
		/* Error in reading the file */
		return -1;
	}
	if (len == sizeof(buf)) {
		/* Error file is too large */
		return -1;
	}
	buf[len] = '\0';

	/* Search for a tag if provided */
	if (tag) {
		p = strstr(buf, tag);
		if (!p)
			return -1; /* looks like the line we want isn't there */
		p += strlen(tag);
	} else
		p = buf;

	val = strtol(p, &q, 0);
	if (*q != ' ') {
		/* Error parsing the file */
		return -1;
	}

	return val;
}

static int set_file(const char *path, long value)
{
	FILE *file;
	int ret;

	file = fopen(path, "w");
	if (!file)
		return -1;
	ret = fprintf(file, "%ld\n", value);
	fclose(file);
	return ret;
}

static int set_nr_hugepages(long value)
{
	return set_file("/proc/sys/vm/nr_hugepages", value);
}

static unsigned int check_first(char *addr)
{
	return *(unsigned int *)addr;
}

static void write_data(char *addr)
{
	unsigned long i;

	for (i = 0; i < LENGTH; i++)
		*(addr + i) = (char)i;
}

static int hugetlb_test_program(const char *cgroup, void *arg)
{
	char *test_group = (char *)arg;
	void *addr;
	long old_current, expected_current, current;
	int ret = EXIT_FAILURE;

	old_current = cg_read_long(test_group, "memory.current");
	set_nr_hugepages(20);
	current = cg_read_long(test_group, "memory.current");
	if (current - old_current >= MB(2)) {
		ksft_print_msg(
			"setting nr_hugepages should not increase hugepage usage.\n");
		ksft_print_msg("before: %ld, after: %ld\n", old_current, current);
		return EXIT_FAILURE;
	}

	addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
	if (addr == MAP_FAILED) {
		ksft_print_msg("fail to mmap.\n");
		return EXIT_FAILURE;
	}
	current = cg_read_long(test_group, "memory.current");
	if (current - old_current >= MB(2)) {
		ksft_print_msg("mmap should not increase hugepage usage.\n");
		ksft_print_msg("before: %ld, after: %ld\n", old_current, current);
		goto out_failed_munmap;
	}
	old_current = current;

	/* read the first page */
	check_first(addr);
	expected_current = old_current + MB(2);
	current = cg_read_long(test_group, "memory.current");
	if (!values_close(expected_current, current, 5)) {
		ksft_print_msg("memory usage should increase by around 2MB.\n");
		ksft_print_msg(
			"expected memory: %ld, actual memory: %ld\n",
			expected_current, current);
		goto out_failed_munmap;
	}

	/* write to the whole range */
	write_data(addr);
	current = cg_read_long(test_group, "memory.current");
	expected_current = old_current + MB(8);
	if (!values_close(expected_current, current, 5)) {
		ksft_print_msg("memory usage should increase by around 8MB.\n");
		ksft_print_msg(
			"expected memory: %ld, actual memory: %ld\n",
			expected_current, current);
		goto out_failed_munmap;
	}

	/* unmap the whole range */
	munmap(addr, LENGTH);
	current = cg_read_long(test_group, "memory.current");
	expected_current = old_current;
	if (!values_close(expected_current, current, 5)) {
		ksft_print_msg("memory usage should go back down.\n");
		ksft_print_msg(
			"expected memory: %ld, actual memory: %ld\n",
			expected_current, current);
		return ret;
	}

	ret = EXIT_SUCCESS;
	return ret;

out_failed_munmap:
	munmap(addr, LENGTH);
	return ret;
}

static int test_hugetlb_memcg(char *root)
{
	int ret = KSFT_FAIL;
	char *test_group;

	test_group = cg_name(root, "hugetlb_memcg_test");
	if (!test_group || cg_create(test_group)) {
		ksft_print_msg("fail to create cgroup.\n");
		goto out;
	}

	if (cg_write(test_group, "memory.max", "100M")) {
		ksft_print_msg("fail to set cgroup memory limit.\n");
		goto out;
	}

	/* disable swap */
	if (cg_write(test_group, "memory.swap.max", "0")) {
		ksft_print_msg("fail to disable swap.\n");
		goto out;
	}

	if (!cg_run(test_group, hugetlb_test_program, (void *)test_group))
		ret = KSFT_PASS;
out:
	cg_destroy(test_group);
	free(test_group);
	return ret;
}

int main(int argc, char **argv)
{
	char root[PATH_MAX];
	int ret = EXIT_SUCCESS, has_memory_hugetlb_acc;

	has_memory_hugetlb_acc = proc_mount_contains("memory_hugetlb_accounting");
	if (has_memory_hugetlb_acc < 0)
		ksft_exit_skip("Failed to query cgroup mount option\n");
	else if (!has_memory_hugetlb_acc)
		ksft_exit_skip("memory hugetlb accounting is disabled\n");

	/* Unit is kB! */
	if (get_hugepage_size() != 2048) {
		ksft_print_msg("test_hugetlb_memcg requires 2MB hugepages\n");
		ksft_test_result_skip("test_hugetlb_memcg\n");
		return ret;
	}

	if (cg_find_unified_root(root, sizeof(root)))
		ksft_exit_skip("cgroup v2 isn't mounted\n");

	switch (test_hugetlb_memcg(root)) {
	case KSFT_PASS:
		ksft_test_result_pass("test_hugetlb_memcg\n");
		break;
	case KSFT_SKIP:
		ksft_test_result_skip("test_hugetlb_memcg\n");
		break;
	default:
		ret = EXIT_FAILURE;
		ksft_test_result_fail("test_hugetlb_memcg\n");
		break;
	}

	return ret;
}
