Linux SNPS ARC Archive on lore.kernel.org
 help / color / Atom feed
* [RFC/RFT WIP] arc: add sparsemem support
@ 2019-05-26 15:38 rppt
  2019-05-26 15:38 ` [RFC/RFT WIP PATCH] " rppt
  0 siblings, 1 reply; 4+ messages in thread
From: rppt @ 2019-05-26 15:38 UTC (permalink / raw)
  To: linux-snps-arc

Hi,

The patch below adds sparsemem support for ARC.

It's really a hack for now, as I'll need to sort out the generic MM bits to
allow creation of ZONE_HIGHMEM below ZONE_NORMAL on the same node.

The eventual intention is to completely replace DISCONTIGMEM with SPARSEMEM
provided the latter is at least as efficient.

I don't have access to ARC hardware I could only check the compilation and
the differences in the resulting vmlinux size. Apparently, I've managed to
have all three memory models buildable, at least with defconfig + override
for the memory model selection.

With the current changes sparsemem build creates a larger kernel,
especially with CONFIG_ARC_HAS_PAE40=y:

$ size -x discontigmem/vmlinux sparsemem/vmlinux
   text	   data	    bss	    dec	    hex	filename
0x348c5e	0xec5dc	0x3b658	4655250	 470892	discontigmem/vmlinux
0x3490cf	0xecde4	0x3bde0	4660371	 471c93	sparsemem/vmlinux

If the runtime results will favor sparsmem, it might be still worthwhile
using it instead of discontigmem.
Otherwise ARC is doomed to keep DISCONTIGMEM forever ;-)

I've defined the constants required for the SPARSEMEM based on the comments inside the code, if the actual parameters might be different, please let me know, I'll update the arch/arc/include/asm/sparsemem.h.

Currently, I presumed that for non-PAE the physical address size is 32 bits and there maybe up to two memory banks: at 0x8zz and at 0x0zz.

For the PAE case, the maximal physical address is 40 bits and the memory can be populated at 0x8zz or 0x1zzz.

--
Sincerely yours,
Mike.

Mike Rapoport (1):
  arc: add sparsemem support

 arch/arc/Kconfig                 |  9 +++++
 arch/arc/include/asm/sparsemem.h | 13 +++++++
 arch/arc/mm/init.c               | 84 ++++++++++++++++++++++++++++------------
 include/linux/mm.h               |  3 ++
 mm/page_alloc.c                  | 37 ++++++++++++++++++
 5 files changed, 121 insertions(+), 25 deletions(-)
 create mode 100644 arch/arc/include/asm/sparsemem.h

-- 
2.7.4

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC/RFT WIP PATCH] arc: add sparsemem support
  2019-05-26 15:38 [RFC/RFT WIP] arc: add sparsemem support rppt
@ 2019-05-26 15:38 ` " rppt
  2019-12-19 14:57   ` Eugeniy Paltsev
  0 siblings, 1 reply; 4+ messages in thread
From: rppt @ 2019-05-26 15:38 UTC (permalink / raw)
  To: linux-snps-arc

Add support for initialization of SPARSE memory model along with Kconfig
options that will allow its selection during the kernel configuration.

Certain configurations of ARC require that the memory that is not directly
mapped by the kernel (ZONE_HIGHMEM) will be below the memory that is always
mapped into the kernel page tables (ZONE_NORMAL).

For such configurations ZONE_NORMAL and ZONE_HIGHMEM were present on
different nodes.

With SPARSEMEM, there is a single node containing all the memory, but it is
initialized using dedicated free_area_init_node_exact_zones() routing that
takes the exact zone extents rather then their sizes.

Signed-off-by: Mike Rapoport <rppt at linux.ibm.com>
---
 arch/arc/Kconfig                 |  9 +++++
 arch/arc/include/asm/sparsemem.h | 13 +++++++
 arch/arc/mm/init.c               | 84 ++++++++++++++++++++++++++++------------
 include/linux/mm.h               |  3 ++
 mm/page_alloc.c                  | 37 ++++++++++++++++++
 5 files changed, 121 insertions(+), 25 deletions(-)
 create mode 100644 arch/arc/include/asm/sparsemem.h

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 23e063d..9b6c31d 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -47,6 +47,7 @@ config ARC
 	select OF_EARLY_FLATTREE
 	select PCI_SYSCALL if PCI
 	select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
+	select SPARSEMEM_STATIC if SPARSEMEM
 
 config ARCH_HAS_CACHE_LINE_SIZE
 	def_bool y
@@ -66,9 +67,15 @@ config GENERIC_CSUM
 config ARCH_DISCONTIGMEM_ENABLE
 	def_bool n
 
+config ARCH_SPARSEMEM_ENABLE
+	def_bool n
+
 config ARCH_FLATMEM_ENABLE
 	def_bool y
 
+config ARCH_SELECT_MEMORY_MODEL
+	def_bool n
+
 config MMU
 	def_bool y
 
@@ -449,6 +456,8 @@ config LINUX_RAM_BASE
 config HIGHMEM
 	bool "High Memory Support"
 	select ARCH_DISCONTIGMEM_ENABLE
+	select ARCH_SPARSEMEM_ENABLE
+	select ARCH_SELECT_MEMORY_MODEL
 	help
 	  With ARC 2G:2G address split, only upper 2G is directly addressable by
 	  kernel. Enable this to potentially allow access to rest of 2G and PAE
diff --git a/arch/arc/include/asm/sparsemem.h b/arch/arc/include/asm/sparsemem.h
new file mode 100644
index 0000000..b23bedd
--- /dev/null
+++ b/arch/arc/include/asm/sparsemem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARC_SPARSEMEM_H
+#define _ASM_ARC_SPARSEMEM_H
+
+#ifdef CONFIG_ARC_HAS_PAE40
+#define MAX_PHYSMEM_BITS	40
+#define SECTION_SIZE_BITS	32
+#else
+#define MAX_PHYSMEM_BITS	32
+#define SECTION_SIZE_BITS	31
+#endif
+
+#endif /* _ASM_ARC_SPARSEMEM_H */
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 02b7a3b..ad9ba05 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -78,6 +78,62 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
 		base, TO_MB(size), !in_use ? "Not used":"");
 }
 
+#ifdef CONFIG_SPARSEMEM
+static void setup_memory_model(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = { 0 };
+	unsigned long zones_start[MAX_NR_ZONES] = { 0 };
+	unsigned long node_min_pfn = min_low_pfn;
+
+	memblocks_present();
+	sparse_init();
+
+	zones_start[ZONE_NORMAL] = min_low_pfn;
+	zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
+
+	if (high_mem_sz) {
+		zones_start[ZONE_HIGHMEM] = min_high_pfn;
+		zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
+
+		node_min_pfn = min(min_low_pfn, min_high_pfn);
+	}
+
+	free_area_init_node_exact_zones(0,		/* node-id */
+					node_min_pfn,	/* first pfn of node */
+					zones_size,	/* num pages per zone */
+					zones_start);	/* firts pfn of zone */
+}
+
+#elif defined(CONFIG_DISCONTIGMEM)
+
+static void setup_memory_model(void)
+{
+	unsigned long zones_size[MAX_NR_ZONES] = { 0 };
+	unsigned long zones_holes[MAX_NR_ZONES] = { 0 };
+
+	/*
+	 * Populate a new node with highmem
+	 *
+	 * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based)
+	 * than addresses in normal ala low memory (0x8000_0000 based).
+	 * Even with PAE, the huge peripheral space hole would waste a lot of
+	 * mem with single mem_map[]. This warrants a mem_map per region design.
+	 * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM.
+	 *
+	 * DISCONTIGMEM in turns requires multiple nodes. node 0 above is
+	 * populated with normal memory zone while node 1 only has highmem
+	 */
+	node_set_online(1);
+
+	zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
+
+	free_area_init_node(1,			/* node-id */
+			    zones_size,		/* num pages per zone */
+			    min_high_pfn,	/* first pfn of node */
+			    zones_holes);	/* holes */
+}
+#endif /* CONFIG_SPARSEMEM || CONFIG_DISCONTIGMEM */
+
 /*
  * First memory setup routine called from setup_arch()
  * 1. setup swapper's mm @init_mm
@@ -142,6 +198,7 @@ void __init setup_arch_memory(void)
 	zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
 	zones_holes[ZONE_NORMAL] = 0;
 
+#ifdef CONFIG_FLATMEM
 	/*
 	 * We can't use the helper free_area_init(zones[]) because it uses
 	 * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
@@ -153,34 +210,11 @@ void __init setup_arch_memory(void)
 			    min_low_pfn,	/* first pfn of node */
 			    zones_holes);	/* holes */
 
-#ifdef CONFIG_HIGHMEM
-	/*
-	 * Populate a new node with highmem
-	 *
-	 * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based)
-	 * than addresses in normal ala low memory (0x8000_0000 based).
-	 * Even with PAE, the huge peripheral space hole would waste a lot of
-	 * mem with single mem_map[]. This warrants a mem_map per region design.
-	 * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM.
-	 *
-	 * DISCONTIGMEM in turns requires multiple nodes. node 0 above is
-	 * populated with normal memory zone while node 1 only has highmem
-	 */
-	node_set_online(1);
-
+#else
 	min_high_pfn = PFN_DOWN(high_mem_start);
 	max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
 
-	zones_size[ZONE_NORMAL] = 0;
-	zones_holes[ZONE_NORMAL] = 0;
-
-	zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
-	zones_holes[ZONE_HIGHMEM] = 0;
-
-	free_area_init_node(1,			/* node-id */
-			    zones_size,		/* num pages per zone */
-			    min_high_pfn,	/* first pfn of node */
-			    zones_holes);	/* holes */
+	setup_memory_model();
 
 	high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
 	kmap_init();
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0e8834a..5d47dee 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2107,6 +2107,9 @@ extern void __init pagecache_init(void);
 extern void free_area_init(unsigned long * zones_size);
 extern void __init free_area_init_node(int nid, unsigned long * zones_size,
 		unsigned long zone_start_pfn, unsigned long *zholes_size);
+extern void __init free_area_init_node_exact_zones(int nid,
+		unsigned long node_start_pfn, unsigned long *zones_size,
+		unsigned long *zones_start);
 extern void free_initmem(void);
 
 /*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3b13d39..7a708b9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6810,6 +6810,43 @@ void __init free_area_init_node(int nid, unsigned long *zones_size,
 	free_area_init_core(pgdat);
 }
 
+void __init free_area_init_node_exact_zones(int nid,
+					    unsigned long node_start_pfn,
+					    unsigned long *zones_size,
+					    unsigned long *zones_start)
+{
+	pg_data_t *pgdat = NODE_DATA(nid);
+	unsigned long totalpages = 0;
+	enum zone_type i;
+
+	/* pg_data_t should be reset to zero when it's allocated */
+	WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx);
+
+	pgdat->node_id = nid;
+	pgdat->node_start_pfn = node_start_pfn;
+	pgdat->per_cpu_nodestats = NULL;
+
+	for (i = 0; i < MAX_NR_ZONES; i++) {
+		struct zone *zone = pgdat->node_zones + i;
+		unsigned long size = zones_size[i];
+
+		zone->zone_start_pfn = zones_start[i];
+		zone->spanned_pages = zone->present_pages = size;
+
+		totalpages += size;
+	}
+
+	pgdat->node_spanned_pages = totalpages;
+	pgdat->node_present_pages = totalpages;
+	printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id,
+							totalpages);
+
+	alloc_node_mem_map(pgdat);
+	pgdat_set_deferred_range(pgdat);
+
+	free_area_init_core(pgdat);
+}
+
 #if !defined(CONFIG_FLAT_NODE_MEM_MAP)
 /*
  * Zero all valid struct pages in range [spfn, epfn), return number of struct
-- 
2.7.4

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC/RFT WIP PATCH] arc: add sparsemem support
  2019-05-26 15:38 ` [RFC/RFT WIP PATCH] " rppt
