static int stress_mremap_child( const args_t *args, const size_t sz, size_t new_sz, const size_t page_size, const size_t mremap_bytes, int *flags) { do { uint8_t *buf = NULL; size_t old_sz; if (!g_keep_stressing_flag) break; buf = mmap(NULL, new_sz, PROT_READ | PROT_WRITE, *flags, -1, 0); if (buf == MAP_FAILED) { /* Force MAP_POPULATE off, just in case */ #if defined(MAP_POPULATE) *flags &= ~MAP_POPULATE; #endif continue; /* Try again */ } (void)madvise_random(buf, new_sz); (void)mincore_touch_pages(buf, mremap_bytes); /* Ensure we can write to the mapped pages */ if (g_opt_flags & OPT_FLAGS_VERIFY) { mmap_set(buf, new_sz, page_size); if (mmap_check(buf, sz, page_size) < 0) { pr_fail("%s: mmap'd region of %zu " "bytes does not contain expected data\n", args->name, sz); (void)munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; while (new_sz > page_size) { if (try_remap(args, &buf, old_sz, new_sz) < 0) { (void)munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); if (g_opt_flags & OPT_FLAGS_VERIFY) { if (mmap_check(buf, new_sz, page_size) < 0) { pr_fail("%s: mremap'd region " "of %zu bytes does " "not contain expected data\n", args->name, sz); (void)munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; } new_sz <<= 1; while (new_sz < mremap_bytes) { if (try_remap(args, &buf, old_sz, new_sz) < 0) { (void)munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); old_sz = new_sz; new_sz <<= 1; } (void)munmap(buf, old_sz); inc_counter(args); } while (keep_stressing()); return EXIT_SUCCESS; }
/* * stress_mremap() * stress mmap */ int stress_mremap( uint64_t *const counter, const uint32_t instance, const uint64_t max_ops, const char *name) { uint8_t *buf = NULL; const size_t page_size = stress_get_pagesize(); size_t sz, new_sz, old_sz; int flags = MAP_PRIVATE | MAP_ANONYMOUS; (void)instance; #ifdef MAP_POPULATE flags |= MAP_POPULATE; #endif if (!set_mremap_bytes) { if (opt_flags & OPT_FLAGS_MAXIMIZE) opt_mremap_bytes = MAX_MREMAP_BYTES; if (opt_flags & OPT_FLAGS_MINIMIZE) opt_mremap_bytes = MIN_MREMAP_BYTES; } new_sz = sz = opt_mremap_bytes & ~(page_size - 1); /* Make sure this is killable by OOM killer */ set_oom_adjustment(name, true); do { if (!opt_do_run) break; buf = mmap(NULL, new_sz, PROT_READ | PROT_WRITE, flags, -1, 0); if (buf == MAP_FAILED) { /* Force MAP_POPULATE off, just in case */ #ifdef MAP_POPULATE flags &= ~MAP_POPULATE; #endif continue; /* Try again */ } (void)madvise_random(buf, new_sz); (void)mincore_touch_pages(buf, opt_mremap_bytes); /* Ensure we can write to the mapped pages */ if (opt_flags & OPT_FLAGS_VERIFY) { stress_mremap_set(buf, new_sz, page_size); if (stress_mremap_check(buf, sz, page_size) < 0) { pr_fail(stderr, "%s: mmap'd region of %zu " "bytes does not contain expected data\n", name, sz); munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; while (new_sz > page_size) { if (try_remap(name, &buf, old_sz, new_sz) < 0) { munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); if (opt_flags & OPT_FLAGS_VERIFY) { if (stress_mremap_check(buf, new_sz, page_size) < 0) { pr_fail(stderr, "%s: mremap'd region " "of %zu bytes does " "not contain expected data\n", name, sz); munmap(buf, new_sz); return EXIT_FAILURE; } } old_sz = new_sz; new_sz >>= 1; } new_sz <<= 1; while (new_sz < opt_mremap_bytes) { if (try_remap(name, &buf, old_sz, new_sz) < 0) { munmap(buf, old_sz); return EXIT_FAILURE; } (void)madvise_random(buf, new_sz); old_sz = new_sz; new_sz <<= 1; } (void)munmap(buf, old_sz); (*counter)++; } while (opt_do_run && (!max_ops || *counter < max_ops)); return EXIT_SUCCESS; }