diff options
Diffstat (limited to 'mm/numa_memblks.c')
-rw-r--r-- | mm/numa_memblks.c | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/mm/numa_memblks.c b/mm/numa_memblks.c index e3c3519725d4..7749b6f6b250 100644 --- a/mm/numa_memblks.c +++ b/mm/numa_memblks.c @@ -415,6 +415,47 @@ int __init numa_register_meminfo(struct numa_meminfo *mi) return 0; } +int __init numa_memblks_init(int (*init_func)(void), + bool memblock_force_top_down) +{ + int ret; + + nodes_clear(numa_nodes_parsed); + nodes_clear(node_possible_map); + nodes_clear(node_online_map); + memset(&numa_meminfo, 0, sizeof(numa_meminfo)); + WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.memory, + NUMA_NO_NODE)); + WARN_ON(memblock_set_node(0, ULLONG_MAX, &memblock.reserved, + NUMA_NO_NODE)); + /* In case that parsing SRAT failed. */ + WARN_ON(memblock_clear_hotplug(0, ULLONG_MAX)); + numa_reset_distance(); + + ret = init_func(); + if (ret < 0) + return ret; + + /* + * We reset memblock back to the top-down direction + * here because if we configured ACPI_NUMA, we have + * parsed SRAT in init_func(). It is ok to have the + * reset here even if we did't configure ACPI_NUMA + * or acpi numa init fails and fallbacks to dummy + * numa init. + */ + if (memblock_force_top_down) + memblock_set_bottom_up(false); + + ret = numa_cleanup_meminfo(&numa_meminfo); + if (ret < 0) + return ret; + + numa_emulation(&numa_meminfo, numa_distance_cnt); + + return numa_register_meminfo(&numa_meminfo); +} + static int __init cmp_memblk(const void *a, const void *b) { const struct numa_memblk *ma = *(const struct numa_memblk **)a; |