@ 2019-12-19 14:57   ` Eugeniy Paltsev
  2019-12-19 17:09     ` Vineet Gupta
  0 siblings, 1 reply; 4+ messages in thread
From: Eugeniy Paltsev @ 2019-12-19 14:57 UTC (permalink / raw)
  To: Mike Rapoport; +Cc: Vineet Gupta, linux-snps-arc, Alexey Brodkin

Hi Mike,

Sorry for late respond.
I've tested this patches but the kernel crashes in the memory initialization code.
Here is bootlog:

------------------------->8-----------------------------
Linux version 5.1.0+ (paltsev@paltsev-e7480) (gcc version 8.2.1 20180814 (ARCv2 ISA Linux uClibc toolchain 2018.09)) #1 PREEMPT Thu Oct 31 02:25:55 MSK 2019
Memory @ 80000000 [512M] 
Memory @ 100000000 [1024M] 
OF: fdt: Machine model: snps,nsim_hs
earlycon: arc_uart0 at MMIO32 0xc0fc1000 (options '115200n8')
printk: bootconsole [arc_uart0] enabled
archs-intc	: 15 priority levels (default 1)

IDENTITY	: ARCVER [0x51] ARCNUM [0xff] CHIPID [ 0x0]
processor [0]	: HS38 R2.0 (ARCv2 ISA) 
Timers		: Timer0 Timer1 RTC [UP 64-bit] 
ISA Extn	: atomic ll64 unalign mpy[opt 9] div_rem 
BPU		: partial match, cache:2048, Predict Table:16384 Return stk: 8
MMU [v4]	: 8k PAGE, 2M Super Page (not used) JTLB 512 (128x4), uDTLB 8, uITLB 4
I-Cache		: 16K, 2way/set, 64B Line, VIPT
D-Cache		: 16K, 4way/set, 64B Line, PIPT
Peripherals	: 0xc0000000
Vector Table	: 0x80000000
DEBUG		: ActionPoint 4/full
Built 1 zonelists, mobility grouping on.  Total pages: 196320
Kernel command line: earlycon=arc_uart,mmio32,0xc0fc1000,115200n8 console=ttyARC0,115200n8 print-fatal-signals=1
Dentry cache hash table entries: 65536 (order: 5, 262144 bytes)
Inode-cache hash table entries: 32768 (order: 4, 131072 bytes)

