diff --git a/core-opts.c b/core-opts.c index 1b95f5a3b..e483ac7d4 100644 --- a/core-opts.c +++ b/core-opts.c @@ -509,6 +509,7 @@ const struct option stress_long_options[] = { { "mmap-mergeable", 0, 0, OPT_mmap_mergeable }, { "mmap-mlock", 0, 0, OPT_mmap_mlock }, { "mmap-mmap2", 0, 0, OPT_mmap_mmap2 }, + { "mmap-write-check", 0, 0, OPT_mmap_write_check }, { "mmapaddr", 1, 0, OPT_mmapaddr }, { "mmapaddr-mlock", 0, 0, OPT_mmapaddr_mlock }, { "mmapaddr-ops", 1, 0, OPT_mmapaddr_ops }, diff --git a/core-opts.h b/core-opts.h index 7e1a18ae4..ce2dda40f 100644 --- a/core-opts.h +++ b/core-opts.h @@ -768,6 +768,7 @@ typedef enum { OPT_mmap_odirect, OPT_mmap_ops, OPT_mmap_osync, + OPT_mmap_write_check, OPT_mmapaddr, OPT_mmapaddr_mlock, diff --git a/kernel-coverage.sh b/kernel-coverage.sh index 5d73cae84..67c218f1b 100755 --- a/kernel-coverage.sh +++ b/kernel-coverage.sh @@ -549,6 +549,7 @@ do_stress --mmap -1 --mmap-mprotect do_stress --mmap -1 --mmap-odirect do_stress --mmap -1 --mmap-osync do_stress --mmap -1 --mmap-mmap2 +do_stress --mmap -1 --mmap-write-check do_stress --mmap -1 --thrash do_stress --mmapaddr -1 --mmapaddr-mlock diff --git a/stress-mmap.c b/stress-mmap.c index 8ad499994..c7c18aaa5 100644 --- a/stress-mmap.c +++ b/stress-mmap.c @@ -38,19 +38,20 @@ #define DEFAULT_MMAP_BYTES (256 * MB) static const stress_help_t help[] = { - { NULL, "mmap N", "start N workers stressing mmap and munmap" }, - { NULL, "mmap-async", "using asynchronous msyncs for file based mmap" }, - { NULL, "mmap-bytes N", "mmap and munmap N bytes for each stress iteration" }, - { NULL, "mmap-file", "mmap onto a file using synchronous msyncs" }, - { NULL, "mmap-madvise", "enable random madvise on mmap'd region" }, - { NULL, "mmap-mergeable","where possible, flag mmap'd pages as mergeable" }, - { NULL, "mmap-mlock", "attempt to mlock mmap'd pages" }, - { NULL, "mmap-mmap2", "use mmap2 instead of mmap (when available)" }, - { NULL, "mmap-mprotect", "enable mmap mprotect stressing" }, - { NULL, "mmap-odirect", "enable O_DIRECT on file" }, - { NULL, "mmap-ops N", "stop after N mmap bogo operations" }, - { NULL, "mmap-osync", "enable O_SYNC on file" }, - { NULL, NULL, NULL } + { NULL, "mmap N", "start N workers stressing mmap and munmap" }, + { NULL, "mmap-async", "using asynchronous msyncs for file based mmap" }, + { NULL, "mmap-bytes N", "mmap and munmap N bytes for each stress iteration" }, + { NULL, "mmap-file", "mmap onto a file using synchronous msyncs" }, + { NULL, "mmap-madvise", "enable random madvise on mmap'd region" }, + { NULL, "mmap-mergeable", "where possible, flag mmap'd pages as mergeable" }, + { NULL, "mmap-mlock", "attempt to mlock mmap'd pages" }, + { NULL, "mmap-mmap2", "use mmap2 instead of mmap (when available)" }, + { NULL, "mmap-mprotect", "enable mmap mprotect stressing" }, + { NULL, "mmap-odirect", "enable O_DIRECT on file" }, + { NULL, "mmap-ops N", "stop after N mmap bogo operations" }, + { NULL, "mmap-osync", "enable O_SYNC on file" }, + { NULL, "mmap-write-check", "set check value in each page and perform sanity read check" }, + { NULL, NULL, NULL } }; typedef void * (*mmap_func_t)(void *addr, size_t length, int prot, int flags, int fd, off_t offset); @@ -66,6 +67,7 @@ typedef struct { bool mmap_mergeable; bool mmap_mlock; bool mmap_mprotect; + bool mmap_write_check; mmap_func_t mmap; size_t mmap_prot_count; int *mmap_prot_perms; @@ -293,6 +295,11 @@ static int stress_set_mmap_mmap2(const char *opt) return stress_set_setting_true("mmap-mmap2", opt); } +static int stress_set_mmap_write_check(const char *opt) +{ + return stress_set_setting_true("mmap-write-check", opt); +} + /* * stress_mmap_mprotect() * cycle through page settings on a region of mmap'd memory @@ -612,11 +619,13 @@ static int stress_mmap_child(stress_args_t *args, void *ctxt) } /* Ensure we can write to the mapped pages */ - stress_mmap_set_light(buf, sz, page_size); - if (g_opt_flags & OPT_FLAGS_VERIFY) { - if (stress_mmap_check_light(buf, sz, page_size) < 0) - pr_fail("%s: mmap'd region of %zu bytes does " - "not contain expected data\n", args->name, sz); + if (context->mmap_write_check) { + stress_mmap_set_light(buf, sz, page_size); + if (g_opt_flags & OPT_FLAGS_VERIFY) { + if (stress_mmap_check_light(buf, sz, page_size) < 0) + pr_fail("%s: mmap'd region of %zu bytes does " + "not contain expected data\n", args->name, sz); + } } /* @@ -711,10 +720,12 @@ static int stress_mmap_child(stress_args_t *args, void *ctxt) page_size, page_size, context->mmap_mprotect); mapped[page] = PAGE_MAPPED; /* Ensure we can write to the mapped page */ - stress_mmap_set_light(mappings[page], page_size, page_size); - if (stress_mmap_check_light(mappings[page], page_size, page_size) < 0) - pr_fail("%s: mmap'd region of %zu bytes does " - "not contain expected data\n", args->name, page_size); + if (context->mmap_write_check) { + stress_mmap_set_light(mappings[page], page_size, page_size); + if (stress_mmap_check_light(mappings[page], page_size, page_size) < 0) + pr_fail("%s: mmap'd region of %zu bytes does " + "not contain expected data\n", args->name, page_size); + } if (mmap_file) { (void)shim_memset(mappings[page], (int)n, page_size); (void)shim_msync((void *)mappings[page], page_size, ms_flags); @@ -925,6 +936,7 @@ static int stress_mmap(stress_args_t *args) (void)stress_get_setting("mmap-mlock", &context.mmap_mlock); (void)stress_get_setting("mmap-mmap2", &mmap_mmap2); (void)stress_get_setting("mmap-mprotect", &context.mmap_mprotect); + (void)stress_get_setting("mmap-write-check", &context.mmap_write_check); for (all_flags = 0, i = 0; i < SIZEOF_ARRAY(mmap_prot); i++) all_flags |= mmap_prot[i]; @@ -1064,6 +1076,7 @@ static const stress_opt_set_func_t opt_set_funcs[] = { { OPT_mmap_mprotect, stress_set_mmap_mprotect }, { OPT_mmap_odirect, stress_set_mmap_odirect }, { OPT_mmap_osync, stress_set_mmap_osync }, + { OPT_mmap_write_check, stress_set_mmap_write_check }, { 0, NULL } }; diff --git a/stress-ng.1 b/stress-ng.1 index 2fa2e77d0..880cff695 100644 --- a/stress-ng.1 +++ b/stress-ng.1 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH STRESS-NG 1 "9 December 2023" +.TH STRESS-NG 1 "18 January 2023" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -4239,6 +4239,13 @@ stop mmap stress workers after N bogo operations. .B \-\-mmap\-osync enable file based memory mapping and used O_SYNC synchronous I/O integrity completion. +.TP +.B \-\-mmap\-write\-check +write into each page a unique 64 bit check value for all pages and +then read the value for a sanity check. This will force newly memory mapped +pages to be faulted-in which slows down mmap bogo-op rate. This can also +cause lock contention on page allocation and page unmapping on systems +with many CPU threads and with cgroup memory accounting. .RE .TP .B Random memory map/unmap stressor