Skip to content

Commit

Permalink
stress-pagemove: add --pagemove-numa option
Browse files Browse the repository at this point in the history
Add option to try to bind mmap'd memory across NUMA nodes for
more page stressing

Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
  • Loading branch information
ColinIanKing committed Jan 22, 2025
1 parent c118c1c commit e5e6612
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 0 deletions.
1 change: 1 addition & 0 deletions core-opts.c
Original file line number Diff line number Diff line change
Expand Up @@ -707,6 +707,7 @@ const struct option stress_long_options[] = {
{ "pagemove", 1, 0, OPT_pagemove },
{ "pagemove-bytes", 1, 0, OPT_pagemove_bytes },
{ "pagemove-mlock", 0, 0, OPT_pagemove_mlock },
{ "pagemove-numa", 0, 0, OPT_pagemove_numa },
{ "pagemove-ops", 1, 0, OPT_pagemove_ops },
{ "pageswap", 1, 0, OPT_pageswap },
{ "pageswap-ops", 1, 0, OPT_pageswap_ops },
Expand Down
1 change: 1 addition & 0 deletions core-opts.h
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,7 @@ typedef enum {
OPT_pagemove,
OPT_pagemove_bytes,
OPT_pagemove_mlock,
OPT_pagemove_numa,
OPT_pagemove_ops,

OPT_pageswap,
Expand Down
4 changes: 4 additions & 0 deletions stress-ng.1
Original file line number Diff line number Diff line change
Expand Up @@ -5851,6 +5851,10 @@ MBytes and GBytes using the suffix b, k, m or g.
attempt to mlock mmap'd and mremap'd pages into memory causing more memory pressure by
preventing pages from swapped out.
.TP
.B \-\-pagemove\-numa
assign memory mapped pages to randomly selected NUMA nodes. This is disabled
for systems that do not support NUMA or have less than 2 NUMA nodes.
.TP
.B \-\-pagemove\-ops N
stop after N pagemove shuffling operations, where suffling all the pages in
the mmap'd region is equivalent to 1 bogo-operation.
Expand Down
55 changes: 55 additions & 0 deletions stress-pagemove.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*
*/
#include "stress-ng.h"
#include "core-numa.h"
#include "core-out-of-memory.h"

#define DEFAULT_PAGE_MOVE_BYTES (4 * MB)
Expand All @@ -27,6 +28,7 @@ static const stress_help_t help[] = {
{ NULL, "pagemove N", "start N workers that shuffle move pages" },
{ NULL, "pagemove-bytes N", "size of mmap'd region to exercise page moving in bytes" },
{ NULL, "pagemove-mlock", "attempt to mlock pages into memory" },
{ NULL, "pagemove-numa", "bind memory mappings to randomly selected NUMA nodes" },
{ NULL, "pagemove-ops N", "stop after N page move bogo operations" },
{ NULL, NULL, NULL }
};
Expand All @@ -39,6 +41,7 @@ typedef struct {
static const stress_opt_t opts[] = {
{ OPT_pagemove_bytes, "pagemove-bytes", TYPE_ID_SIZE_T_BYTES_VM, MIN_PAGE_MOVE_BYTES, MAX_PAGE_MOVE_BYTES, NULL },
{ OPT_pagemove_mlock, "pagemove-mlock", TYPE_ID_BOOL, 0, 1, NULL },
{ OPT_pagemove_numa, "pagemove-numa", TYPE_ID_BOOL, 0, 1, NULL },
END_OPT,
};

Expand Down Expand Up @@ -69,10 +72,34 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
double duration = 0.0, count = 0.0, rate;
int metrics_count = 0;
bool pagemove_mlock = false;
bool pagemove_numa = false;
#if defined(HAVE_LINUX_MEMPOLICY_H)
stress_numa_mask_t *numa_mask = NULL;
#endif

(void)context;

(void)stress_get_setting("pagemove-mlock", &pagemove_mlock);
(void)stress_get_setting("pagemove-numa", &pagemove_numa);

if (pagemove_numa) {
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (stress_numa_nodes() > 1) {
numa_mask = stress_numa_mask_alloc();
} else {
if (args->instance == 0) {
pr_inf("%s: only 1 NUMA node available, disabling --pagemove-numa\n",
args->name);
pagemove_numa = false;
}
}
#else
if (args->instance == 0)
pr_inf("%s: --pagemove-numa selected but not supported by this system, disabling option\n",
args->name);
pagemove_numa = false;
#endif
}

if (!stress_get_setting("pagemove-bytes", &pagemove_bytes)) {
if (g_opt_flags & OPT_FLAGS_MAXIMIZE)
Expand Down Expand Up @@ -152,6 +179,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, ptr, unmapped_page);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr1, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr1, page_size);

Expand All @@ -161,6 +192,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, ptr + page_size, ptr);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr2, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr2, page_size);

Expand All @@ -170,6 +205,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, remap_addr1, ptr + page_size);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr3, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr3, page_size);
} else {
Expand All @@ -186,6 +225,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, ptr, unmapped_page);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr1, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr1, page_size);

Expand All @@ -199,6 +242,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, ptr + page_size, ptr);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr2, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr2, page_size);

Expand All @@ -212,6 +259,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
stress_pagemove_remap_fail(args, remap_addr1, ptr + page_size);
goto fail;
}
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_randomize_pages(numa_mask, remap_addr3, page_size, page_size);
#endif
if (pagemove_mlock)
(void)shim_mlock(remap_addr3, page_size);
}
Expand All @@ -233,6 +284,10 @@ static int stress_pagemove_child(stress_args_t *args, void *context)
fail:
stress_set_proc_state(args->name, STRESS_STATE_DEINIT);
(void)munmap((void *)buf, sz);
#if defined(HAVE_LINUX_MEMPOLICY_H)
if (pagemove_numa)
stress_numa_mask_free(numa_mask);
#endif

rate = (duration > 0.0) ? count / duration : 0.0;
stress_metrics_set(args, 0, "page remaps per sec",
Expand Down

0 comments on commit e5e6612

Please sign in to comment.