Skip to content

Commit

Permalink
stress-mmaptorture: add --mmaptorture-bytes option
Browse files Browse the repository at this point in the history
Add option to specify mmap size shared by all the mmaptorture
instances.

Signed-off-by: Colin Ian King <[email protected]>
  • Loading branch information
ColinIanKing committed Feb 17, 2025
1 parent 27e9c4b commit c971be9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 24 deletions.
1 change: 1 addition & 0 deletions core-opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ const struct option stress_long_options[] = {
{ "mmapmany-numa", 0, 0, OPT_mmapmany_numa },
{ "mmapmany-ops", 1, 0, OPT_mmapmany_ops },
{ "mmaptorture", 1, 0, OPT_mmaptorture },
{ "mmaptorture-bytes", 1, 0, OPT_mmaptorture_bytes },
{ "mmaptorture-ops", 1, 0, OPT_mmaptorture_ops },
{ "module", 1, 0, OPT_module},
{ "module-ops", 1, 0, OPT_module_ops },
Expand Down
1 change: 1 addition & 0 deletions core-opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -916,6 +916,7 @@ typedef enum {
OPT_mmapmany_ops,

OPT_mmaptorture,
OPT_mmaptorture_bytes,
OPT_mmaptorture_ops,

OPT_module,
Expand Down
73 changes: 50 additions & 23 deletions stress-mmaptorture.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

static const stress_help_t help[] = {
{ NULL, "mmaptorture N", "start N workers torturing page mappings" },
{ NULL, "mmaptorture-bytes N", "size of file backed region to be memory mapped" },
{ NULL, "mmaptorture-ops N", "stop after N mmaptorture bogo operations" },
{ NULL, NULL, NULL }
};
Expand All @@ -33,18 +34,23 @@ typedef struct {
size_t size;
} mmap_info_t;

#define MMAP_MAX (128)
#define MMAP_PAGES_MAX (1024)
#define MMAP_SIZE_MAP (4) /* in pages */
#define MMAP_MAPPINGS_MAX (128)
#define MMAP_SIZE_MAP (4) /* in pages */

#define PAGE_WR_FLAG (0x01)
#define PAGE_RD_FLAG (0x02)
#define PAGE_WR_FLAG (0x01)
#define PAGE_RD_FLAG (0x02)

#define MIN_MMAPTORTURE_BYTES (16 * MB)
#define MAX_MMAPTORTURE_BYTES (MAX_MEM_LIMIT)
#define DEFAULT_MMAPTORTURE_BYTES (1024 * 4096)

static sigjmp_buf jmp_env;

static int mmap_fd;
const char *name = "mmaptorture";
uint8_t *mmap_data;
static const char *name = "mmaptorture";
static uint8_t *mmap_data;
static size_t mmap_bytes = DEFAULT_MMAPTORTURE_BYTES;
static bool mmap_bytes_adjusted = false;

#if defined(HAVE_MADVISE)
static const int madvise_options[] = {
Expand Down Expand Up @@ -221,10 +227,20 @@ static void stress_mmaptorture_init(const uint32_t num_instances)
{
char path[PATH_MAX];
const pid_t pid = getpid();
const size_t len = MMAP_PAGES_MAX * stress_get_page_size();
const size_t page_size = stress_get_page_size();

(void)num_instances;

mmap_bytes = DEFAULT_MMAPTORTURE_BYTES;
stress_get_setting("mmaptorture-bytes", &mmap_bytes);

mmap_bytes = (num_instances < 1) ? mmap_bytes : mmap_bytes / num_instances;
mmap_bytes &= ~(page_size - 1);
if (mmap_bytes < page_size * MMAP_SIZE_MAP * 2) {
mmap_bytes = (page_size * MMAP_SIZE_MAP * 2);
mmap_bytes_adjusted = true;
}

if (stress_temp_dir_mk(name, pid, 0) < 0) {
mmap_fd = -1;
return;
Expand All @@ -238,18 +254,16 @@ static void stress_mmaptorture_init(const uint32_t num_instances)
}
(void)unlink(path);

VOID_RET(int, ftruncate(mmap_fd, len));
mmap_data = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, 0);
VOID_RET(int, ftruncate(mmap_fd, mmap_bytes));
mmap_data = mmap(NULL, mmap_bytes, PROT_READ | PROT_WRITE, MAP_SHARED, mmap_fd, 0);
}

static void stress_mmaptorture_deinit(void)
{
const size_t len = MMAP_PAGES_MAX * stress_get_page_size();

if (mmap_fd == -1)
return;
if (mmap_data != MAP_FAILED)
(void)munmap((void *)mmap_data, len);
(void)munmap((void *)mmap_data, mmap_bytes);
(void)stress_temp_dir_rm(name, getpid(), 0);
}

Expand Down Expand Up @@ -277,12 +291,12 @@ static void stress_mmaptorture_msync(uint8_t *addr, const size_t length, const s
static int stress_mmaptorture_child(stress_args_t *args, void *context)
{
const size_t page_size = args->page_size;
const size_t page_mask = ~(page_size - 1);
NOCLOBBER mmap_info_t *mappings;
#if defined(HAVE_LINUX_MEMPOLICY_H)
NOCLOBBER stress_numa_mask_t *numa_mask = NULL;
#endif
size_t i;

(void)context;

if (sigsetjmp(jmp_env, 1)) {
Expand All @@ -295,7 +309,7 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)
if (stress_sighandler(args->name, SIGSEGV, stress_mmaptorture_sighandler, NULL) < 0)
return EXIT_NO_RESOURCE;

mappings = (mmap_info_t *)calloc((size_t)MMAP_MAX, sizeof(*mappings));
mappings = (mmap_info_t *)calloc((size_t)MMAP_MAPPINGS_MAX, sizeof(*mappings));
if (UNLIKELY(!mappings)) {
pr_fail("%s: calloc failed, out of memory\n", args->name);
return EXIT_NO_RESOURCE;
Expand All @@ -305,7 +319,7 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)
if (stress_numa_nodes() > 0)
numa_mask = stress_numa_mask_alloc();
#endif
for (i = 0; i < MMAP_MAX; i++) {
for (i = 0; i < MMAP_MAPPINGS_MAX; i++) {
mappings[i].addr = MAP_FAILED;
mappings[i].size = 0;
}
Expand All @@ -322,8 +336,7 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)

VOID_RET(int, ftruncate(mmap_fd, 0));

offset = page_size * stress_mwc16modn(MMAP_PAGES_MAX);

offset = stress_mwc64modn((uint64_t)mmap_bytes) & page_mask;
if (lseek(mmap_fd, offset, SEEK_SET) == offset) {
char data[page_size];

Expand All @@ -333,16 +346,16 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)
volatile uint8_t *vptr = (volatile uint8_t *)(mmap_data + offset);

(*vptr)++;
stress_mmaptorture_msync(mmap_data, MMAP_PAGES_MAX * page_size, page_size);
stress_mmaptorture_msync(mmap_data, mmap_bytes, page_size);
}
}
#if defined(HAVE_REMAP_FILE_PAGES) && \
!defined(STRESS_ARCH_SPARC)
(void)remap_file_pages(mmap_data, MMAP_PAGES_MAX * page_size, PROT_NONE, 0, MAP_SHARED | MAP_NONBLOCK);
(void)mprotect(mmap_data, MMAP_PAGES_MAX * page_size, PROT_READ | PROT_WRITE);
(void)remap_file_pages(mmap_data, mmap_bytes, PROT_NONE, 0, MAP_SHARED | MAP_NONBLOCK);
(void)mprotect(mmap_data, mmap_bytes, PROT_READ | PROT_WRITE);
#endif

for (n = 0; n < MMAP_MAX; n++) {
for (n = 0; n < MMAP_MAPPINGS_MAX; n++) {
int flag = 0;
#if defined(HAVE_MADVISE)
const int madvise_option = madvise_options[stress_mwc8modn(SIZEOF_ARRAY(madvise_options))];
Expand All @@ -359,7 +372,7 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)
break;

mmap_size = page_size * (1 + stress_mwc8modn(MMAP_SIZE_MAP));
offset = page_size * stress_mwc16modn(MMAP_PAGES_MAX);
offset = stress_mwc64modn((uint64_t)mmap_bytes) & page_mask;
#if defined(HAVE_FALLOCATE)
#if defined(FALLOC_FL_PUNCH_HOLE) && \
defined(FALLOC_FL_KEEP_SIZE)
Expand Down Expand Up @@ -523,18 +536,32 @@ static int stress_mmaptorture_child(stress_args_t *args, void *context)
*/
static int stress_mmaptorture(stress_args_t *args)
{
if (args->instance == 0) {
char str1[64], str2[64];

stress_uint64_to_str(str1, sizeof(str1), (uint64_t)mmap_bytes);
stress_uint64_to_str(str2, sizeof(str2), (uint64_t)mmap_bytes * args->num_instances);

pr_inf("%s: using %smmap'd size %s per stressor (total %s)\n", args->name,
mmap_bytes_adjusted ? "adjusted " : "", str1, str2);
}
stress_set_proc_state(args->name, STRESS_STATE_SYNC_WAIT);
stress_sync_start_wait(args);
stress_set_proc_state(args->name, STRESS_STATE_RUN);

return stress_oomable_child(args, NULL, stress_mmaptorture_child, STRESS_OOMABLE_NORMAL);
}

static const stress_opt_t opts[] = {
{ OPT_mmaptorture_bytes, "mmaptorture-bytes", TYPE_ID_SIZE_T_BYTES_VM, MIN_MMAPTORTURE_BYTES, MAX_MMAPTORTURE_BYTES, NULL },
};

const stressor_info_t stress_mmaptorture_info = {
.stressor = stress_mmaptorture,
.class = CLASS_VM | CLASS_OS,
.verify = VERIFY_NONE,
.init = stress_mmaptorture_init,
.deinit = stress_mmaptorture_deinit,
.opts = opts,
.help = help
};
7 changes: 6 additions & 1 deletion stress-ng.1
Original file line number Diff line number Diff line change
Expand Up @@ -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 "16 February 2025"
.TH STRESS-NG 1 "17 February 2025"
.\" Please adjust this date whenever revising the manpage.
.\"
.\" Some roff macros, for reference:
Expand Down Expand Up @@ -5269,6 +5269,11 @@ file. For NUMA systems, pages are randomly placed across NUMA nodes. All this
activity causes cache misses, exercises the TLB and causes IPI interrupts between
CPUs.
.TP
.B \-\-mmaptorture\-bytes N
allocate N bytes in total for all the mmaptorture stressor instances, the default is
16 MB. One can specify the size as % of total available memory or in units of
Bytes, KBytes, MBytes and GBytes using the suffix b, k, m or g.
.TP
.B \-\-mmaptorture\-ops N
stop after N iterations of memory mapping torture operations.
.RE
Expand Down

0 comments on commit c971be9

Please sign in to comment.