Oops
Path: (null)
CPU: 0 PID: 0 Comm: swapper Not tainted 5.1.0+ #1

[ECR   ]: 0x00050100 => Invalid Read @ 0x01200000 by insn @ 0x800a8bc6
[EFA   ]: 0x01200000
[BLINK ]: mem_init+0x40/0x58
[ERET  ]: free_highmem_page+0x6/0x88
[STAT32]: 0x00080002 :   K     
BTA: 0x800a8bc0	 SP: 0x803ebfd8	 FP: 0x00000000
LPS: 0x802fbd3c	LPE: 0x802fbd44	LPC: 0x00000000
r00: 0x01200000	r01: 0x0000000a	r02: 0x00000000	
r03: 0x000a0000	r04: 0x00000021	r05: 0x00000000	
r06: 0x646f6e49	r07: 0x61632d65	r08: 0x20656863	
r09: 0x68736168	r10: 0x00000016	r11: 0x6520656c	
r12: 0x800066e4	

Stack Trace:
  free_highmem_page+0x6/0x88
  mem_init+0x40/0x58
------------------------->8-----------------------------

So we have invalid memory access here:
------------------------->8-----------------------------
void __init mem_init(void)
{
#ifdef CONFIG_HIGHMEM
	unsigned long tmp;

	reset_all_zones_managed_pages();
	for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
		free_highmem_page(pfn_to_page(tmp));           // <<<<<<<<------
#endif

	memblock_free_all();
	mem_init_print_info(NULL);
}
------------------------->8-----------------------------


