at v6.0-rc6 166 lines 3.5 kB view raw
1// SPDX-License-Identifier: GPL-2.0-or-later 2#include "tests/common.h" 3#include <string.h> 4#include <getopt.h> 5#include <linux/memory_hotplug.h> 6#include <linux/build_bug.h> 7 8#define INIT_MEMBLOCK_REGIONS 128 9#define INIT_MEMBLOCK_RESERVED_REGIONS INIT_MEMBLOCK_REGIONS 10#define PREFIXES_MAX 15 11#define DELIM ": " 12 13static struct test_memory memory_block; 14static const char __maybe_unused *prefixes[PREFIXES_MAX]; 15static int __maybe_unused nr_prefixes; 16 17static const char *short_opts = "mv"; 18static const struct option long_opts[] = { 19 {"movable-node", 0, NULL, 'm'}, 20 {"verbose", 0, NULL, 'v'}, 21 {NULL, 0, NULL, 0} 22}; 23 24static 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" 27 "parameter", 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." 31}; 32 33static int verbose; 34 35/* sets global variable returned by movable_node_is_enabled() stub */ 36bool movable_node_enabled; 37 38void reset_memblock_regions(void) 39{ 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; 45 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; 51} 52 53void reset_memblock_attributes(void) 54{ 55 memblock.memory.name = "memory"; 56 memblock.reserved.name = "reserved"; 57 memblock.bottom_up = false; 58 memblock.current_limit = MEMBLOCK_ALLOC_ANYWHERE; 59} 60 61void setup_memblock(void) 62{ 63 reset_memblock_regions(); 64 memblock_add((phys_addr_t)memory_block.base, MEM_SIZE); 65} 66 67void dummy_physical_memory_init(void) 68{ 69 memory_block.base = malloc(MEM_SIZE); 70 assert(memory_block.base); 71} 72 73void dummy_physical_memory_cleanup(void) 74{ 75 free(memory_block.base); 76} 77 78static void usage(const char *prog) 79{ 80 BUILD_BUG_ON(ARRAY_SIZE(help_opts) != ARRAY_SIZE(long_opts) - 1); 81 82 printf("Usage: %s [-%s]\n", prog, short_opts); 83 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]); 87 } 88 89 exit(1); 90} 91 92void parse_args(int argc, char **argv) 93{ 94 int c; 95 96 while ((c = getopt_long_only(argc, argv, short_opts, long_opts, 97 NULL)) != -1) { 98 switch (c) { 99 case 'm': 100 movable_node_enabled = true; 101 break; 102 case 'v': 103 verbose = 1; 104 break; 105 default: 106 usage(argv[0]); 107 } 108 } 109} 110 111void print_prefixes(const char *postfix) 112{ 113 for (int i = 0; i < nr_prefixes; i++) 114 test_print("%s%s", prefixes[i], DELIM); 115 test_print(postfix); 116} 117 118void test_fail(void) 119{ 120 if (verbose) { 121 ksft_test_result_fail(": "); 122 print_prefixes("failed\n"); 123 } 124} 125 126void test_pass(void) 127{ 128 if (verbose) { 129 ksft_test_result_pass(": "); 130 print_prefixes("passed\n"); 131 } 132} 133 134void test_print(const char *fmt, ...) 135{ 136 if (verbose) { 137 int saved_errno = errno; 138 va_list args; 139 140 va_start(args, fmt); 141 errno = saved_errno; 142 vprintf(fmt, args); 143 va_end(args); 144 } 145} 146 147void prefix_reset(void) 148{ 149 memset(prefixes, 0, PREFIXES_MAX * sizeof(char *)); 150 nr_prefixes = 0; 151} 152 153void prefix_push(const char *prefix) 154{ 155 assert(nr_prefixes < PREFIXES_MAX); 156 prefixes[nr_prefixes] = prefix; 157 nr_prefixes++; 158} 159 160void prefix_pop(void) 161{ 162 if (nr_prefixes > 0) { 163 prefixes[nr_prefixes - 1] = 0; 164 nr_prefixes--; 165 } 166}