* [LTP] [PATCH v3 1/8] Refactor mmap03 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:58 ` Petr Vorel
2025-03-13 9:15 ` [LTP] [PATCH v3 2/8] Refactor mmap10 test Andrea Cervesato
` (7 subsequent siblings)
8 siblings, 1 reply; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap03.c | 263 +++++++++-----------------------
1 file changed, 69 insertions(+), 194 deletions(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap03.c b/testcases/kernel/syscalls/mmap/mmap03.c
index 9d94d2653661387d22f811cd959a87b8112c1167..45fb50fbf5cfceea1043b1cd736cb87aaf3aab4b 100644
--- a/testcases/kernel/syscalls/mmap/mmap03.c
+++ b/testcases/kernel/syscalls/mmap/mmap03.c
@@ -1,230 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) International Business Machines Corp., 2001
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
- * the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * 07/2001 Ported by Wayne Boyer
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Test Description:
- * Call mmap() to map a file creating a mapped region with execute access
- * under the following conditions -
- * - The prot parameter is set to PROT_EXE
- * - The file descriptor is open for read
- * - The file being mapped has execute permission bit set.
- * - The minimum file permissions should be 0555.
+/*\
+ * Map a file with mmap() syscall, creating a mapped region with execute access
+ * under the following conditions:
*
- * The call should succeed to map the file creating mapped memory with the
- * required attributes.
+ * - file descriptor is open for read
+ * - minimum file permissions should be 0555
+ * - file being mapped has PROT_EXEC execute permission bit set
*
- * Expected Result:
- * mmap() should succeed returning the address of the mapped region,
- * and the mapped region should contain the contents of the mapped file.
- * but with ia64 and PARISC/hppa,
- * an attempt to access the contents of the mapped region should give
- * rise to the signal SIGSEGV.
+ * mmap() should succeed returning the address of the mapped region
+ * and the mapped region should contain the contents of the mapped file.
*
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
+ * With ia64 and PARISC/hppa, an attempt to access the contents of the
+ * mapped region should rise signal SIGSEGV.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <setjmp.h>
-
-#include "test.h"
-#define TEMPFILE "mmapfile"
+#include "tst_test.h"
-char *TCID = "mmap03";
-int TST_TOTAL = 1;
+#define TEMPFILE "mmapfile"
+static void *addr;
+static char *tmpdata;
static size_t page_sz;
-static char *addr;
-static char *dummy;
-static int fildes;
-static volatile int pass = 0;
-static sigjmp_buf env;
+static int fdesc = -1;
-static void setup(void);
-static void cleanup(void);
-static void sig_handler(int sig);
-
-int main(int ac, char **av)
+static void run_child(void)
{
- int lc;
-
- tst_parse_opts(ac, av, NULL, NULL);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
- /*
- * Call mmap to map the temporary file 'TEMPFILE'
- * with execute access.
- */
- errno = 0;
- addr = mmap(0, page_sz, PROT_EXEC,
- MAP_FILE | MAP_SHARED, fildes, 0);
-
- /* Check for the return value of mmap() */
- if (addr == MAP_FAILED) {
- tst_resm(TFAIL | TERRNO, "mmap() failed on %s",
- TEMPFILE);
- continue;
- }
-
- /*
- * Read the file contents into the dummy
- * variable.
- */
- if (read(fildes, dummy, page_sz) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup,
- "reading %s failed", TEMPFILE);
- }
-
- /*
- * Check whether the mapped memory region
- * has the file contents.
- *
- * with ia64 and PARISC/hppa, this should
- * generate a SIGSEGV which will be caught below.
- *
- */
-
- if (sigsetjmp(env, 1) == 0) {
- if (memcmp(dummy, addr, page_sz)) {
- tst_resm(TFAIL,
- "mapped memory region "
- "contains invalid data");
- } else {
- tst_resm(TPASS,
- "mmap() functionality is "
- "correct");
- }
- }
-#if defined(__ia64__) || defined(__hppa__) || defined(__mips__)
- if (pass) {
- tst_resm(TPASS, "Got SIGSEGV as expected");
- } else {
- tst_resm(TFAIL, "Mapped memory region with NO "
- "access is accessible");
- }
-#endif
-
- /* Clean up things in case we are looping */
- /* Unmap the mapped memory */
- if (munmap(addr, page_sz) != 0) {
- tst_brkm(TFAIL | TERRNO, cleanup,
- "failed to unmap the mmapped pages");
- }
- pass = 0;
+ char *data;
- }
+ tst_res(TINFO, "Map temporary file in memory with PROT_EXEC");
- cleanup();
- tst_exit();
-}
+ addr = SAFE_MMAP(0, page_sz, PROT_EXEC,
+ MAP_FILE | MAP_SHARED, fdesc, 0);
-static void setup(void)
-{
- char *tst_buff;
+ data = SAFE_MALLOC(page_sz);
+ memset(data, 0, page_sz);
- tst_sig(NOFORK, sig_handler, cleanup);
+ tst_res(TINFO, "Read data back from mapped file");
- TEST_PAUSE;
+ SAFE_READ(0, fdesc, data, page_sz);
+ SAFE_LSEEK(fdesc, 0, SEEK_SET);
- page_sz = getpagesize();
+ TST_EXP_EQ_LI(memcmp(data, tmpdata, page_sz), 0);
- /* Allocate space for the test buffer */
- if ((tst_buff = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, NULL, "calloc failed (tst_buff)");
- }
-
- /* Fill the test buffer with the known data */
- memset(tst_buff, 'A', page_sz);
-
- tst_tmpdir();
+ SAFE_MUNMAP(addr, page_sz);
+ free(data);
+}
- /* Creat a temporary file used for mapping */
- if ((fildes = open(TEMPFILE, O_WRONLY | O_CREAT, 0666)) < 0) {
- free(tst_buff);
- tst_brkm(TFAIL | TERRNO, cleanup, "opening %s failed",
- TEMPFILE);
- }
+static void run(void)
+{
+ pid_t pid;
+ int status;
- /* Write test buffer contents into temporary file */
- if (write(fildes, tst_buff, page_sz) < (long)page_sz) {
- free(tst_buff);
- tst_brkm(TFAIL | TERRNO, cleanup, "writing to %s failed",
- TEMPFILE);
+ pid = SAFE_FORK();
+ if (!pid) {
+ run_child();
+ exit(0);
}
- /* Free the memory allocated for test buffer */
- free(tst_buff);
+ SAFE_WAITPID(pid, &status, 0);
- /* Make sure proper permissions set on file */
- if (fchmod(fildes, 0555) < 0) {
- tst_brkm(TFAIL, cleanup, "fchmod of %s failed", TEMPFILE);
+#if defined(__ia64__) || defined(__hppa__) || defined(__mips__)
+ if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
+ tst_res(TPASS, "SIGSEGV has been received");
+ } else {
+ tst_res(TFAIL, "Mapped memory region with NO "
+ "access is accessible");
}
+#endif
+}
- /* Close the temporary file opened for write */
- if (close(fildes) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup, "closing %s failed",
- TEMPFILE);
- }
+static void setup(void)
+{
+ page_sz = getpagesize();
- /* Allocate and initialize dummy string of system page size bytes */
- if ((dummy = calloc(page_sz, sizeof(char))) == NULL) {
- tst_brkm(TFAIL, cleanup, "calloc failed (dummy)");
- }
+ tmpdata = SAFE_MALLOC(page_sz);
+ memset(tmpdata, 'a', page_sz);
- /* Open the temporary file again for reading */
- if ((fildes = open(TEMPFILE, O_RDONLY)) < 0) {
- tst_brkm(TFAIL | TERRNO, cleanup,
- "opening %s read-only failed", TEMPFILE);
- }
-}
+ tst_res(TINFO, "Create temporary file");
-/*
- * This function gets executed when the test process receives
- * the signal SIGSEGV while trying to access the contents of memory which
- * is not accessible.
- */
-static void sig_handler(int sig)
-{
- if (sig == SIGSEGV) {
- /* set the global variable and jump back */
- pass = 1;
- siglongjmp(env, 1);
- } else
- tst_brkm(TBROK, cleanup, "received an unexpected signal");
+ tst_fill_file(TEMPFILE, 'a', page_sz, 1);
+ fdesc = SAFE_OPEN(TEMPFILE, O_RDONLY, 0555);
}
static void cleanup(void)
{
- close(fildes);
- free(dummy);
- tst_rmdir();
+ free(tmpdata);
+
+ if (fdesc != -1)
+ SAFE_CLOSE(fdesc);
}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .forks_child = 1,
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [LTP] [PATCH v3 1/8] Refactor mmap03 test
2025-03-13 9:15 ` [LTP] [PATCH v3 1/8] Refactor mmap03 test Andrea Cervesato
@ 2025-03-13 9:58 ` Petr Vorel
0 siblings, 0 replies; 11+ messages in thread
From: Petr Vorel @ 2025-03-13 9:58 UTC (permalink / raw)
To: Andrea Cervesato; +Cc: ltp
Hi Andrea, Cyril,
...
> +++ b/testcases/kernel/syscalls/mmap/mmap03.c
> - /*
> - * Check whether the mapped memory region
> - * has the file contents.
> - *
> - * with ia64 and PARISC/hppa, this should
> - * generate a SIGSEGV which will be caught below.
> - *
> - */
> -
> - if (sigsetjmp(env, 1) == 0) {
> - if (memcmp(dummy, addr, page_sz)) {
> - tst_resm(TFAIL,
> - "mapped memory region "
> - "contains invalid data");
> - } else {
> - tst_resm(TPASS,
> - "mmap() functionality is "
> - "correct");
> - }
> - }
> -#if defined(__ia64__) || defined(__hppa__) || defined(__mips__)
> - if (pass) {
> - tst_resm(TPASS, "Got SIGSEGV as expected");
> - } else {
> - tst_resm(TFAIL, "Mapped memory region with NO "
> - "access is accessible");
> - }
...
> +#if defined(__ia64__) || defined(__hppa__) || defined(__mips__)
> + if (WIFSIGNALED(status) && WTERMSIG(status) == SIGSEGV) {
> + tst_res(TPASS, "SIGSEGV has been received");
In the previous discussion [1] Cyril noted:
The fact that memory mapped with PROT_EXEC is readable is an
implementation detail for an architecture and not guaranteed. So the
best result is either to expect that the child returns with 0 or dies
with SIGSEGV, either one is correct behavior.
Therefore we don't need to check this for *any* specific architecture (e.g.
remove #if defined preprocessor wrap. And we should check either for 0 or
SIGSEGV, many tests do this, e.g. fstatfs/fstatfs02.c, clone/clone07.c.
> + } else {
> + tst_res(TFAIL, "Mapped memory region with NO "
> + "access is accessible");
nit: Please no split strings (when they are reasonable long).
Kind regards,
Petr
[1] https://lore.kernel.org/ltp/Z7ykr8it7KmHjWsY@yuki.lan/
...
> +static struct tst_test test = {
> + .test_all = run,
> + .setup = setup,
> + .cleanup = cleanup,
> + .needs_tmpdir = 1,
> + .forks_child = 1,
> +};
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread
* [LTP] [PATCH v3 2/8] Refactor mmap10 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 1/8] Refactor mmap03 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 3/8] Cleanup mmap12 test Andrea Cervesato
` (6 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Simplify the mm runtest file, removing mmap10 options, including them
inside the test cases of mmap10.
Reviewed-by: Ricardo B. Marlière <ricardo@marliere.net>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/mm | 5 +-
testcases/kernel/syscalls/mmap/mmap10.c | 255 +++++++++++---------------------
2 files changed, 86 insertions(+), 174 deletions(-)
diff --git a/runtest/mm b/runtest/mm
index d8e62af81fcbf9381a5419ab713139774d081c44..22eb3fd195e72409ea53cf16b0ba26436cb511a9 100644
--- a/runtest/mm
+++ b/runtest/mm
@@ -53,10 +53,7 @@ mmapstress09 mmapstress09 -p 20 -t 0.2
mmapstress10 mmapstress10 -p 20 -t 0.2
mmap10 mmap10
-mmap10_1 mmap10 -a
-mmap10_2 mmap10 -s
-mmap10_3 mmap10 -a -s
-mmap10_4 mmap10 -a -s -i 60
+mmap10_1 mmap10 -i 60
kallsyms kallsyms
diff --git a/testcases/kernel/syscalls/mmap/mmap10.c b/testcases/kernel/syscalls/mmap/mmap10.c
index b844af07fd78d69c5cf5afc3039a54685c982776..4c6a617ddf805613c304f2e1711be057c4a41a89 100644
--- a/testcases/kernel/syscalls/mmap/mmap10.c
+++ b/testcases/kernel/syscalls/mmap/mmap10.c
@@ -1,206 +1,121 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* 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.
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * mmap/munmap /dev/zero: a common way of malloc()/free() anonymous
- * memory on Solaris.
+/*\
+ * This test examines the functionality of mapping and unmapping /dev/zero,
+ * which is a common method for allocating anonymous memory in 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.
+ * The primary objective is to determine whether it is possible to successfully
+ * map and unmap /dev/zero, as well as to read from and write to the mapped
+ * memory. The design of this test is inspired by two previous bugs,
+ * incorporating variations based on their reproducers. Additionally, the test
+ * accepts 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.
+ * One of the bugs aims to trigger a panic related to the transparent hugepage
+ * feature. The split_huge_page function is particularly strict in verifying
+ * that the reverse mapping (rmap) walk is accurate. This strictness is crucial
+ * because if the page_mapcount is not stable or correct, the subsequent
+ * __split_huge_page_refcount operation could lead to inconsistent page_count()
+ * values for the subpages. A bug related to fork caused the rmap walk to find
+ * the parent huge-pmd twice instead of once, due to the anon_vma_chain objects
+ * of the child VMA still pointing to the parent's vma->vm_mm. This
+ * inconsistency triggers a failure in the split_huge_page mapcount versus
+ * page_mapcount check, resulting in 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.
+ * The second bug involves the mmap() operation on /dev/zero, which invokes
+ * map_zero(). On RHEL5, this function maps the ZERO_PAGE into every page table
+ * entry (PTE) within the specified virtual address range. When an application
+ * maps a region from 5M to 16M and operates in a multi-threaded environment,
+ * the subsequent munmap() of /dev/zero leads to TLB shootdowns across all CPUs.
+ * When this occurs thousands or millions of times, it severely degrades
+ * application performance. The optimization of mapping the ZERO_PAGE in every
+ * PTE within that virtual address range was intended to enhance page fault
+ * handling times on RHEL5 but has since been modified or removed in upstream
+ * versions.
*/
-#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;
+#include "tst_test.h"
-static int fd, opt_anon, opt_ksm;
-static long ps;
-static char *x;
+#define SIZE (5 * TST_MB)
+#define PATH_KSM "/sys/kernel/mm/ksm/"
-void setup(void);
-void cleanup(void);
-void mmapzero(void);
-void help(void);
+static size_t page_sz;
+static char *memory;
-static option_t options[] = {
- {"a", &opt_anon, NULL},
- {"s", &opt_ksm, NULL},
- {NULL, NULL, NULL}
+struct tcase {
+ int anon;
+ int add_ksm;
+} tcases[] = {
+ { .anon = 1 },
+ { .add_ksm = 1 },
+ { .anon = 1, .add_ksm = 1 },
};
-int main(int argc, char *argv[])
+static void run(unsigned int i)
{
- int lc;
-
- tst_parse_opts(argc, argv, options, help);
+ struct tcase *tc = &tcases[i];
+ int fd = -1;
- if (opt_ksm) {
+ if (tc->add_ksm) {
if (access(PATH_KSM, F_OK) == -1)
- tst_brkm(TCONF, NULL,
- "KSM configuration is not enabled");
-#ifdef HAVE_DECL_MADV_MERGEABLE
- tst_resm(TINFO, "add to KSM regions.");
-#else
- tst_brkm(TCONF, NULL, "MADV_MERGEABLE missing in sys/mman.h");
-#endif
+ tst_brk(TCONF, "KSM configuration is not enabled");
+ } else {
+ tst_res(TINFO, "Add to KSM regions");
}
- if (opt_anon)
- tst_resm(TINFO, "use anonymous pages.");
+
+ if (tc->anon)
+ tst_res(TINFO, "Use anonymous pages");
else
- tst_resm(TINFO, "use /dev/zero.");
+ tst_res(TINFO, "Use /dev/zero device");
- setup();
+ if (tc->anon) {
+ memory = SAFE_MMAP(NULL, SIZE + SIZE - page_sz,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ } else {
+ fd = SAFE_OPEN("/dev/zero", O_RDWR, 0666);
- tst_resm(TINFO, "start tests.");
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
- mmapzero();
+ memory = SAFE_MMAP(NULL, SIZE + SIZE - page_sz,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE, fd, 0);
}
- 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_DECL_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;
+ if (tc->add_ksm) {
+ if (madvise(memory, SIZE + SIZE - page_sz, MADV_MERGEABLE) == -1)
+ tst_brk(TBROK | TERRNO, "madvise error");
}
- 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");
+ memory[SIZE] = 0;
+
+ for (int i = 0; i < 3; i++) {
+ if (!SAFE_FORK()) {
+ SAFE_MUNMAP(memory + SIZE + page_sz, SIZE - page_sz * 2);
exit(0);
- default:
- break;
}
- break;
}
- if (munmap(x, SIZE + SIZE - ps) == -1)
- tst_resm(TFAIL | TERRNO, "munmap all");
+ SAFE_MUNMAP(memory, SIZE + SIZE - page_sz);
- while (waitpid(-1, &n, WUNTRACED | WCONTINUED) > 0)
- if (WEXITSTATUS(n) != 0)
- tst_resm(TFAIL, "child exit status is %d",
- WEXITSTATUS(n));
-}
+ tst_reap_children();
-void cleanup(void)
-{
-}
-
-void setup(void)
-{
- tst_require_root();
+ tst_res(TPASS, "All memory has been released");
- tst_sig(FORK, DEF_HANDLER, cleanup);
- TEST_PAUSE;
-
- if ((ps = sysconf(_SC_PAGESIZE)) == -1)
- tst_brkm(TBROK | TERRNO, cleanup, "sysconf(_SC_PAGESIZE)");
+ if (fd != -1)
+ SAFE_CLOSE(fd);
}
-void help(void)
+static void setup(void)
{
- printf(" -a Test anonymous pages\n");
- printf(" -s Add to KSM regions\n");
+ page_sz = SAFE_SYSCONF(_SC_PAGESIZE);
}
+
+static struct tst_test test = {
+ .test = run,
+ .setup = setup,
+ .needs_root = 1,
+ .forks_child = 1,
+ .tcnt = ARRAY_SIZE(tcases),
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 3/8] Cleanup mmap12 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 1/8] Refactor mmap03 test Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 2/8] Refactor mmap10 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 4/8] Cleanup mmap17 test Andrea Cervesato
` (5 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap12.c | 30 ++++++------------------------
1 file changed, 6 insertions(+), 24 deletions(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap12.c b/testcases/kernel/syscalls/mmap/mmap12.c
index 995a2bab091a745dd7332fe919c1ea38b25641e3..043218834ca8c5284e6d25c7018faa0d09460f67 100644
--- a/testcases/kernel/syscalls/mmap/mmap12.c
+++ b/testcases/kernel/syscalls/mmap/mmap12.c
@@ -1,31 +1,13 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) 2013 FNST, DAN LI <li.dan@cn.fujitsu.com>
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Test Description:
- * Verify MAP_POPULATE works fine.
- * "For a file mapping, this causes read-ahead on the file.
- * Later accesses to the mapping will not be blocked by page faults"
- *
- * Expected Result:
- * mmap() with MAP_POPULATE should succeed returning the address of the
- * mapped region and this file has been read into RAM, so pages should
- * be present.
+/*\
+ * Verify that mmap() with MAP_POPULATE succeed returning the address of the
+ * mapped region. The file should be read into RAM, and pages should be present.
*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <signal.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <sys/shm.h>
#include "tst_test.h"
@@ -60,9 +42,9 @@ static void page_check(void)
tst_res(TCONF | TERRNO,
"don't have permission to open dev pagemap");
return;
- } else {
- tst_brk(TFAIL | TERRNO, "pen dev pagemap failed");
}
+
+ tst_brk(TFAIL | TERRNO, "pen dev pagemap failed");
}
offset = SAFE_LSEEK(pm, index, SEEK_SET);
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 4/8] Cleanup mmap17 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (2 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 3/8] Cleanup mmap12 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 5/8] Cleanup mmap18 test Andrea Cervesato
` (4 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap17.c | 52 +++++++++++++--------------------
1 file changed, 21 insertions(+), 31 deletions(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap17.c b/testcases/kernel/syscalls/mmap/mmap17.c
index 39703fbd397d33fe549b1c9a52db62f763e146dd..c7b12f0fe9607afed7a934cceff1a8f643757b54 100644
--- a/testcases/kernel/syscalls/mmap/mmap17.c
+++ b/testcases/kernel/syscalls/mmap/mmap17.c
@@ -1,73 +1,63 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Zilogic Systems Pvt. Ltd., 2020
- * Email: code@zilogic.com
+ * Email: code@zilogic.com
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Test mmap with MAP_FIXED_NOREPLACE flag
- *
- * We are testing the MAP_FIXED_NOREPLACE flag of mmap() syscall. To check
+/*\
+ * Verify MAP_FIXED_NOREPLACE flag for the mmap() syscall and check
* if an attempt to mmap at an exisiting mapping fails with EEXIST.
+ *
+ * [Algorithm]
+ *
* The code allocates a free address by passing NULL to first mmap call
- * Then tries to mmap with the same address using MAP_FIXED_NOREPLACE flag
+ * then tries to mmap with the same address using MAP_FIXED_NOREPLACE flag
* and the mapping fails as expected.
*/
-#include <stdio.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-#include <stdlib.h>
-#include "lapi/mmap.h"
#include "tst_test.h"
static int fd_file1;
static int fd_file2;
static void *mapped_address;
-static const char str[] = "Writing to mapped file";
+static const char msg[] = "Writing to mapped file";
+static int msg_len;
#define FNAME1 "file1_to_mmap"
#define FNAME2 "file2_to_mmap"
static void setup(void)
{
+ msg_len = strlen(msg);
+
fd_file1 = SAFE_OPEN(FNAME1, O_CREAT | O_RDWR, 0600);
fd_file2 = SAFE_OPEN(FNAME2, O_CREAT | O_RDWR, 0600);
+
+ SAFE_WRITE(SAFE_WRITE_ALL, fd_file1, msg, msg_len);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd_file2, msg, msg_len);
+
+ mapped_address = SAFE_MMAP(NULL, msg_len,
+ PROT_WRITE, MAP_PRIVATE, fd_file1, 0);
}
static void cleanup(void)
{
- int str_len;
-
- str_len = strlen(str);
-
if (fd_file2 > 0)
SAFE_CLOSE(fd_file2);
if (fd_file1 > 0)
SAFE_CLOSE(fd_file1);
if (mapped_address)
- SAFE_MUNMAP(mapped_address, str_len);
+ SAFE_MUNMAP(mapped_address, msg_len);
}
static void test_mmap(void)
{
- int str_len;
void *address;
- str_len = strlen(str);
-
- SAFE_WRITE(SAFE_WRITE_ALL, fd_file1, str, str_len);
- mapped_address = SAFE_MMAP(NULL, str_len, PROT_WRITE,
- MAP_PRIVATE, fd_file1, 0);
-
- SAFE_WRITE(SAFE_WRITE_ALL, fd_file2, str, str_len);
-
- address = mmap(mapped_address, str_len, PROT_WRITE,
+ address = mmap(mapped_address, msg_len, PROT_WRITE,
MAP_PRIVATE | MAP_FIXED_NOREPLACE, fd_file2, 0);
+
if (address == MAP_FAILED && errno == EEXIST)
tst_res(TPASS, "mmap set errno to EEXIST as expected");
else
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 5/8] Cleanup mmap18 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (3 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 4/8] Cleanup mmap17 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 6/8] Cleanup mmap19 test Andrea Cervesato
` (3 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap18.c | 90 ++++++++++++++++-----------------
1 file changed, 43 insertions(+), 47 deletions(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap18.c b/testcases/kernel/syscalls/mmap/mmap18.c
index b37b29890ca009ea671b29e81e02fc1e42b44dbb..3de524ecc60b53ec352f58a00620dc39f3f787a5 100644
--- a/testcases/kernel/syscalls/mmap/mmap18.c
+++ b/testcases/kernel/syscalls/mmap/mmap18.c
@@ -1,58 +1,54 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (c) Zilogic Systems Pvt. Ltd., 2020
- * Email: code@zilogic.com
+ * Email: code@zilogic.com
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
*/
-/*
- * Test mmap() MAP_GROWSDOWN flag
+/*\
+ * Verify mmap() syscall using MAP_GROWSDOWN flag.
+ *
+ * [Algorithm]
*
- * # Test1:
+ * **Test 1**
*
- * We assign the memory region partially allocated with MAP_GROWSDOWN flag to
- * a thread as a stack and expect the mapping to grow when we touch the
- * guard page by calling a recusive function in the thread that uses the
- * growable mapping as a stack.
+ * We assign the memory region partially allocated with MAP_GROWSDOWN flag to
+ * a thread as a stack and expect the mapping to grow when we touch the
+ * guard page by calling a recusive function in the thread that uses the
+ * growable mapping as a stack.
*
- * The kernel only grows the memory region when the stack pointer is within
- * guard page when the guard page is touched so simply faulting the guard
- * page will not cause the mapping to grow.
+ * The kernel only grows the memory region when the stack pointer is within
+ * guard page when the guard page is touched so simply faulting the guard
+ * page will not cause the mapping to grow.
*
- * Newer kernels does not allow a MAP_GROWSDOWN mapping to grow closer than
- * 'stack_guard_gap' pages to an existing mapping. So when we map the stack we
- * make sure there is enough of free address space before the lowest stack
- * address.
+ * Newer kernels does not allow a MAP_GROWSDOWN mapping to grow closer than
+ * 'stack_guard_gap' pages to an existing mapping. So when we map the stack we
+ * make sure there is enough of free address space before the lowest stack
+ * address.
*
- * Kernel default 'stack_guard_gap' size is '256 * getpagesize()'.
+ * Kernel default `stack_guard_gap` size is `256 * getpagesize()`.
*
- * The stack memory map would look like:
+ * The stack memory map would look like:
*
- * | - - - reserved size - - - |
+ * | - - - reserved size - - - |
*
- * +-- - - - --+------------+-------------+
- * | 256 pages | unmapped | mapped |
- * +-- - - - --+------------+-------------+
- * | mapped size |
- * ^ | - - stack size - - |
- * start
- * ^ ^
- * stack bottom stack top
+ * +-- - - - --+------------+-------------+
+ * | 256 pages | unmapped | mapped |
+ * +-- - - - --+------------+-------------+
+ * | mapped size |
+ * ^ | - - stack size - - |
+ * start
+ * ^ ^
+ * stack bottom stack top
*
- * # Test2:
+ * **Test 2**
*
- * We allocate stack as we do in the first test but we mmap a page in the
- * space the stack is supposed to grow into and we expect the thread to
- * segfault when the guard page is faulted.
+ * We allocate stack as we do in the first test but we mmap a page in the
+ * space the stack is supposed to grow into and we expect the thread to
+ * segfault when the guard page is faulted.
*/
-#include <unistd.h>
#include <pthread.h>
-#include <sys/mman.h>
-#include <sys/wait.h>
-#include <sys/types.h>
-#include <stdlib.h>
-#include <stdbool.h>
-
#include "tst_test.h"
#include "tst_safe_pthread.h"
@@ -63,12 +59,12 @@ static bool __attribute__((noinline)) check_stackgrow_up(void)
char local_var;
static char *addr;
- if (!addr) {
- addr = &local_var;
- return check_stackgrow_up();
- }
+ if (!addr) {
+ addr = &local_var;
+ return check_stackgrow_up();
+ }
- return (addr < &local_var);
+ return (addr < &local_var);
}
static void setup(void)
@@ -90,7 +86,7 @@ static void *allocate_stack(size_t stack_size, size_t mapped_size)
long reserved_size = 256 * page_size + stack_size;
start = SAFE_MMAP(NULL, reserved_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
SAFE_MUNMAP(start, reserved_size);
SAFE_MMAP((start + reserved_size - mapped_size), mapped_size, PROT_READ | PROT_WRITE,
@@ -103,7 +99,7 @@ static void *allocate_stack(size_t stack_size, size_t mapped_size)
tst_res(TINFO, "start = %p, stack_top = %p, stack bottom = %p",
start, stack_top, stack_bottom);
tst_res(TINFO, "mapped pages %zu, stack pages %zu",
- mapped_size/page_size, stack_size/page_size);
+ mapped_size/page_size, stack_size/page_size);
return stack_bottom;
}
@@ -192,10 +188,10 @@ static void grow_stack_fail(size_t stack_size, size_t mapped_size)
}
SAFE_WAIT(&wstatus);
- if (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGSEGV)
+ if (WIFSIGNALED(wstatus) && WTERMSIG(wstatus) == SIGSEGV)
tst_res(TPASS, "Child killed by %s as expected", tst_strsig(SIGSEGV));
- else
- tst_res(TFAIL, "Child: %s", tst_strstatus(wstatus));
+ else
+ tst_res(TFAIL, "Child: %s", tst_strstatus(wstatus));
}
static void run_test(void)
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 6/8] Cleanup mmap19 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (4 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 5/8] Cleanup mmap18 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 7/8] Cleanup mmap20 test Andrea Cervesato
` (2 subsequent siblings)
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap19.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap19.c b/testcases/kernel/syscalls/mmap/mmap19.c
index e622539c32c704bfa557d1d6b93366fea502acb5..77ff771ae20d0dba4e8c17664b52201c5f99e664 100644
--- a/testcases/kernel/syscalls/mmap/mmap19.c
+++ b/testcases/kernel/syscalls/mmap/mmap19.c
@@ -22,7 +22,7 @@
#define LEN 64
static int f1 = -1, f2 = -1;
-static char *mm1 = NULL, *mm2 = NULL;
+static char *mm1, *mm2;
static const char tmp1[] = "testfile1";
static const char tmp2[] = "testfile2";
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 7/8] Cleanup mmap20 test
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (5 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 6/8] Cleanup mmap19 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:15 ` [LTP] [PATCH v3 8/8] Refactor mmap001 test and move it to mmap21 Andrea Cervesato
2025-03-13 9:22 ` [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato via ltp
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Cyril Hrubis <chrubis@suse.cz>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
testcases/kernel/syscalls/mmap/mmap20.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/testcases/kernel/syscalls/mmap/mmap20.c b/testcases/kernel/syscalls/mmap/mmap20.c
index 09dea8c41d2687031cce7ded90cf10d2ab392a5b..f8e5129d1e490b931f0668bd2fe8ea89c64d0404 100644
--- a/testcases/kernel/syscalls/mmap/mmap20.c
+++ b/testcases/kernel/syscalls/mmap/mmap20.c
@@ -10,9 +10,6 @@
* flag and invalid flag.
*/
-#include <errno.h>
-#include <stdio.h>
-#include <sys/types.h>
#include "tst_test.h"
#include "lapi/mmap.h"
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* [LTP] [PATCH v3 8/8] Refactor mmap001 test and move it to mmap21
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (6 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 7/8] Cleanup mmap20 test Andrea Cervesato
@ 2025-03-13 9:15 ` Andrea Cervesato
2025-03-13 9:22 ` [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato via ltp
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato @ 2025-03-13 9:15 UTC (permalink / raw)
To: ltp
From: Andrea Cervesato <andrea.cervesato@suse.com>
Reviewed-by: Ricardo B. Marlière <ricardo@marliere.net>
Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
---
runtest/mm | 8 +-
runtest/syscalls | 3 +-
testcases/kernel/syscalls/mmap/.gitignore | 2 +-
testcases/kernel/syscalls/mmap/mmap001.c | 183 ------------------------------
testcases/kernel/syscalls/mmap/mmap21.c | 99 ++++++++++++++++
5 files changed, 104 insertions(+), 191 deletions(-)
diff --git a/runtest/mm b/runtest/mm
index 22eb3fd195e72409ea53cf16b0ba26436cb511a9..871e1f026785929240bb87d32a68dfdb5ea90fef 100644
--- a/runtest/mm
+++ b/runtest/mm
@@ -1,13 +1,9 @@
#DESCRIPTION:Memory Mgmt tests
-mm01 mmap001 -m 10000
+mmap21_01 mmap21 -m 10000
# 40 Mb mmap() test.
# Creates a 10000 page mmap, touches all of the map, sync's it, and
# munmap()s it.
-mm02 mmap001
-# simple mmap() test.
-#mm03 mmap001 -i 0 -I 1 -m 100
-# repetitive mmapping test.
-# Creates a one page map repetitively for one minute.
+mmap21_02 mmap21
mtest01 mtest01 -p80
mtest01w mtest01 -p80 -w
diff --git a/runtest/syscalls b/runtest/syscalls
index 5cd1ae656ca38fff64aec158d293f465917bd706..8ebf842ff3f3e572f90dfdc0b3159a7370c6d3e5 100644
--- a/runtest/syscalls
+++ b/runtest/syscalls
@@ -823,7 +823,6 @@ mlock201 mlock201
mlock202 mlock202
mlock203 mlock203
-qmm01 mmap001 -m 1
mmap01 mmap01
mmap02 mmap02
mmap03 mmap03
@@ -843,6 +842,8 @@ mmap17 mmap17
mmap18 mmap18
mmap19 mmap19
mmap20 mmap20
+mmap21_01 mmap21 -m 1
+mmap21_02 mmap21
modify_ldt01 modify_ldt01
modify_ldt02 modify_ldt02
diff --git a/testcases/kernel/syscalls/mmap/.gitignore b/testcases/kernel/syscalls/mmap/.gitignore
index 4591fdbb9b71d5edb534c3d99f1a66e0e42ce6b6..850284d86616e29674df89b8107a5939c25723da 100644
--- a/testcases/kernel/syscalls/mmap/.gitignore
+++ b/testcases/kernel/syscalls/mmap/.gitignore
@@ -1,4 +1,3 @@
-/mmap001
/mmap01
/mmap02
/mmap03
@@ -18,3 +17,4 @@
/mmap18
/mmap19
/mmap20
+/mmap21
diff --git a/testcases/kernel/syscalls/mmap/mmap001.c b/testcases/kernel/syscalls/mmap/mmap001.c
deleted file mode 100644
index dabb7d1e4998b1097e179abe23555926f5841117..0000000000000000000000000000000000000000
--- a/testcases/kernel/syscalls/mmap/mmap001.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (C) 2000 Juan Quintela <quintela@fi.udc.es>
- * Aaron Laffin <alaffin@sgi.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * mmap001.c - Tests mmapping a big file and writing it once
- */
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
-
-#include "test.h"
-
-char *TCID = "mmap001";
-int TST_TOTAL = 5;
-static char *filename = NULL;
-static int m_opt = 0;
-static char *m_copt;
-
-static void cleanup(void)
-{
- free(filename);
-
- tst_rmdir();
-}
-
-static void setup(void)
-{
- char buf[1024];
- /*
- * setup a default signal hander and a
- * temporary working directory.
- */
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- tst_tmpdir();
-
- snprintf(buf, 1024, "testfile.%d", getpid());
-
- if ((filename = strdup(buf)) == NULL) {
- tst_brkm(TBROK | TERRNO, cleanup, "strdup failed");
- }
-
-}
-
-static void help(void)
-{
- printf(" -m x size of mmap in pages (default 1000)\n");
-}
-
-/*
- * add the -m option whose parameter is the
- * pages that should be mapped.
- */
-option_t options[] = {
- {"m:", &m_opt, &m_copt},
- {NULL, NULL, NULL}
-};
-
-int main(int argc, char *argv[])
-{
- char *array;
- int lc;
- unsigned int i;
- int fd;
- unsigned int pages, memsize;
-
- tst_parse_opts(argc, argv, options, help);
-
- if (m_opt) {
- memsize = pages = atoi(m_copt);
-
- if (memsize < 1) {
- tst_brkm(TBROK, cleanup, "Invalid arg for -m: %s",
- m_copt);
- }
-
- memsize *= getpagesize(); /* N PAGES */
-
- } else {
- /*
- * default size 1000 pages;
- */
- memsize = pages = 1000;
- memsize *= getpagesize();
- }
-
- tst_resm(TINFO, "mmap()ing file of %u pages or %u bytes", pages,
- memsize);
-
- setup();
-
- for (lc = 0; TEST_LOOPING(lc); lc++) {
- tst_count = 0;
-
- fd = open(filename, O_RDWR | O_CREAT, 0666);
- if ((fd == -1))
- tst_brkm(TBROK | TERRNO, cleanup,
- "opening %s failed", filename);
-
- if (lseek(fd, memsize, SEEK_SET) != memsize) {
- TEST_ERRNO = errno;
- close(fd);
- tst_brkm(TBROK | TTERRNO, cleanup, "lseek failed");
- }
-
- if (write(fd, "\0", 1) != 1) {
- TEST_ERRNO = errno;
- close(fd);
- tst_brkm(TBROK | TTERRNO, cleanup,
- "writing to %s failed", filename);
- }
-
- array = mmap(0, memsize, PROT_WRITE, MAP_SHARED, fd, 0);
- if (array == MAP_FAILED) {
- TEST_ERRNO = errno;
- close(fd);
- tst_brkm(TBROK | TTERRNO, cleanup,
- "mmapping %s failed", filename);
- } else {
- tst_resm(TPASS, "mmap() completed successfully.");
- }
-
- tst_resm(TINFO, "touching mmaped memory");
-
- for (i = 0; i < memsize; i++) {
- array[i] = (char)i;
- }
-
- /*
- * seems that if the map area was bad, we'd get SEGV,
- * hence we can indicate a PASS.
- */
- tst_resm(TPASS,
- "we're still here, mmaped area must be good");
-
- TEST(msync(array, memsize, MS_SYNC));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL | TTERRNO,
- "synchronizing mmapped page failed");
- } else {
- tst_resm(TPASS,
- "synchronizing mmapped page passed");
- }
-
- TEST(munmap(array, memsize));
-
- if (TEST_RETURN == -1) {
- tst_resm(TFAIL | TTERRNO,
- "munmapping %s failed", filename);
- } else {
- tst_resm(TPASS, "munmapping %s successful", filename);
- }
-
- close(fd);
- unlink(filename);
-
- }
- cleanup();
- tst_exit();
-}
diff --git a/testcases/kernel/syscalls/mmap/mmap21.c b/testcases/kernel/syscalls/mmap/mmap21.c
new file mode 100644
index 0000000000000000000000000000000000000000..5e41f194abcee306dd7075e7bc2a955ae04ed4c6
--- /dev/null
+++ b/testcases/kernel/syscalls/mmap/mmap21.c
@@ -0,0 +1,99 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2000 Juan Quintela <quintela@fi.udc.es>
+ * Aaron Laffin <alaffin@sgi.com>
+ * Copyright (C) 2025 SUSE LLC Andrea Cervesato <andrea.cervesato@suse.com>
+ */
+
+/*\
+ * Verify that we can use mmap() to map a large file, write to it via memory
+ * access, and read back the data from the file.
+ */
+
+#include "tst_test.h"
+
+#define FILE_NAME "testfile"
+
+static char *str_pages;
+static long long pages = 1000;
+static long long memory_size;
+static char *memory_data;
+static char *buff;
+
+static void run(void)
+{
+ int fd;
+ pid_t pid;
+
+ tst_res(TINFO, "mmap()ing file of %llu bytes", memory_size);
+
+ fd = SAFE_OPEN(FILE_NAME, O_RDWR | O_CREAT, 0666);
+ SAFE_LSEEK(fd, memory_size, SEEK_SET);
+ SAFE_WRITE(SAFE_WRITE_ALL, fd, "\0", 1);
+
+ memory_data = SAFE_MMAP(0, memory_size, PROT_WRITE, MAP_SHARED, fd, 0);
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ tst_res(TINFO, "Touching mapped memory");
+
+ for (int i = 0; i < memory_size; i++)
+ memory_data[i] = (char)i;
+
+ exit(0);
+ }
+
+ tst_reap_children();
+
+ SAFE_MSYNC(memory_data, memory_size, MS_SYNC);
+
+ memset(buff, 0, memory_size);
+
+ SAFE_LSEEK(fd, 0, SEEK_SET);
+ SAFE_READ(0, fd, buff, memory_size);
+ SAFE_CLOSE(fd);
+
+ for (int i = 0; i < memory_size; i++) {
+ if (buff[i] != (char)i) {
+ tst_res(TFAIL, "Mapped file has not been updated at byte %d", i);
+ goto exit;
+ }
+ }
+
+ tst_res(TPASS, "Mapped file has been updated");
+
+exit:
+ SAFE_MUNMAP(memory_data, memory_size);
+ SAFE_UNLINK(FILE_NAME);
+}
+
+static void setup(void)
+{
+ if (tst_parse_filesize(str_pages, &pages, 1, LLONG_MAX))
+ tst_brk(TBROK, "Invalid number of pages: %s", str_pages);
+
+ memory_size = pages * getpagesize();
+
+ buff = SAFE_MALLOC(memory_size);
+}
+
+static void cleanup(void)
+{
+ if (buff)
+ free(buff);
+
+ if (memory_data)
+ SAFE_MUNMAP(memory_data, memory_size);
+}
+
+static struct tst_test test = {
+ .test_all = run,
+ .setup = setup,
+ .cleanup = cleanup,
+ .needs_tmpdir = 1,
+ .forks_child = 1,
+ .options = (struct tst_option[]) {
+ {"m:", &str_pages, "Number of pages (default 1000)"},
+ {}
+ },
+};
--
2.43.0
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply related [flat|nested] 11+ messages in thread* Re: [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite
2025-03-13 9:15 [LTP] [PATCH v3 0/8] Cleanup the mmap testing suite Andrea Cervesato
` (7 preceding siblings ...)
2025-03-13 9:15 ` [LTP] [PATCH v3 8/8] Refactor mmap001 test and move it to mmap21 Andrea Cervesato
@ 2025-03-13 9:22 ` Andrea Cervesato via ltp
8 siblings, 0 replies; 11+ messages in thread
From: Andrea Cervesato via ltp @ 2025-03-13 9:22 UTC (permalink / raw)
To: Andrea Cervesato, ltp
Hi,
there are some missing parts in the patch set. I got spare reviews
between v1 and v2 that I missed. Please ignore this patch-set and I will
send a new v4 with correct description as well...
Andrea
On 3/13/25 10:15, Andrea Cervesato wrote:
> Some of the tests in the mmap testing suites are using old API, having
> documentation which is not linked to the metadata or need to be cleaned
> up a bit. This patch-set is meant to fix these issues. mmap11 is for
> IA64 only and that will require a separate patch and discussion.
>
> Signed-off-by: Andrea Cervesato <andrea.cervesato@suse.com>
> ---
> Changes in v3:
> - mmap01: this and that
> - Link to v2: https://lore.kernel.org/r/20250210-mmap_suite_refactoring-v2-0-6edea3a4363a@suse.com
>
> Changes in v2:
> - mmap21: verify SIGSEGV
> - Link to v1: https://lore.kernel.org/r/20250207-mmap_suite_refactoring-v1-0-d006d921e4d5@suse.com
>
> ---
> Andrea Cervesato (8):
> Refactor mmap03 test
> Refactor mmap10 test
> Cleanup mmap12 test
> Cleanup mmap17 test
> Cleanup mmap18 test
> Cleanup mmap19 test
> Cleanup mmap20 test
> Refactor mmap001 test and move it to mmap21
>
> runtest/mm | 13 +-
> runtest/syscalls | 3 +-
> testcases/kernel/syscalls/mmap/.gitignore | 2 +-
> testcases/kernel/syscalls/mmap/mmap001.c | 183 ---------------------
> testcases/kernel/syscalls/mmap/mmap03.c | 263 ++++++++----------------------
> testcases/kernel/syscalls/mmap/mmap10.c | 255 ++++++++++-------------------
> testcases/kernel/syscalls/mmap/mmap12.c | 30 +---
> testcases/kernel/syscalls/mmap/mmap17.c | 52 +++---
> testcases/kernel/syscalls/mmap/mmap18.c | 90 +++++-----
> testcases/kernel/syscalls/mmap/mmap19.c | 2 +-
> testcases/kernel/syscalls/mmap/mmap20.c | 3 -
> testcases/kernel/syscalls/mmap/mmap21.c | 99 +++++++++++
> 12 files changed, 330 insertions(+), 665 deletions(-)
> ---
> base-commit: a92aedfabd5826d07809559508c8486c12ff7b96
> change-id: 20250205-mmap_suite_refactoring-322042abb356
>
> Best regards,
--
Mailing list info: https://lists.linux.it/listinfo/ltp
^ permalink raw reply [flat|nested] 11+ messages in thread