BTW, you can also test your future changes by yourself. For that you can use 
nSIM free simulator which provides an instruction accurate processor model for
the ARC processors. To download nSIM free you need request it via this form:
https://www.synopsys.com/cgi-bin/dwarcnsim/req1.cgi
You will be able to download it after the from will be approved.

You can find instructions describing how to run Linux with nSIM free here:
https://github.com/foss-for-synopsys-dwc-arc-processors/linux/wiki/How-to-run-ARC-Linux-kernel-and-debug-(with-MetaWare-Debugger)#standalone-nsim-also-free-nsim

If you are going to rebase you patches on v5.5 kernel (or newer) please also read this note:
https://github.com/foss-for-synopsys-dwc-arc-processors/linux/wiki/How-to-run-ARC-Linux-kernel-and-debug-(with-MetaWare-Debugger)#v55-linux-kernel-note

Thanks.
---
 Eugeniy Paltsev


________________________________________
From: linux-snps-arc <linux-snps-arc-bounces@lists.infradead.org> on behalf of Mike Rapoport <rppt@linux.ibm.com>
Sent: Sunday, May 26, 2019 18:38
To: Vineet Gupta
Cc: linux-snps-arc@lists.infradead.org; Mike Rapoport
Subject: [RFC/RFT WIP PATCH] arc: add sparsemem support

