// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2023 Red Hat, Inc. * * Author: Gavin Shan * * Attempt to reproduce the xfs issue that Zhenyu observed. * The idea is to mimic QEMU's behavior to have private * mmap'ed VMA on xfs file (/tmp/test_data). The program * should be put into cgroup where the memory limit is set, * so that memory claim is enforced. */ #include #include #include #include #include #include #include #include #define TEST_FILENAME "/tmp/test_data" #define TEST_MEM_SIZE 0x40000000 static void hold(int argc, const char *desc) { int opt; if (argc <= 1) return; fprintf(stdout, "%s\n", desc); scanf("%c", &opt); } int main(int argc, char **argv) { int fd = 0; void *buf = (void *)-1, *p; int pgsize = getpagesize(); int ret; fd = open(TEST_FILENAME, O_RDWR); if (fd < 0) { fprintf(stderr, "Unable to open <%s>\n", TEST_FILENAME); return -EIO; } hold(argc, "Press any key to mmap...\n"); buf = mmap(NULL, TEST_MEM_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (buf == (void *)-1) { fprintf(stderr, "Unable to mmap <%s>\n", TEST_FILENAME); goto cleanup; } fprintf(stdout, "mmap'ed at 0x%p\n", buf); ret = madvise(buf, TEST_MEM_SIZE, MADV_HUGEPAGE); if (ret) { fprintf(stderr, "Unable to madvise(MADV_HUGEPAGE)\n"); goto cleanup; } hold(argc, "Press any key to populate..."); fprintf(stdout, "Populate area at 0x%lx, size=0x%x\n", (unsigned long)buf, TEST_MEM_SIZE); ret = madvise(buf, TEST_MEM_SIZE, MADV_POPULATE_WRITE); if (ret) { fprintf(stderr, "Unable to madvise(MADV_POPULATE_WRITE)\n"); goto cleanup; } cleanup: hold(argc, "Press any key to munmap..."); if (buf != (void *)-1) munmap(buf, TEST_MEM_SIZE); hold(argc, "Press any key to close..."); if (fd > 0) close(fd); hold(argc, "Press any key to exit..."); return 0; }