Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cb2fe060 authored by Helge Deller's avatar Helge Deller Committed by Gerrit - the friendly Code Review server
Browse files

parisc: Switch from DISCONTIGMEM to SPARSEMEM



The commit 1c30844d2dfe ("mm: reclaim small amounts of memory when an
external fragmentation event occurs") breaks memory management on a
parisc c8000 workstation with this memory layout:

	0) Start 0x0000000000000000 End 0x000000003fffffff Size   1024 MB
	1) Start 0x0000000100000000 End 0x00000001bfdfffff Size   3070 MB
	2) Start 0x0000004040000000 End 0x00000040ffffffff Size   3072 MB

With the patch 1c30844d2dfe, the kernel will incorrectly reclaim the
first zone when it fills up, ignoring the fact that there are two
completely free zones. Basiscally, it limits cache size to 1GiB.

The parisc kernel is currently using the DISCONTIGMEM implementation,
but isn't NUMA. Avoid this issue or strange work-arounds by switching to
the more commonly used SPARSEMEM implementation.

Change-Id: I29e215673497c122e999000ec1453a7942d8ad0c
Reported-by: default avatarMikulas Patocka <mpatocka@redhat.com>
Fixes: 1c30844d2dfe ("mm: reclaim small amounts of memory when an external fragmentation event occurs")
Signed-off-by: default avatarHelge Deller <deller@gmx.de>
Git-commit: dbdf0760990583649bfaca75fd98f76afd5f3905
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git


Signed-off-by: default avatarVinayak Menon <vinmenon@codeaurora.org>
parent 3df2190b
Loading
Loading
Loading
Loading
+4 −8
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ config PARISC
	select GENERIC_STRNCPY_FROM_USER
	select SYSCTL_ARCH_UNALIGN_ALLOW
	select SYSCTL_EXCEPTION_TRACE
	select ARCH_DISCARD_MEMBLOCK
	select HAVE_MOD_ARCH_SPECIFIC
	select VIRT_TO_BUS
	select MODULES_USE_ELF_RELA
@@ -311,21 +312,16 @@ config ARCH_SELECT_MEMORY_MODEL
	def_bool y
	depends on 64BIT

config ARCH_DISCONTIGMEM_ENABLE
config ARCH_SPARSEMEM_ENABLE
	def_bool y
	depends on 64BIT

config ARCH_FLATMEM_ENABLE
	def_bool y

config ARCH_DISCONTIGMEM_DEFAULT
config ARCH_SPARSEMEM_DEFAULT
	def_bool y
	depends on ARCH_DISCONTIGMEM_ENABLE

config NODES_SHIFT
	int
	default "3"
	depends on NEED_MULTIPLE_NODES
	depends on ARCH_SPARSEMEM_ENABLE

source "kernel/Kconfig.hz"

+1 −57
Original line number Diff line number Diff line
@@ -2,62 +2,6 @@
#ifndef _PARISC_MMZONE_H
#define _PARISC_MMZONE_H

#define MAX_PHYSMEM_RANGES 8 /* Fix the size for now (current known max is 3) */
#define MAX_PHYSMEM_RANGES 4 /* Fix the size for now (current known max is 3) */

#ifdef CONFIG_DISCONTIGMEM

extern int npmem_ranges;

struct node_map_data {
    pg_data_t pg_data;
};

extern struct node_map_data node_data[];

#define NODE_DATA(nid)          (&node_data[nid].pg_data)

/* We have these possible memory map layouts:
 * Astro: 0-3.75, 67.75-68, 4-64
 * zx1: 0-1, 257-260, 4-256
 * Stretch (N-class): 0-2, 4-32, 34-xxx
 */

/* Since each 1GB can only belong to one region (node), we can create
 * an index table for pfn to nid lookup; each entry in pfnnid_map 
 * represents 1GB, and contains the node that the memory belongs to. */

#define PFNNID_SHIFT (30 - PAGE_SHIFT)
#define PFNNID_MAP_MAX  512     /* support 512GB */
extern signed char pfnnid_map[PFNNID_MAP_MAX];

#ifndef CONFIG_64BIT
#define pfn_is_io(pfn) ((pfn & (0xf0000000UL >> PAGE_SHIFT)) == (0xf0000000UL >> PAGE_SHIFT))
#else
/* io can be 0xf0f0f0f0f0xxxxxx or 0xfffffffff0000000 */
#define pfn_is_io(pfn) ((pfn & (0xf000000000000000UL >> PAGE_SHIFT)) == (0xf000000000000000UL >> PAGE_SHIFT))
#endif

static inline int pfn_to_nid(unsigned long pfn)
{
	unsigned int i;

	if (unlikely(pfn_is_io(pfn)))
		return 0;

	i = pfn >> PFNNID_SHIFT;
	BUG_ON(i >= ARRAY_SIZE(pfnnid_map));

	return pfnnid_map[i];
}

static inline int pfn_valid(int pfn)
{
	int nid = pfn_to_nid(pfn);

	if (nid >= 0)
		return (pfn < node_end_pfn(nid));
	return 0;
}

#endif
#endif /* _PARISC_MMZONE_H */
+2 −2
Original line number Diff line number Diff line
@@ -145,9 +145,9 @@ extern int npmem_ranges;
#define __pa(x)			((unsigned long)(x)-PAGE_OFFSET)
#define __va(x)			((void *)((unsigned long)(x)+PAGE_OFFSET))

#ifndef CONFIG_DISCONTIGMEM
#ifndef CONFIG_SPARSEMEM
#define pfn_valid(pfn)		((pfn) < max_mapnr)
#endif /* CONFIG_DISCONTIGMEM */
#endif

#ifdef CONFIG_HUGETLB_PAGE
#define HPAGE_SHIFT		PMD_SHIFT /* fixed for transparent huge pages */
+14 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef ASM_PARISC_SPARSEMEM_H
#define ASM_PARISC_SPARSEMEM_H

/* We have these possible memory map layouts:
 * Astro: 0-3.75, 67.75-68, 4-64
 * zx1: 0-1, 257-260, 4-256
 * Stretch (N-class): 0-2, 4-32, 34-xxx
 */

#define MAX_PHYSMEM_BITS	39	/* 512 GB */
#define SECTION_SIZE_BITS	27	/* 128 MB */

#endif
+0 −6
Original line number Diff line number Diff line
@@ -138,12 +138,6 @@ extern void $$dyncall(void);
EXPORT_SYMBOL($$dyncall);
#endif

#ifdef CONFIG_DISCONTIGMEM
#include <asm/mmzone.h>
EXPORT_SYMBOL(node_data);
EXPORT_SYMBOL(pfnnid_map);
#endif

#ifdef CONFIG_FUNCTION_TRACER
extern void _mcount(void);
EXPORT_SYMBOL(_mcount);
Loading