1 // SPDX-License-Identifier: GPL-2.0-or-later
2 #include "tests/common.h"
5 #include <linux/memory_hotplug.h>
6 #include <linux/build_bug.h>
8 #define INIT_MEMBLOCK_REGIONS 128
9 #define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS
10 #define PREFIXES_MAX 15
13 static struct test_memory memory_block;
14 static const char __maybe_unused *prefixes[PREFIXES_MAX];
15 static int __maybe_unused nr_prefixes;
17 static const char *short_opts = "mv";
18 static const struct option long_opts[] = {
19 {"movable-node", 0, NULL, 'm'},
20 {"verbose", 0, NULL, 'v'},
24 static const char * const help_opts[] = {
25 "disallow allocations from regions marked as hotplugged\n\t\t\t"
26 "by simulating enabling the \"movable_node\" kernel\n\t\t\t"
28 "enable verbose output, which includes the name of the\n\t\t\t"
29 "memblock function being tested, the name of the test,\n\t\t\t"
30 "and whether the test passed or failed."
35 /* sets global variable returned by movable_node_is_enabled() stub */
36 bool movable_node_enabled;
38 void reset_memblock_regions(void)
40 memset(memblock.memory.regions, 0,
41 memblock.memory.cnt * sizeof(struct memblock_region));
42 memblock.memory.cnt = 1;
43 memblock.memory.max = INIT_MEMBLOCK_REGIONS;
44 memblock.memory.total_size = 0;
46 memset(memblock.reserved.regions, 0,
47 memblock.reserved.cnt * sizeof(struct memblock_region));
48 memblock.reserved.cnt = 1;
49 memblock.reserved.max = INIT_MEMBLOCK_RESERVED_REGIONS;
50 memblock.reserved.total_size = 0;
53 void reset_memblock_attributes(void)
55 memblock.memory.name = "memory";
56 memblock.reserved.name = "reserved";
57 memblock.bottom_up = false;
58 memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE;
61 void setup_memblock(void)
63 reset_memblock_regions();
64 memblock_add((phys_addr_t)memory_block.base, MEM_SIZE);
67 void dummy_physical_memory_init(void)
69 memory_block.base = malloc(MEM_SIZE);
70 assert(memory_block.base);
73 void dummy_physical_memory_cleanup(void)
75 free(memory_block.base);
78 static void usage(const char *prog)
80 BUILD_BUG_ON(ARRAY_SIZE(help_opts) != ARRAY_SIZE(long_opts) - 1);
82 printf("Usage: %s [-%s]\n", prog, short_opts);
84 for (int i = 0; long_opts[i].name; i++) {
85 printf(" -%c, --%-12s\t%s\n", long_opts[i].val,
86 long_opts[i].name, help_opts[i]);
92 void parse_args(int argc, char **argv)
96 while ((c = getopt_long_only(argc, argv, short_opts, long_opts,
100 movable_node_enabled = true;
111 void print_prefixes(const char *postfix)
113 for (int i = 0; i < nr_prefixes; i++)
114 test_print("%s%s", prefixes[i], DELIM);
121 ksft_test_result_fail(": ");
122 print_prefixes("failed\n");
129 ksft_test_result_pass(": ");
130 print_prefixes("passed\n");
134 void test_print(const char *fmt, ...)
137 int saved_errno = errno;
147 void prefix_reset(void)
149 memset(prefixes, 0, PREFIXES_MAX * sizeof(char *));
153 void prefix_push(const char *prefix)
155 assert(nr_prefixes < PREFIXES_MAX);
156 prefixes[nr_prefixes] = prefix;
160 void prefix_pop(void)
162 if (nr_prefixes > 0) {
163 prefixes[nr_prefixes - 1] = 0;