Add support for initialization of SPARSE memory model along with Kconfig
options that will allow its selection during the kernel configuration.

Certain configurations of ARC require that the memory that is not directly
mapped by the kernel (ZONE_HIGHMEM) will be below the memory that is always
mapped into the kernel page tables (ZONE_NORMAL).

For such configurations ZONE_NORMAL and ZONE_HIGHMEM were present on
different nodes.

With SPARSEMEM, there is a single node containing all the memory, but it is
initialized using dedicated free_area_init_node_exact_zones() routing that
takes the exact zone extents rather then their sizes.

Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
---
 arch/arc/Kconfig                 |  9 +++++
 arch/arc/include/asm/sparsemem.h | 13 +++++++
 arch/arc/mm/init.c               | 84 ++++++++++++++++++++++++++++------------
 include/linux/mm.h               |  3 ++
 mm/page_alloc.c                  | 37 ++++++++++++++++++
 5 files changed, 121 insertions(+), 25 deletions(-)
 create mode 100644 arch/arc/include/asm/sparsemem.h

diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig
index 23e063d..9b6c31d 100644
--- a/arch/arc/Kconfig
+++ b/arch/arc/Kconfig
@@ -47,6 +47,7 @@ config ARC
        select OF_EARLY_FLATTREE
        select PCI_SYSCALL if PCI
        select PERF_USE_VMALLOC if ARC_CACHE_VIPT_ALIASING
+       select SPARSEMEM_STATIC if SPARSEMEM

 config ARCH_HAS_CACHE_LINE_SIZE
        def_bool y
@@ -66,9 +67,15 @@ config GENERIC_CSUM
 config ARCH_DISCONTIGMEM_ENABLE
        def_bool n

+config ARCH_SPARSEMEM_ENABLE
+       def_bool n
+
 config ARCH_FLATMEM_ENABLE
        def_bool y

+config ARCH_SELECT_MEMORY_MODEL
+       def_bool n
+
 config MMU
        def_bool y

@@ -449,6 +456,8 @@ config LINUX_RAM_BASE
 config HIGHMEM
        bool "High Memory Support"
        select ARCH_DISCONTIGMEM_ENABLE
+       select ARCH_SPARSEMEM_ENABLE
+       select ARCH_SELECT_MEMORY_MODEL
        help
          With ARC 2G:2G address split, only upper 2G is directly addressable by
          kernel. Enable this to potentially allow access to rest of 2G and PAE
diff --git a/arch/arc/include/asm/sparsemem.h b/arch/arc/include/asm/sparsemem.h
new file mode 100644
index 0000000..b23bedd
--- /dev/null
+++ b/arch/arc/include/asm/sparsemem.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_ARC_SPARSEMEM_H
+#define _ASM_ARC_SPARSEMEM_H
+
+#ifdef CONFIG_ARC_HAS_PAE40
+#define MAX_PHYSMEM_BITS       40
+#define SECTION_SIZE_BITS      32
+#else
+#define MAX_PHYSMEM_BITS       32
+#define SECTION_SIZE_BITS      31
+#endif
+
+#endif /* _ASM_ARC_SPARSEMEM_H */
diff --git a/arch/arc/mm/init.c b/arch/arc/mm/init.c
index 02b7a3b..ad9ba05 100644
--- a/arch/arc/mm/init.c
+++ b/arch/arc/mm/init.c
@@ -78,6 +78,62 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
                base, TO_MB(size), !in_use ? "Not used":"");
 }

