Commit 254b2fd0 authored by Heiko Carstens's avatar Heiko Carstens Committed by Alexander Gordeev
Browse files

s390/mm: provide minimal setup_per_cpu_areas() implementation



s390 allows to enable CONFIG_NUMA, mainly to enable a couple of system
calls which are only present if NUMA is enabled. The NUMA specific system
calls are required by a couple of applications, which wouldn't work if the
system calls wouldn't be present.

The NUMA implementation itself maps all CPUs and memory to node 0. A
special case is the generic percpu setup code, which doesn't expect an s390
like implementation and therefore emits a message/warning:
"percpu: cpu 0 has no node -1 or node-local memory".

In order to get rid of this message, and also to provide sane CPU to node
and CPU distance mappings implement a minimal setup_per_cpu_areas()
function, which is very close to the generic variant.

Signed-off-by: default avatarHeiko Carstens <hca@linux.ibm.com>
Signed-off-by: default avatarAlexander Gordeev <agordeev@linux.ibm.com>
parent 2e71df94
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -197,6 +197,7 @@ config S390
	select HAVE_RSEQ
	select HAVE_SAMPLE_FTRACE_DIRECT
	select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
	select HAVE_SETUP_PER_CPU_AREA
	select HAVE_SOFTIRQ_ON_OWN_STACK
	select HAVE_SYSCALL_TRACEPOINTS
	select HAVE_VIRT_CPU_ACCOUNTING
@@ -208,6 +209,7 @@ config S390
	select MMU_GATHER_MERGE_VMAS
	select MODULES_USE_ELF_RELA
	select NEED_DMA_MAP_STATE	if PCI
	select NEED_PER_CPU_EMBED_FIRST_CHUNK
	select NEED_SG_DMA_LENGTH	if PCI
	select OLD_SIGACTION
	select OLD_SIGSUSPEND3
+36 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@
#include <linux/cma.h>
#include <linux/gfp.h>
#include <linux/dma-direct.h>
#include <linux/percpu.h>
#include <asm/processor.h>
#include <linux/uaccess.h>
#include <asm/pgalloc.h>
@@ -222,6 +223,41 @@ unsigned long memory_block_size_bytes(void)
	return max_t(unsigned long, MIN_MEMORY_BLOCK_SIZE, sclp.rzm);
}

unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(__per_cpu_offset);

static int __init pcpu_cpu_distance(unsigned int from, unsigned int to)
{
	return LOCAL_DISTANCE;
}

static int __init pcpu_cpu_to_node(int cpu)
{
	return 0;
}

void __init setup_per_cpu_areas(void)
{
	unsigned long delta;
	unsigned int cpu;
	int rc;

	/*
	 * Always reserve area for module percpu variables.  That's
	 * what the legacy allocator did.
	 */
	rc = pcpu_embed_first_chunk(PERCPU_MODULE_RESERVE,
				    PERCPU_DYNAMIC_RESERVE, PAGE_SIZE,
				    pcpu_cpu_distance,
				    pcpu_cpu_to_node);
	if (rc < 0)
		panic("Failed to initialize percpu areas.");

	delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
	for_each_possible_cpu(cpu)
		__per_cpu_offset[cpu] = delta + pcpu_unit_offsets[cpu];
}

#ifdef CONFIG_MEMORY_HOTPLUG

#ifdef CONFIG_CMA