// SPDX-License-Identifier: GPL-2.0
/*
 * NUMA support for s390
 *
 * Implement NUMA core code.
 *
 * Copyright IBM Corp. 2015
 */

#define KMSG_COMPONENT "numa"
#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt

#include <linux/kernel.h>
#include <linux/mmzone.h>
#include <linux/cpumask.h>
#include <linux/bootmem.h>
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/node.h>

#include <asm/numa.h>
#include "numa_mode.h"

pg_data_t *node_data[MAX_NUMNODES];
EXPORT_SYMBOL(node_data);

cpumask_t node_to_cpumask_map[MAX_NUMNODES];
EXPORT_SYMBOL(node_to_cpumask_map);

static void plain_setup(void)
{
	node_set(0, node_possible_map);
}

const struct numa_mode numa_mode_plain = {
	.name = "plain",
	.setup = plain_setup,
};

static const struct numa_mode *mode = &numa_mode_plain;

int numa_pfn_to_nid(unsigned long pfn)
{
	return mode->__pfn_to_nid ? mode->__pfn_to_nid(pfn) : 0;
}

void numa_update_cpu_topology(void)
{
	if (mode->update_cpu_topology)
		mode->update_cpu_topology();
}

int __node_distance(int a, int b)
{
	return mode->distance ? mode->distance(a, b) : 0;
}

int numa_debug_enabled;

/*
 * alloc_node_data() - Allocate node data
 */
static __init pg_data_t *alloc_node_data(void)
{
	pg_data_t *res;

	res = (pg_data_t *) memblock_alloc(sizeof(pg_data_t), 8);
	memset(res, 0, sizeof(pg_data_t));
	return res;
}

/*
 * numa_setup_memory() - Assign bootmem to nodes
 *
 * The memory is first added to memblock without any respect to nodes.
 * This is fixed before remaining memblock memory is handed over to the
 * buddy allocator.
 * An important side effect is that large bootmem allocations might easily
 * cross node boundaries, which can be needed for large allocations with
 * smaller memory stripes in each node (i.e. when using NUMA emulation).
 *
 * Memory defines nodes:
 * Therefore this routine also sets the nodes online with memory.
 */
static void __init numa_setup_memory(void)
{
	unsigned long cur_base, align, end_of_dram;
	int nid = 0;

	end_of_dram = memblock_end_of_DRAM();
	align = mode->align ? mode->align() : ULONG_MAX;

	/*
	 * Step through all available memory and assign it to the nodes
	 * indicated by the mode implementation.
	 * All nodes which are seen here will be set online.
	 */
	cur_base = 0;
	do {
		nid = numa_pfn_to_nid(PFN_DOWN(cur_base));
		node_set_online(nid);
		memblock_set_node(cur_base, align, &memblock.memory, nid);
		cur_base += align;
	} while (cur_base < end_of_dram);

	/* Allocate and fill out node_data */
	for (nid = 0; nid < MAX_NUMNODES; nid++)
		NODE_DATA(nid) = alloc_node_data();

	for_each_online_node(nid) {
		unsigned long start_pfn, end_pfn;
		unsigned long t_start, t_end;
		int i;

		start_pfn = ULONG_MAX;
		end_pfn = 0;
		for_each_mem_pfn_range(i, nid, &t_start, &t_end, NULL) {
			if (t_start < start_pfn)
				start_pfn = t_start;
			if (t_end > end_pfn)
				end_pfn = t_end;
		}
		NODE_DATA(nid)->node_spanned_pages = end_pfn - start_pfn;
		NODE_DATA(nid)->node_id = nid;
	}
}

/*
 * numa_setup() - Earliest initialization
 *
 * Assign the mode and call the mode's setup routine.
 */
void __init numa_setup(void)
{
	pr_info("NUMA mode: %s\n", mode->name);
	nodes_clear(node_possible_map);
	if (mode->setup)
		mode->setup();
	numa_setup_memory();
	memblock_dump_all();
}

/*
 * numa_init_early() - Initialization initcall
 *
 * This runs when only one CPU is online and before the first
 * topology update is called for by the scheduler.
 */
static int __init numa_init_early(void)
{
	/* Attach all possible CPUs to node 0 for now. */
	cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask);
	return 0;
}
early_initcall(numa_init_early);

/*
 * numa_init_late() - Initialization initcall
 *
 * Register NUMA nodes.
 */
static int __init numa_init_late(void)
{
	int nid;

	for_each_online_node(nid)
		register_one_node(nid);
	return 0;
}
arch_initcall(numa_init_late);

static int __init parse_debug(char *parm)
{
	numa_debug_enabled = 1;
	return 0;
}
early_param("numa_debug", parse_debug);

static int __init parse_numa(char *parm)
{
	if (strcmp(parm, numa_mode_plain.name) == 0)
		mode = &numa_mode_plain;
#ifdef CONFIG_NUMA_EMU
	if (strcmp(parm, numa_mode_emu.name) == 0)
		mode = &numa_mode_emu;
#endif
	return 0;
}
early_param("numa", parse_numa);