+#ifdef CONFIG_SPARSEMEM
+static void setup_memory_model(void)
+{
+       unsigned long zones_size[MAX_NR_ZONES] = { 0 };
+       unsigned long zones_start[MAX_NR_ZONES] = { 0 };
+       unsigned long node_min_pfn = min_low_pfn;
+
+       memblocks_present();
+       sparse_init();
+
+       zones_start[ZONE_NORMAL] = min_low_pfn;
+       zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
+
+       if (high_mem_sz) {
+               zones_start[ZONE_HIGHMEM] = min_high_pfn;
+               zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
+
+               node_min_pfn = min(min_low_pfn, min_high_pfn);
+       }
+
+       free_area_init_node_exact_zones(0,              /* node-id */
+                                       node_min_pfn,   /* first pfn of node */
+                                       zones_size,     /* num pages per zone */
+                                       zones_start);   /* firts pfn of zone */
+}
+
+#elif defined(CONFIG_DISCONTIGMEM)
+
+static void setup_memory_model(void)
+{
+       unsigned long zones_size[MAX_NR_ZONES] = { 0 };
+       unsigned long zones_holes[MAX_NR_ZONES] = { 0 };
+
+       /*
+        * Populate a new node with highmem
+        *
+        * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based)
+        * than addresses in normal ala low memory (0x8000_0000 based).
+        * Even with PAE, the huge peripheral space hole would waste a lot of
+        * mem with single mem_map[]. This warrants a mem_map per region design.
+        * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM.
+        *
+        * DISCONTIGMEM in turns requires multiple nodes. node 0 above is
+        * populated with normal memory zone while node 1 only has highmem
+        */
+       node_set_online(1);
+
+       zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
+
+       free_area_init_node(1,                  /* node-id */
+                           zones_size,         /* num pages per zone */
+                           min_high_pfn,       /* first pfn of node */
+                           zones_holes);       /* holes */
+}
+#endif /* CONFIG_SPARSEMEM || CONFIG_DISCONTIGMEM */
+
 /*
  * First memory setup routine called from setup_arch()
  * 1. setup swapper's mm @init_mm
@@ -142,6 +198,7 @@ void __init setup_arch_memory(void)
        zones_size[ZONE_NORMAL] = max_low_pfn - min_low_pfn;
        zones_holes[ZONE_NORMAL] = 0;

+#ifdef CONFIG_FLATMEM
        /*
         * We can't use the helper free_area_init(zones[]) because it uses
         * PAGE_OFFSET to compute the @min_low_pfn which would be wrong
@@ -153,34 +210,11 @@ void __init setup_arch_memory(void)
                            min_low_pfn,        /* first pfn of node */
                            zones_holes);       /* holes */

-#ifdef CONFIG_HIGHMEM
-       /*
-        * Populate a new node with highmem
-        *
-        * On ARC (w/o PAE) HIGHMEM addresses are actually smaller (0 based)
-        * than addresses in normal ala low memory (0x8000_0000 based).
-        * Even with PAE, the huge peripheral space hole would waste a lot of
-        * mem with single mem_map[]. This warrants a mem_map per region design.
-        * Thus HIGHMEM on ARC is imlemented with DISCONTIGMEM.
-        *
-        * DISCONTIGMEM in turns requires multiple nodes. node 0 above is
-        * populated with normal memory zone while node 1 only has highmem
-        */
-       node_set_online(1);
-
+#else
        min_high_pfn = PFN_DOWN(high_mem_start);
        max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz);

-       zones_size[ZONE_NORMAL] = 0;
-       zones_holes[ZONE_NORMAL] = 0;
-
-       zones_size[ZONE_HIGHMEM] = max_high_pfn - min_high_pfn;
-       zones_holes[ZONE_HIGHMEM] = 0;
-
-       free_area_init_node(1,                  /* node-id */
-                           zones_size,         /* num pages per zone */
-                           min_high_pfn,       /* first pfn of node */
-                           zones_holes);       /* holes */
+       setup_memory_model();

        high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
        kmap_init();
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 0e8834a..5d47dee 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -2107,6 +2107,9 @@ extern void __init pagecache_init(void);
 extern void free_area_init(unsigned long * zones_size);
 extern void __init free_area_init_node(int nid, unsigned long * zones_size,
                unsigned long zone_start_pfn, unsigned long *zholes_size);
