1
0
Files
kernel-49/arch/s390/numa/numa.c
Greg Kroah-Hartman 90f2be6c18 Merge 4.9.141 into android-4.9
Changes in 4.9.141
	cifs: don't dereference smb_file_target before null check
	reiserfs: propagate errors from fill_with_dentries() properly
	hfs: prevent btree data loss on root split
	hfsplus: prevent btree data loss on root split
	um: Give start_idle_thread() a return code
	drm/edid: Add 6 bpc quirk for BOE panel.
	platform/x86: intel_telemetry: report debugfs failure
	clk: fixed-rate: fix of_node_get-put imbalance
	fs/exofs: fix potential memory leak in mount option parsing
	clk: samsung: exynos5420: Enable PERIS clocks for suspend
	platform/x86: acerhdf: Add BIOS entry for Gateway LT31 v1.3307
	arm64: percpu: Initialize ret in the default case
	s390/vdso: add missing FORCE to build targets
	netfilter: ipset: actually allow allowable CIDR 0 in hash:net,port,net
	s390/mm: Fix ERROR: "__node_distance" undefined!
	netfilter: ipset: Correct rcu_dereference() call in ip_set_put_comment()
	netfilter: xt_IDLETIMER: add sysfs filename checking routine
	s390/qeth: fix HiperSockets sniffer
	hwmon: (ibmpowernv) Remove bogus __init annotations
	clk: fixed-factor: fix of_node_get-put imbalance
	lib/raid6: Fix arm64 test build
	qed: Fix memory/entry leak in qed_init_sp_request()
	qed: Fix blocking/unlimited SPQ entries leak
	zram: close udev startup race condition as default groups
	SUNRPC: drop pointless static qualifier in xdr_get_next_encode_buffer()
	gfs2: Put bitmap buffers in put_super
	ACPI / watchdog: Prefer iTCO_wdt on Lenovo Z50-70
	ACPI / watchdog: Prefer iTCO_wdt always when WDAT table uses RTC SRAM
	btrfs: Enhance btrfs_trim_fs function to handle error better
	btrfs: Ensure btrfs_trim_fs can trim the whole filesystem
	btrfs: fix pinned underflow after transaction aborted
	Revert "media: videobuf2-core: don't call memop 'finish' when queueing"
	Revert "Bluetooth: h5: Fix missing dependency on BT_HCIUART_SERDEV"
	media: v4l: event: Add subscription to list before calling "add" operation
	uio: Fix an Oops on load
	usb: cdc-acm: add entry for Hiro (Conexant) modem
	USB: quirks: Add no-lpm quirk for Raydium touchscreens
	usb: quirks: Add delay-init quirk for Corsair K70 LUX RGB
	misc: atmel-ssc: Fix section annotation on atmel_ssc_get_driver_data
	USB: misc: appledisplay: add 20" Apple Cinema Display
	drivers/misc/sgi-gru: fix Spectre v1 vulnerability
	ACPI / platform: Add SMB0001 HID to forbidden_id_list
	new helper: uaccess_kernel()
	HID: uhid: forbid UHID_CREATE under KERNEL_DS or elevated privileges
	libceph: fall back to sendmsg for slab pages
	Linux 4.9.141

Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
2019-02-11 22:57:43 +03:00

178 lines
3.9 KiB
C

/*
* 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;
}
EXPORT_SYMBOL(__node_distance);
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);
/* Initially attach all possible CPUs to node 0. */
cpumask_copy(&node_to_cpumask_map[0], cpu_possible_mask);
if (mode->setup)
mode->setup();
numa_setup_memory();
memblock_dump_all();
}
/*
* 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);