/*
 * Copyright (C) 2010  Red Hat, Inc.
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of version 2 of the GNU General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it would be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * Further, this software is distributed without any warranty that it
 * is free of the rightful claim of any third person regarding
 * infringement or the like.  Any license provided herein, whether
 * implied or otherwise, applies only to this software file.  Patent
 * licenses, if any, provided herein do not apply to combinations of
 * this program with other software, or any other product whatsoever.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

/*
 * mmap/munmap /dev/zero: a common way of malloc()/free() anonymous
 * memory on Solaris.
 *
 * The basic purpose of this is a to test if it is possible to map and
 * unmap /dev/zero, and to read and write the mapping. Being inspired
 * by two bugs in the past, the design of the test was added some
 * variations based on the reproducers for them. It also accept an
 * option to mmap/munmap anonymous pages.
 *
 * One is to trigger panic with transparent hugepage feature that
 * split_huge_page is very strict in checking the rmap walk was
 * perfect. Keep it strict because if page_mapcount isn't stable and
 * just right, the __split_huge_page_refcount that follows the rmap
 * walk could lead to erratic page_count()s for the subpages. The bug
 * in fork lead to the rmap walk finding the parent huge-pmd twice
 * instead of just one, because the anon_vma_chain objects of the
 * child vma still point to the vma->vm_mm of the parent. That trips
 * on the split_huge_page mapcount vs page_mapcount check leading to a
 * BUG_ON.
 *
 * The other bug is mmap() of /dev/zero results in calling map_zero()
 * which on RHEL5 maps the ZERO_PAGE in every PTE within that virtual
 * address range. Since the application which maps a region from 5M to
 * 16M in size is also multi-threaded the subsequent munmap() of
 * /dev/zero results is TLB shootdowns to all other CPUs. When this
 * happens thousands or millions of times the application performance
 * is terrible. The mapping ZERO_PAGE in every pte within that virtual
 * address range was an optimization to make the subsequent pagefault
 * times faster on RHEL5 that has been removed/changed upstream.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include "test.h"
#include "config.h"

#define SIZE (5*1024*1024)
#define PATH_KSM "/sys/kernel/mm/ksm/"

char *TCID = "mmap10";
int TST_TOTAL = 1;

static int fd, opt_anon, opt_ksm;
static long ps;
static char *x;

void setup(void);
void cleanup(void);
void mmapzero(void);
void help(void);

static option_t options[] = {
	{"a", &opt_anon, NULL},
	{"s", &opt_ksm, NULL},
	{NULL, NULL, NULL}
};

int main(int argc, char *argv[])
{
	int lc;
	const char *msg;

	msg = parse_opts(argc, argv, options, help);
	if (msg != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	if (opt_ksm) {
		if (access(PATH_KSM, F_OK) == -1)
			tst_brkm(TCONF, NULL,
				 "KSM configuration is not enabled");
#ifdef HAVE_MADV_MERGEABLE
		tst_resm(TINFO, "add to KSM regions.");
#else
		tst_brkm(TCONF, NULL, "MADV_MERGEABLE missing in sys/mman.h");
#endif
	}
	if (opt_anon)
		tst_resm(TINFO, "use anonymous pages.");
	else
		tst_resm(TINFO, "use /dev/zero.");

	setup();

	tst_resm(TINFO, "start tests.");
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		mmapzero();
	}

	cleanup();
	tst_exit();
}

void mmapzero(void)
{
	int n;

	if (opt_anon) {
		x = mmap(NULL, SIZE + SIZE - ps, PROT_READ | PROT_WRITE,
			 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	} else {
		if ((fd = open("/dev/zero", O_RDWR, 0666)) < 0)
			tst_brkm(TBROK | TERRNO, cleanup, "open");
		x = mmap(NULL, SIZE + SIZE - ps, PROT_READ | PROT_WRITE,
			 MAP_PRIVATE, fd, 0);
	}
	if (x == MAP_FAILED)
		tst_brkm(TFAIL | TERRNO, cleanup, "mmap");
#ifdef HAVE_MADV_MERGEABLE
	if (opt_ksm) {
		if (madvise(x, SIZE + SIZE - ps, MADV_MERGEABLE) == -1)
			tst_brkm(TBROK | TERRNO, cleanup, "madvise");
	}
#endif
	x[SIZE] = 0;

	switch (n = fork()) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork");
	case 0:
		if (munmap(x + SIZE + ps, SIZE - ps - ps) == -1)
			tst_brkm(TFAIL | TERRNO, cleanup, "munmap");
		exit(0);
	default:
		break;
	}

	switch (n = fork()) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork");
	case 0:
		if (munmap(x + SIZE + ps, SIZE - ps - ps) == -1)
			tst_brkm(TFAIL | TERRNO, cleanup,
				 "subsequent munmap #1");
		exit(0);
	default:
		switch (n = fork()) {
		case -1:
			tst_brkm(TBROK | TERRNO, cleanup, "fork");
		case 0:
			if (munmap(x + SIZE + ps, SIZE - ps - ps) == -1)
				tst_brkm(TFAIL | TERRNO, cleanup,
					 "subsequent munmap #2");
			exit(0);
		default:
			break;
		}
		break;
	}

	if (munmap(x, SIZE + SIZE - ps) == -1)
		tst_resm(TFAIL | TERRNO, "munmap all");

	while (waitpid(-1, &n, WUNTRACED | WCONTINUED) > 0)
		if (WEXITSTATUS(n) != 0)
			tst_resm(TFAIL, "child exit status is %d",
				 WEXITSTATUS(n));
}

void cleanup(void)
{
}

void setup(void)
{
	tst_require_root(NULL);

	tst_sig(FORK, DEF_HANDLER, cleanup);
	TEST_PAUSE;

	if ((ps = sysconf(_SC_PAGESIZE)) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "sysconf(_SC_PAGESIZE)");
}

void help(void)
{
	printf("  -a      Test anonymous pages\n");
	printf("  -s      Add to KSM regions\n");
}