+extern void __init free_area_init_node_exact_zones(int nid,
+               unsigned long node_start_pfn, unsigned long *zones_size,
+               unsigned long *zones_start);
 extern void free_initmem(void);

 /*
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 3b13d39..7a708b9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -6810,6 +6810,43 @@ void __init free_area_init_node(int nid, unsigned long *zones_size,
        free_area_init_core(pgdat);
 }

+void __init free_area_init_node_exact_zones(int nid,
+                                           unsigned long node_start_pfn,
+                                           unsigned long *zones_size,
+                                           unsigned long *zones_start)
+{
+       pg_data_t *pgdat = NODE_DATA(nid);
+       unsigned long totalpages = 0;
+       enum zone_type i;
+
+       /* pg_data_t should be reset to zero when it's allocated */
+       WARN_ON(pgdat->nr_zones || pgdat->kswapd_classzone_idx);
+
+       pgdat->node_id = nid;
+       pgdat->node_start_pfn = node_start_pfn;
+       pgdat->per_cpu_nodestats = NULL;
+
+       for (i = 0; i < MAX_NR_ZONES; i++) {
+               struct zone *zone = pgdat->node_zones + i;
+               unsigned long size = zones_size[i];
+
+               zone->zone_start_pfn = zones_start[i];
+               zone->spanned_pages = zone->present_pages = size;
+
+               totalpages += size;
+       }
+
+       pgdat->node_spanned_pages = totalpages;
+       pgdat->node_present_pages = totalpages;
+       printk(KERN_DEBUG "On node %d totalpages: %lu\n", pgdat->node_id,
+                                                       totalpages);
+
+       alloc_node_mem_map(pgdat);
+       pgdat_set_deferred_range(pgdat);
+
+       free_area_init_core(pgdat);
+}
+
 #if !defined(CONFIG_FLAT_NODE_MEM_MAP)
 /*
  * Zero all valid struct pages in range [spfn, epfn), return number of struct
--
2.7.4


_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
https://urldefense.proofpoint.com/v2/url?u=http-3A__lists.infradead.org_mailman_listinfo_linux-2Dsnps-2Darc&d=DwICAg&c=DPL6_X_6JkXFx7AXWqB0tg&r=ZlJN1MriPUTkBKCrPSx67GmaplEUGcAEk9yPtCLdUXI&m=km3pqqSiGIrbaUQv0sK9eZBHx9g-rqWaJ6pwsCbiNtw&s=YjkIJuc5SRPRLmuwX90J87ghv-Ffmn98lbGQoEJDRlg&e=

_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [RFC/RFT WIP PATCH] arc: add sparsemem support
  2019-12-19 14:57   ` Eugeniy Paltsev
@ 2019-12-19 17:09     ` Vineet Gupta
  0 siblings, 0 replies; 4+ messages in thread
From: Vineet Gupta @ 2019-12-19 17:09 UTC (permalink / raw)
  To: Eugeniy Paltsev, Mike Rapoport; +Cc: linux-snps-arc, Alexey Brodkin

On 12/19/19 6:57 AM, Eugeniy Paltsev wrote:
> You can find instructions describing how to run Linux with nSIM free here:
> https://github.com/foss-for-synopsys-dwc-arc-processors/linux/wiki/How-to-run-ARC-Linux-kernel-and-debug-(with-MetaWare-Debugger)#standalone-nsim-also-free-nsim
>
> If you are going to rebase you patches on v5.5 kernel (or newer) please also read this note:
> https://github.com/foss-for-synopsys-dwc-arc-processors/linux/wiki/How-to-run-ARC-Linux-kernel-and-debug-(with-MetaWare-Debugger)#v55-linux-kernel-note

Thx for nice update of the wiki page. I've made some mods to make the DW UART
settings as default and mentioned the fallback ARC UART settings in foot note (vs.
the other way around)

-Vineet
_______________________________________________
linux-snps-arc mailing list
linux-snps-arc@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-snps-arc

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-26 15:38 [RFC/RFT WIP] arc: add sparsemem support rppt
2019-05-26 15:38 ` [RFC/RFT WIP PATCH] " rppt
2019-12-19 14:57   ` Eugeniy Paltsev
2019-12-19 17:09     ` Vineet Gupta

Linux SNPS ARC Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-snps-arc/0 linux-snps-arc/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-snps-arc linux-snps-arc/ https://lore.kernel.org/linux-snps-arc \
		linux-snps-arc@lists.infradead.org
	public-inbox-index linux-snps-arc

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.infradead.lists.linux-snps-arc


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git