linux-mips.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Drop boot_mem_map
@ 2019-08-08  7:50 Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 1/7] MIPS: init: " Jiaxun Yang
                   ` (8 more replies)
  0 siblings, 9 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc

Hi there:
I was trying to make a generic NUMA implementation for ip27 and loongson-3,
and the boot_mem_map without nid support become a barrier of merging memory
init code.

Rather than add nid support to boot_mem_map, this patchset drops the whole
boot_mem_map as it can be replaced by memblock functions.

--
Jiaxun Yang




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

* [PATCH 1/7] MIPS: init: Drop boot_mem_map
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-14 11:54   ` Serge Semin
  2019-08-08  7:50 ` [PATCH 2/7] MIPS: OCTEON: " Jiaxun Yang
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map was introduced very early and cannot handle memory maps
with nid. Nowadays, memblock can exactly replace boot_mem_map.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/include/asm/bootinfo.h |  15 --
 arch/mips/kernel/setup.c         | 352 ++++++++-----------------------
 arch/mips/mm/init.c              |  51 +----
 3 files changed, 91 insertions(+), 327 deletions(-)

diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 235bc2f52113..f711ccf7bace 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -94,21 +94,6 @@ extern unsigned long mips_machtype;
 #define BOOT_MEM_INIT_RAM	4
 #define BOOT_MEM_NOMAP		5
 
-/*
- * A memory map that's built upon what was determined
- * or specified on the command line.
- */
-struct boot_mem_map {
-	int nr_map;
-	struct boot_mem_map_entry {
-		phys_addr_t addr;	/* start of memory segment */
-		phys_addr_t size;	/* size of memory segment */
-		long type;		/* type of memory segment */
-	} map[BOOT_MEM_MAP_MAX];
-};
-
-extern struct boot_mem_map boot_mem_map;
-
 extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
 extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min,  phys_addr_t sz_max);
 
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index ab349d2381c3..ceef8240f171 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
 
 EXPORT_SYMBOL(mips_machtype);
 
-struct boot_mem_map boot_mem_map;
-
 static char __initdata command_line[COMMAND_LINE_SIZE];
 char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
 
@@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET);
 
 void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
 {
-	int x = boot_mem_map.nr_map;
-	int i;
+	/*
+	 * Note: This function only exists for historical reason,
+	 * new code should use memblock_add or memblock_add_node instead.
+	 */
 
 	/*
 	 * If the region reaches the top of the physical address space, adjust
@@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
 		return;
 	}
 
-	/*
-	 * Try to merge with existing entry, if any.
-	 */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		struct boot_mem_map_entry *entry = boot_mem_map.map + i;
-		unsigned long top;
-
-		if (entry->type != type)
-			continue;
-
-		if (start + size < entry->addr)
-			continue;			/* no overlap */
+	memblock_add(start, size);
+	/* Reserve any memory except the ordinary RAM ranges. */
+	switch (type) {
+	case BOOT_MEM_RAM:
+		break;
 
-		if (entry->addr + entry->size < start)
-			continue;			/* no overlap */
+	case BOOT_MEM_NOMAP: /* Discard the range from the system. */
+		memblock_remove(start, size);
+		break;
 
-		top = max(entry->addr + entry->size, start + size);
-		entry->addr = min(entry->addr, start);
-		entry->size = top - entry->addr;
-
-		return;
+	default: /* Reserve the rest of the memory types at boot time */
+		memblock_reserve(start, size);
+		break;
 	}
-
-	if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
-		pr_err("Ooops! Too many entries in the memory map!\n");
-		return;
-	}
-
-	boot_mem_map.map[x].addr = start;
-	boot_mem_map.map[x].size = size;
-	boot_mem_map.map[x].type = type;
-	boot_mem_map.nr_map++;
 }
 
 void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
@@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
 	add_memory_region(start, size, BOOT_MEM_RAM);
 }
 
-static bool __init __maybe_unused memory_region_available(phys_addr_t start,
-							  phys_addr_t size)
-{
-	int i;
-	bool in_ram = false, free = true;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		phys_addr_t start_, end_;
-
-		start_ = boot_mem_map.map[i].addr;
-		end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			if (start >= start_ && start + size <= end_)
-				in_ram = true;
-			break;
-		case BOOT_MEM_RESERVED:
-		case BOOT_MEM_NOMAP:
-			if ((start >= start_ && start < end_) ||
-			    (start < start_ && start + size >= start_))
-				free = false;
-			break;
-		default:
-			continue;
-		}
-	}
-
-	return in_ram && free;
-}
-
-static void __init print_memory_map(void)
-{
-	int i;
-	const int field = 2 * sizeof(unsigned long);
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
-		       field, (unsigned long long) boot_mem_map.map[i].size,
-		       field, (unsigned long long) boot_mem_map.map[i].addr);
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			printk(KERN_CONT "(usable)\n");
-			break;
-		case BOOT_MEM_INIT_RAM:
-			printk(KERN_CONT "(usable after init)\n");
-			break;
-		case BOOT_MEM_ROM_DATA:
-			printk(KERN_CONT "(ROM data)\n");
-			break;
-		case BOOT_MEM_RESERVED:
-			printk(KERN_CONT "(reserved)\n");
-			break;
-		case BOOT_MEM_NOMAP:
-			printk(KERN_CONT "(nomap)\n");
-			break;
-		default:
-			printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
-			break;
-		}
-	}
-}
-
 /*
  * Manage initrd
  */
@@ -376,8 +294,11 @@ static void __init bootmem_init(void)
 
 static void __init bootmem_init(void)
 {
-	phys_addr_t ramstart = PHYS_ADDR_MAX;
-	int i;
+	struct memblock_region *mem;
+	phys_addr_t ramstart, ramend;
+
+	ramstart = memblock_start_of_DRAM();
+	ramend = memblock_end_of_DRAM();
 
 	/*
 	 * Sanity check any INITRD first. We don't take it into account
@@ -398,115 +319,61 @@ static void __init bootmem_init(void)
 	min_low_pfn = ~0UL;
 	max_low_pfn = 0;
 
-	/* Find the highest and lowest page frame numbers we have available. */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start, end;
-
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
+#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
+	min_low_pfn = PFN_UP(ramstart);
+	ARCH_PFN_OFFSET = PFN_UP(ramstart);
+#else
+	/*
+	 * Reserve any memory between the start of RAM and PHYS_OFFSET
+	 */
+	if (PFN_UP(ramstart) > PHYS_OFFSET)
+		memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
 
-		start = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr
-				+ boot_mem_map.map[i].size);
+	if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
+		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
+			(unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)),
+			(unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET));
+	} else if (ARCH_PFN_OFFSET - PFN_UP(ramstart) > 0UL) {
+		pr_info("%lu free pages won't be used\n",
+			(unsigned long)(ARCH_PFN_OFFSET - PFN_UP(ramstart)));
+	}
+	min_low_pfn = ARCH_PFN_OFFSET;
+#endif
 
-		ramstart = min(ramstart, boot_mem_map.map[i].addr);
+	max_pfn = PFN_DOWN(ramend);
+	for_each_memblock(memory, mem) {
+		unsigned long start = memblock_region_memory_base_pfn(mem);
+		unsigned long end = memblock_region_memory_end_pfn(mem);
 
-#ifndef CONFIG_HIGHMEM
 		/*
 		 * Skip highmem here so we get an accurate max_low_pfn if low
 		 * memory stops short of high memory.
 		 * If the region overlaps HIGHMEM_START, end is clipped so
 		 * max_pfn excludes the highmem portion.
 		 */
+		if (memblock_is_nomap(mem))
+			continue;
 		if (start >= PFN_DOWN(HIGHMEM_START))
 			continue;
 		if (end > PFN_DOWN(HIGHMEM_START))
 			end = PFN_DOWN(HIGHMEM_START);
-#endif
-
 		if (end > max_low_pfn)
 			max_low_pfn = end;
-		if (start < min_low_pfn)
-			min_low_pfn = start;
 	}
 
-	if (min_low_pfn >= max_low_pfn)
-		panic("Incorrect memory mapping !!!");
-
-#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
-	ARCH_PFN_OFFSET = PFN_UP(ramstart);
-#else
-	/*
-	 * Reserve any memory between the start of RAM and PHYS_OFFSET
-	 */
-	if (ramstart > PHYS_OFFSET) {
-		add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
-				  BOOT_MEM_RESERVED);
-		memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
-	}
-
-	if (min_low_pfn > ARCH_PFN_OFFSET) {
-		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
-			(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
-			min_low_pfn - ARCH_PFN_OFFSET);
-	} else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) {
-		pr_info("%lu free pages won't be used\n",
-			ARCH_PFN_OFFSET - min_low_pfn);
+#ifdef CONFIG_HIGHMEM
+	if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
+		highstart_pfn = max_low_pfn;
+		highend_pfn = max_pfn;
 	}
-	min_low_pfn = ARCH_PFN_OFFSET;
 #endif
 
 	/*
-	 * Determine low and high memory ranges
+	 * In any case the added to the memblock memory regions
+	 * (highmem/lowmem, available/reserved, etc) are considered
+	 * as present, so inform sparsemem about them.
 	 */
-	max_pfn = max_low_pfn;
-	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
-#ifdef CONFIG_HIGHMEM
-		highstart_pfn = PFN_DOWN(HIGHMEM_START);
-		highend_pfn = max_low_pfn;
-#endif
-		max_low_pfn = PFN_DOWN(HIGHMEM_START);
-	}
-
-	/* Install all valid RAM ranges to the memblock memory region */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start, end;
-
-		start = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr
-				+ boot_mem_map.map[i].size);
-
-		if (start < min_low_pfn)
-			start = min_low_pfn;
-#ifndef CONFIG_HIGHMEM
-		/* Ignore highmem regions if highmem is unsupported */
-		if (end > max_low_pfn)
-			end = max_low_pfn;
-#endif
-		if (end <= start)
-			continue;
-
-		memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
-
-		/* Reserve any memory except the ordinary RAM ranges. */
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			break;
-		case BOOT_MEM_NOMAP: /* Discard the range from the system. */
-			memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start));
-			continue;
-		default: /* Reserve the rest of the memory types at boot time */
-			memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start));
-			break;
-		}
-
-		/*
-		 * In any case the added to the memblock memory regions
-		 * (highmem/lowmem, available/reserved, etc) are considered
-		 * as present, so inform sparsemem about them.
-		 */
-		memory_present(0, start, end);
-	}
+	memblocks_present();
 
 	/*
 	 * Reserve initrd memory if needed.
@@ -528,8 +395,9 @@ static int __init early_parse_mem(char *p)
 	 * size.
 	 */
 	if (usermem == 0) {
-		boot_mem_map.nr_map = 0;
 		usermem = 1;
+		memblock_remove(memblock_start_of_DRAM(),
+			memblock_end_of_DRAM() - memblock_start_of_DRAM());
 	}
 	start = 0;
 	size = memparse(p, &p);
@@ -586,14 +454,13 @@ early_param("memmap", early_parse_memmap);
 unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
 static int __init early_parse_elfcorehdr(char *p)
 {
-	int i;
+	struct memblock_region *mem;
 
 	setup_elfcorehdr = memparse(p, &p);
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start = boot_mem_map.map[i].addr;
-		unsigned long end = (boot_mem_map.map[i].addr +
-				     boot_mem_map.map[i].size);
+	 for_each_memblock(memory, mem) {
+		unsigned long start = mem->base;
+		unsigned long end = mem->end;
 		if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
 			/*
 			 * Reserve from the elf core header to the end of
@@ -613,47 +480,20 @@ static int __init early_parse_elfcorehdr(char *p)
 early_param("elfcorehdr", early_parse_elfcorehdr);
 #endif
 
-static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
-{
-	phys_addr_t size;
-	int i;
-
-	size = end - mem;
-	if (!size)
-		return;
-
-	/* Make sure it is in the boot_mem_map */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (mem >= boot_mem_map.map[i].addr &&
-		    mem < (boot_mem_map.map[i].addr +
-			   boot_mem_map.map[i].size))
-			return;
-	}
-	add_memory_region(mem, size, type);
-}
-
 #ifdef CONFIG_KEXEC
-static inline unsigned long long get_total_mem(void)
-{
-	unsigned long long total;
-
-	total = max_pfn - min_low_pfn;
-	return total << PAGE_SHIFT;
-}
-
 static void __init mips_parse_crashkernel(void)
 {
 	unsigned long long total_mem;
 	unsigned long long crash_size, crash_base;
 	int ret;
 
-	total_mem = get_total_mem();
+	total_mem = memblock_phys_mem_size();
 	ret = parse_crashkernel(boot_command_line, total_mem,
 				&crash_size, &crash_base);
 	if (ret != 0 || crash_size <= 0)
 		return;
 
-	if (!memory_region_available(crash_base, crash_size)) {
+	if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) {
 		pr_warn("Invalid memory region reserved for crash kernel\n");
 		return;
 	}
@@ -686,6 +526,17 @@ static void __init request_crashkernel(struct resource *res)
 }
 #endif /* !defined(CONFIG_KEXEC)  */
 
+static void __init check_kernel_sections_mem(void)
+{
+	phys_addr_t start = PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT;
+	phys_addr_t size = (PFN_UP(__pa_symbol(&_end)) - start) << PAGE_SHIFT;
+
+	if (!memblock_is_region_memory(start, size)) {
+		pr_info("Kernel sections are not in the memory maps\n");
+		memblock_add(start, size);
+	}
+}
+
 #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
 #define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
@@ -731,25 +582,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	plat_mem_setup();
 	memblock_set_bottom_up(true);
 
-	/*
-	 * Make sure all kernel memory is in the maps.  The "UP" and
-	 * "DOWN" are opposite for initdata since if it crosses over
-	 * into another memory section you don't want that to be
-	 * freed when the initdata is freed.
-	 */
-	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
-			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
-			 BOOT_MEM_RAM);
-	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
-			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
-			 BOOT_MEM_INIT_RAM);
-	arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT,
-			 PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT,
-			 BOOT_MEM_RAM);
-
-	pr_info("Determined physical RAM map:\n");
-	print_memory_map();
-
 #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
 	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 #else
@@ -783,14 +615,17 @@ static void __init arch_mem_init(char **cmdline_p)
 
 	parse_early_param();
 
-	if (usermem) {
-		pr_info("User-defined physical RAM map:\n");
-		print_memory_map();
-	}
+	if (usermem)
+		pr_info("User-defined physical RAM map overwrite\n");
+
+	check_kernel_sections_mem();
 
 	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
+#ifndef CONFIG_NUMA
+	memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
+#endif
 	bootmem_init();
 
 	/*
@@ -835,7 +670,7 @@ static void __init arch_mem_init(char **cmdline_p)
 
 static void __init resource_init(void)
 {
-	int i;
+	struct memblock_region *region;
 
 	if (UNCAC_BASE != IO_BASE)
 		return;
@@ -847,16 +682,10 @@ static void __init resource_init(void)
 	bss_resource.start = __pa_symbol(&__bss_start);
 	bss_resource.end = __pa_symbol(&__bss_stop) - 1;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
+	for_each_memblock(memory, region) {
+		phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
+		phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
 		struct resource *res;
-		unsigned long start, end;
-
-		start = boot_mem_map.map[i].addr;
-		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
-		if (start >= HIGHMEM_START)
-			continue;
-		if (end >= HIGHMEM_START)
-			end = HIGHMEM_START - 1;
 
 		res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
 		if (!res)
@@ -865,20 +694,7 @@ static void __init resource_init(void)
 
 		res->start = start;
 		res->end = end;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-		case BOOT_MEM_ROM_DATA:
-			res->name = "System RAM";
-			res->flags |= IORESOURCE_SYSRAM;
-			break;
-		case BOOT_MEM_RESERVED:
-		case BOOT_MEM_NOMAP:
-		default:
-			res->name = "reserved";
-		}
+		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
 
 		request_resource(&iomem_resource, res);
 
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8a038b30d3c4..2bb8ebf0d2d5 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -271,25 +271,17 @@ void __init fixrange_init(unsigned long start, unsigned long end,
 
 unsigned __weak platform_maar_init(unsigned num_pairs)
 {
-	struct maar_config cfg[BOOT_MEM_MAP_MAX];
-	unsigned i, num_configured, num_cfg = 0;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-			break;
-		default:
-			continue;
-		}
+	struct maar_config cfg[32];
+	unsigned int num_configured, num_cfg = 0;
+	struct memblock_region *mem;
 
+	for_each_memblock(memory, mem) {
 		/* Round lower up */
-		cfg[num_cfg].lower = boot_mem_map.map[i].addr;
+		cfg[num_cfg].lower = __pfn_to_phys(memblock_region_memory_base_pfn(mem));
 		cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
 
 		/* Round upper down */
-		cfg[num_cfg].upper = boot_mem_map.map[i].addr +
-					boot_mem_map.map[i].size;
+		cfg[num_cfg].upper = __pfn_to_phys(memblock_region_memory_end_pfn(mem));
 		cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
 
 		cfg[num_cfg].attrs = MIPS_MAAR_S;
@@ -382,33 +374,6 @@ void maar_init(void)
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-int page_is_ram(unsigned long pagenr)
-{
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long addr, end;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-			break;
-		default:
-			/* not usable memory */
-			continue;
-		}
-
-		addr = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr +
-			       boot_mem_map.map[i].size);
-
-		if (pagenr >= addr && pagenr < end)
-			return 1;
-	}
-
-	return 0;
-}
-
 void __init paging_init(void)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
@@ -452,9 +417,7 @@ static inline void mem_init_free_highmem(void)
 		return;
 
 	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-		struct page *page = pfn_to_page(tmp);
-
-		if (!page_is_ram(tmp))
+		if (!memblock_is_memory(PFN_PHYS(tmp)))
 			SetPageReserved(page);
 		else
 			free_highmem_page(page);
-- 
2.22.0


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

* [PATCH 2/7] MIPS: OCTEON: Drop boot_mem_map
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 1/7] MIPS: init: " Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 3/7] MIPS: fw: Record prom memory Jiaxun Yang
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Replace walk through boot_mem_map with for_each_memblock.
And remove the check of total boot_mem_map.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/cavium-octeon/dma-octeon.c | 17 +++++++----------
 arch/mips/cavium-octeon/setup.c      |  3 +--
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 11d5a4e90736..72f24a4db099 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/memblock.h>
 
 #include <asm/bootinfo.h>
 
@@ -190,7 +191,7 @@ char *octeon_swiotlb;
 
 void __init plat_swiotlb_setup(void)
 {
-	int i;
+	struct memblock_region *mem;
 	phys_addr_t max_addr;
 	phys_addr_t addr_size;
 	size_t swiotlbsize;
@@ -199,19 +200,15 @@ void __init plat_swiotlb_setup(void)
 	max_addr = 0;
 	addr_size = 0;
 
-	for (i = 0 ; i < boot_mem_map.nr_map; i++) {
-		struct boot_mem_map_entry *e = &boot_mem_map.map[i];
-		if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM)
-			continue;
-
+	for_each_memblock(memory, mem) {
 		/* These addresses map low for PCI. */
-		if (e->addr > 0x410000000ull && !OCTEON_IS_OCTEON2())
+		if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2())
 			continue;
 
-		addr_size += e->size;
+		addr_size += mem->size;
 
-		if (max_addr < e->addr + e->size)
-			max_addr = e->addr + e->size;
+		if (max_addr < mem->base + mem->size)
+			max_addr = mem->base + mem->size;
 
 	}
 
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 8bf43c5a7bc7..95034bf5ca83 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -1007,8 +1007,7 @@ void __init plat_mem_setup(void)
 	 * regions next to each other.
 	 */
 	cvmx_bootmem_lock();
-	while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
-		&& (total < max_memory)) {
+	while (total < max_memory) {
 		memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
 						__pa_symbol(&_end), -1,
 						0x100000,
-- 
2.22.0


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

* [PATCH 3/7] MIPS: fw: Record prom memory
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 1/7] MIPS: init: " Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 2/7] MIPS: OCTEON: " Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-14 12:03   ` Serge Semin
  2019-08-08  7:50 ` [PATCH 4/7] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map is nolonger exist so we need to maintain a list
of prom memory by ourselves.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/fw/arc/memory.c | 20 ++++++++++++++------
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
index 429b7f8d2aeb..02e954b3700e 100644
--- a/arch/mips/fw/arc/memory.c
+++ b/arch/mips/fw/arc/memory.c
@@ -27,6 +27,11 @@
 
 #undef DEBUG
 
+#define MAX_PROM_MEM 5
+static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
+static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
+static unsigned int nr_prom_mem __initdata;
+
 /*
  * For ARC firmware memory functions the unit of meassuring memory is always
  * a 4k page of memory
@@ -129,6 +134,7 @@ void __init prom_meminit(void)
 	}
 #endif
 
+	nr_prom_mem = 0;
 	p = PROM_NULL_MDESC;
 	while ((p = ArcGetMemoryDescriptor(p))) {
 		unsigned long base, size;
@@ -139,6 +145,12 @@ void __init prom_meminit(void)
 		type = prom_memtype_classify(p->type);
 
 		add_memory_region(base, size, type);
+
+		if (type == BOOT_MEM_ROM_DATA) {
+			prom_mem_base[nr_prom_mem] = base;
+			prom_mem_size[nr_prom_mem] = size;
+			nr_prom_mem++;
+		}
 	}
 }
 
@@ -150,12 +162,8 @@ void __init prom_free_prom_memory(void)
 	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
 		return;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
+	for (i = 0; i < nr_prom_mem; i++) {
 		free_init_pages("prom memory",
-				addr, addr + boot_mem_map.map[i].size);
+			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
 	}
 }
-- 
2.22.0


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

* [PATCH 4/7] MIPS: malta: Drop prom_free_prom_memory
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (2 preceding siblings ...)
  2019-08-08  7:50 ` [PATCH 3/7] MIPS: fw: Record prom memory Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 5/7] MIPS: msp: Record prom memory Jiaxun Yang
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Current prom_free_prom_memory is freeing maps marked
as BOOT_MEM_ROM_DATA, however, nobody is exactly setting
this type for malta.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/mti-malta/malta-memory.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 868921adef1d..7c25a0a2345c 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -39,17 +39,6 @@ void __init fw_meminit(void)
 
 void __init prom_free_prom_memory(void)
 {
-	unsigned long addr;
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
-		free_init_pages("YAMON memory",
-				addr, addr + boot_mem_map.map[i].size);
-	}
 }
 
 phys_addr_t mips_cdmm_phys_base(void)
-- 
2.22.0


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

* [PATCH 5/7] MIPS: msp: Record prom memory
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (3 preceding siblings ...)
  2019-08-08  7:50 ` [PATCH 4/7] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-14 12:12   ` Serge Semin
  2019-08-08  7:50 ` [PATCH 6/7] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map is nolonger exist so we need to maintain a list
of prom memory by ourselves

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/pmcs-msp71xx/msp_prom.c | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c
index 6fdcb3d6fbb5..13a5eb47af94 100644
--- a/arch/mips/pmcs-msp71xx/msp_prom.c
+++ b/arch/mips/pmcs-msp71xx/msp_prom.c
@@ -61,6 +61,10 @@ int init_debug = 1;
 /* memory blocks */
 struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
 
+static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
+static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
+static unsigned int nr_prom_mem __initdata;
+
 /* default feature sets */
 static char msp_default_features[] =
 #if defined(CONFIG_PMC_MSP4200_EVAL) \
@@ -352,6 +356,12 @@ void __init prom_meminit(void)
 
 		add_memory_region(base, size, type);
 		p++;
+
+		if (type == BOOT_MEM_ROM_DATA) {
+			prom_mem_base[nr_prom_mem] = base;
+			prom_mem_size[nr_prom_mem] = size;
+			nr_prom_mem++;
+		}
 	}
 }
 
@@ -407,13 +417,9 @@ void __init prom_free_prom_memory(void)
 	envp[i] = NULL;			/* end array with null pointer */
 	prom_envp = envp;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
+	for (i = 0; i < nr_prom_mem; i++) {
 		free_init_pages("prom memory",
-				addr, addr + boot_mem_map.map[i].size);
+			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
 	}
 }
 
-- 
2.22.0


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

* [PATCH 6/7] MIPS: ip22: Drop addr_is_ram
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (4 preceding siblings ...)
  2019-08-08  7:50 ` [PATCH 5/7] MIPS: msp: Record prom memory Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-08  7:50 ` [PATCH 7/7] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

It can be replaced by memblock_is_region_memory.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/sgi-ip22/ip28-berr.c | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index c0cf7baee36d..d4150ab8d140 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -12,6 +12,7 @@
 #include <linux/sched/debug.h>
 #include <linux/sched/signal.h>
 #include <linux/seq_file.h>
+#include <linux/memblock.h>
 
 #include <asm/addrspace.h>
 #include <asm/traps.h>
@@ -300,23 +301,6 @@ static void print_buserr(const struct pt_regs *regs)
 	       field, regs->cp0_epc, field, regs->regs[31]);
 }
 
-/*
- * Check, whether MC's (virtual) DMA address caused the bus error.
- * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
- */
-
-static int addr_is_ram(unsigned long addr, unsigned sz)
-{
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long a = boot_mem_map.map[i].addr;
-		if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
-			return 1;
-	}
-	return 0;
-}
-
 static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 {
 	/* This is likely rather similar to correct code ;-) */
@@ -331,7 +315,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 			/* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
 			unsigned long pte = (lo >> 6) << 12; /* PTEBase */
 			pte += 8*((vaddr >> pgsz) & 0x1ff);
-			if (addr_is_ram(pte, 8)) {
+			if (memblock_is_region_memory(pte, 8)) {
 				/*
 				 * Note: Since DMA hardware does look up
 				 * translation on its own, this PTE *must*
-- 
2.22.0


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

* [PATCH 7/7] MIPS: xlp: Drop boot_mem_map
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (5 preceding siblings ...)
  2019-08-08  7:50 ` [PATCH 6/7] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
@ 2019-08-08  7:50 ` Jiaxun Yang
  2019-08-12  4:56 ` [EXTERNAL]Drop boot_mem_map Paul Burton
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-08  7:50 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Simply replace with memblock functions.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/netlogic/xlp/setup.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index f743fd9da323..1a0fc5b62ba4 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -34,6 +34,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of_fdt.h>
+#include <linux/memblock.h>
 
 #include <asm/idle.h>
 #include <asm/reboot.h>
@@ -67,12 +68,11 @@ static void nlm_linux_exit(void)
 static void nlm_fixup_mem(void)
 {
 	const int pref_backup = 512;
-	int i;
+	struct memblock_region *mem;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
-		boot_mem_map.map[i].size -= pref_backup;
+	for_each_memblock(memory, mem) {
+		memblock_remove(mem->base + mem->size - pref_backup,
+			pref_backup);
 	}
 }
 
@@ -110,7 +110,7 @@ void __init plat_mem_setup(void)
 	/* memory and bootargs from DT */
 	xlp_early_init_devtree();
 
-	if (boot_mem_map.nr_map == 0) {
+	if (memblock_end_of_DRAM() == 0) {
 		pr_info("Using DRAM BARs for memory map.\n");
 		xlp_init_mem_from_bars();
 	}
-- 
2.22.0


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

* Re: [EXTERNAL]Drop boot_mem_map
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (6 preceding siblings ...)
  2019-08-08  7:50 ` [PATCH 7/7] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
@ 2019-08-12  4:56 ` Paul Burton
  2019-08-12  5:28   ` Jiaxun Yang
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
  8 siblings, 1 reply; 31+ messages in thread
From: Paul Burton @ 2019-08-12  4:56 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc

Hi Jiaxun,

On Thu, Aug 08, 2019 at 03:50:06PM +0800, Jiaxun Yang wrote:
> Hi there:
> I was trying to make a generic NUMA implementation for ip27 and loongson-3,
> and the boot_mem_map without nid support become a barrier of merging memory
> init code.
> 
> Rather than add nid support to boot_mem_map, this patchset drops the whole
> boot_mem_map as it can be replaced by memblock functions.

Very nice - cleaning this up will be a neat improvement :)

Am I right to suspect though that patch 1 will break the build for all
platforms that make use of boot_mem_map? (ie. all the platforms touched
by later patches in this series)

Thanks,
    Paul

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

* Re: [EXTERNAL]Drop boot_mem_map
  2019-08-12  4:56 ` [EXTERNAL]Drop boot_mem_map Paul Burton
@ 2019-08-12  5:28   ` Jiaxun Yang
  2019-08-13  8:39     ` Serge Semin
  0 siblings, 1 reply; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-12  5:28 UTC (permalink / raw)
  To: Paul Burton
  Cc: linux-mips, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc


On 2019/8/12 下午12:56, Paul Burton wrote:
> Hi Jiaxun,
>
> On Thu, Aug 08, 2019 at 03:50:06PM +0800, Jiaxun Yang wrote:
>> Hi there:
>> I was trying to make a generic NUMA implementation for ip27 and loongson-3,
>> and the boot_mem_map without nid support become a barrier of merging memory
>> init code.
>>
>> Rather than add nid support to boot_mem_map, this patchset drops the whole
>> boot_mem_map as it can be replaced by memblock functions.
> Very nice - cleaning this up will be a neat improvement :)
>
> Am I right to suspect though that patch 1 will break the build for all
> platforms that make use of boot_mem_map? (ie. all the platforms touched
> by later patches in this series)

Yes. Rest of the set should fixed all the platforms.

You can verify by grep boot_mem_map tree-wide.

--

Jiaxun Yang


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

* Re: [EXTERNAL]Drop boot_mem_map
  2019-08-12  5:28   ` Jiaxun Yang
@ 2019-08-13  8:39     ` Serge Semin
  2019-08-13 15:09       ` Jiaxun Yang
  0 siblings, 1 reply; 31+ messages in thread
From: Serge Semin @ 2019-08-13  8:39 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: Paul Burton, linux-mips, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

Hello Jiaxun,

On Mon, Aug 12, 2019 at 01:28:19PM +0800, Jiaxun Yang wrote:
> 
> On 2019/8/12 下午12:56, Paul Burton wrote:
> > Hi Jiaxun,
> > 
> > On Thu, Aug 08, 2019 at 03:50:06PM +0800, Jiaxun Yang wrote:
> > > Hi there:
> > > I was trying to make a generic NUMA implementation for ip27 and loongson-3,
> > > and the boot_mem_map without nid support become a barrier of merging memory
> > > init code.
> > > 
> > > Rather than add nid support to boot_mem_map, this patchset drops the whole
> > > boot_mem_map as it can be replaced by memblock functions.
> > Very nice - cleaning this up will be a neat improvement :)
> > 
> > Am I right to suspect though that patch 1 will break the build for all
> > platforms that make use of boot_mem_map? (ie. all the platforms touched
> > by later patches in this series)
> 
> Yes. Rest of the set should fixed all the platforms.
> 
> You can verify by grep boot_mem_map tree-wide.
> 
> --
> 
> Jiaxun Yang
> 

The cleanup you did is great! I was going to do this myself when get to have
more free time. Thanks to you the only thing left is to review your work.

Regarding the Paul' comment about the platforms source code buildability in
patch 1. Alas it's a kernel patches requirement to leave the source code
buildable and the kernel runnable after each patch [1].

I am not sure about correct execution, but at least buildability can be reached
just by moving the patch 1 to the tail of the series.

Regarding the patches itself, I'll leave my comments inline within the
corresponding emails.

[1] https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L223

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

* Re: [EXTERNAL]Drop boot_mem_map
  2019-08-13  8:39     ` Serge Semin
@ 2019-08-13 15:09       ` Jiaxun Yang
  0 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-13 15:09 UTC (permalink / raw)
  To: Serge Semin
  Cc: Paul Burton, linux-mips, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc


On 2019/8/13 下午4:39, Serge Semin wrote:
> The cleanup you did is great! I was going to do this myself when get to have
> more free time. Thanks to you the only thing left is to review your work.
>
> Regarding the Paul' comment about the platforms source code buildability in
> patch 1. Alas it's a kernel patches requirement to leave the source code
> buildable and the kernel runnable after each patch [1].

Hi Serge:

Thanks for your remind.

I'm going to send v1 and correct the patch order after receiving your 
review tag.

> I am not sure about correct execution, but at least buildability can be reached
> just by moving the patch 1 to the tail of the series.
>
> Regarding the patches itself, I'll leave my comments inline within the
> corresponding emails.
>
> [1] https://elixir.bootlin.com/linux/latest/source/Documentation/process/submitting-patches.rst#L223

--

Jiaxun Yang


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

* Re: [PATCH 1/7] MIPS: init: Drop boot_mem_map
  2019-08-08  7:50 ` [PATCH 1/7] MIPS: init: " Jiaxun Yang
@ 2019-08-14 11:54   ` Serge Semin
  2019-08-14 13:40     ` Jiaxun Yang
  0 siblings, 1 reply; 31+ messages in thread
From: Serge Semin @ 2019-08-14 11:54 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

Hello Jiaxun,

On Thu, Aug 08, 2019 at 03:50:07PM +0800, Jiaxun Yang wrote:
> boot_mem_map was introduced very early and cannot handle memory maps
> with nid. Nowadays, memblock can exactly replace boot_mem_map.
> 

Seeing how much changes the patch introduces, the message doesn't explains
the way the replacement and cleanup is performed. I suggest to extend the
commit message with more descriptive text of what the patch does, what is
removed and why.
As an alternative for better readability the patch could be split up
into a series of smaller commits.

> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  arch/mips/include/asm/bootinfo.h |  15 --
>  arch/mips/kernel/setup.c         | 352 ++++++++-----------------------
>  arch/mips/mm/init.c              |  51 +----
>  3 files changed, 91 insertions(+), 327 deletions(-)
> 
> diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
> index 235bc2f52113..f711ccf7bace 100644
> --- a/arch/mips/include/asm/bootinfo.h
> +++ b/arch/mips/include/asm/bootinfo.h
> @@ -94,21 +94,6 @@ extern unsigned long mips_machtype;
>  #define BOOT_MEM_INIT_RAM	4
>  #define BOOT_MEM_NOMAP		5
>  
> -/*
> - * A memory map that's built upon what was determined
> - * or specified on the command line.
> - */
> -struct boot_mem_map {
> -	int nr_map;
> -	struct boot_mem_map_entry {
> -		phys_addr_t addr;	/* start of memory segment */
> -		phys_addr_t size;	/* size of memory segment */
> -		long type;		/* type of memory segment */
> -	} map[BOOT_MEM_MAP_MAX];
> -};
> -
> -extern struct boot_mem_map boot_mem_map;
> -
>  extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
>  extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min,  phys_addr_t sz_max);
>  
> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
> index ab349d2381c3..ceef8240f171 100644
> --- a/arch/mips/kernel/setup.c
> +++ b/arch/mips/kernel/setup.c
> @@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
>  
>  EXPORT_SYMBOL(mips_machtype);
>  
> -struct boot_mem_map boot_mem_map;
> -
>  static char __initdata command_line[COMMAND_LINE_SIZE];
>  char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
>  
> @@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET);
>  
>  void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
>  {
> -	int x = boot_mem_map.nr_map;
> -	int i;
> +	/*
> +	 * Note: This function only exists for historical reason,
> +	 * new code should use memblock_add or memblock_add_node instead.
> +	 */
>  

Since now we discourage to use this method to add the memory regions, what about
printing an info/warning regarding the function being deprecated, for instance
by using pr_*_once()? In addition, since you are going to mark this function
as deprecated, it's better to remove it' usage at least from the generic MIPS code:
arch/mips/kernel/setup.c
arch/mips/kernel/prom.c

On the other hand we can have a good use of this method. Since platforms are using
it to declare the whole memory space, we could perform the regions sanity checks right
here at add-time. For instance this concerns PHYS_OFFSET/PFN_OFFSET checks, HIGHMEM-related
test and so on. We could also perform the {max,min}_low_pfn, max_pfn, high{start,end}_pfn,
calculations right here. In this case the corresponding bootmem_init() code can be just
removed.

What do you think? Paul, your opinion?

>  	/*
>  	 * If the region reaches the top of the physical address space, adjust
> @@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
>  		return;
>  	}
>  
> -	/*
> -	 * Try to merge with existing entry, if any.
> -	 */
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		struct boot_mem_map_entry *entry = boot_mem_map.map + i;
> -		unsigned long top;
> -
> -		if (entry->type != type)
> -			continue;
> -
> -		if (start + size < entry->addr)
> -			continue;			/* no overlap */
> +	memblock_add(start, size);
> +	/* Reserve any memory except the ordinary RAM ranges. */
> +	switch (type) {
> +	case BOOT_MEM_RAM:
> +		break;
>  
> -		if (entry->addr + entry->size < start)
> -			continue;			/* no overlap */
> +	case BOOT_MEM_NOMAP: /* Discard the range from the system. */
> +		memblock_remove(start, size);
> +		break;
>  
> -		top = max(entry->addr + entry->size, start + size);
> -		entry->addr = min(entry->addr, start);
> -		entry->size = top - entry->addr;
> -
> -		return;
> +	default: /* Reserve the rest of the memory types at boot time */
> +		memblock_reserve(start, size);
> +		break;
>  	}
> -
> -	if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
> -		pr_err("Ooops! Too many entries in the memory map!\n");
> -		return;
> -	}
> -
> -	boot_mem_map.map[x].addr = start;
> -	boot_mem_map.map[x].size = size;
> -	boot_mem_map.map[x].type = type;
> -	boot_mem_map.nr_map++;
>  }
>  
>  void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
> @@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
>  	add_memory_region(start, size, BOOT_MEM_RAM);
>  }
>  
> -static bool __init __maybe_unused memory_region_available(phys_addr_t start,
> -							  phys_addr_t size)
> -{
> -	int i;
> -	bool in_ram = false, free = true;
> -
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		phys_addr_t start_, end_;
> -
> -		start_ = boot_mem_map.map[i].addr;
> -		end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
> -
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -			if (start >= start_ && start + size <= end_)
> -				in_ram = true;
> -			break;
> -		case BOOT_MEM_RESERVED:
> -		case BOOT_MEM_NOMAP:
> -			if ((start >= start_ && start < end_) ||
> -			    (start < start_ && start + size >= start_))
> -				free = false;
> -			break;
> -		default:
> -			continue;
> -		}
> -	}
> -
> -	return in_ram && free;
> -}
> -
> -static void __init print_memory_map(void)
> -{
> -	int i;
> -	const int field = 2 * sizeof(unsigned long);
> -
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
> -		       field, (unsigned long long) boot_mem_map.map[i].size,
> -		       field, (unsigned long long) boot_mem_map.map[i].addr);
> -
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -			printk(KERN_CONT "(usable)\n");
> -			break;
> -		case BOOT_MEM_INIT_RAM:
> -			printk(KERN_CONT "(usable after init)\n");
> -			break;
> -		case BOOT_MEM_ROM_DATA:
> -			printk(KERN_CONT "(ROM data)\n");
> -			break;
> -		case BOOT_MEM_RESERVED:
> -			printk(KERN_CONT "(reserved)\n");
> -			break;
> -		case BOOT_MEM_NOMAP:
> -			printk(KERN_CONT "(nomap)\n");
> -			break;
> -		default:
> -			printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
> -			break;
> -		}
> -	}
> -}
> -
>  /*
>   * Manage initrd
>   */
> @@ -376,8 +294,11 @@ static void __init bootmem_init(void)
>  
>  static void __init bootmem_init(void)
>  {
> -	phys_addr_t ramstart = PHYS_ADDR_MAX;
> -	int i;
> +	struct memblock_region *mem;
> +	phys_addr_t ramstart, ramend;
> +
> +	ramstart = memblock_start_of_DRAM();
> +	ramend = memblock_end_of_DRAM();
>  
>  	/*
>  	 * Sanity check any INITRD first. We don't take it into account
> @@ -398,115 +319,61 @@ static void __init bootmem_init(void)
>  	min_low_pfn = ~0UL;
>  	max_low_pfn = 0;

This initialization is pointless, since max_low_pfn is static and will be zero anyway,
while min_low_pfn will be reinitialized in the next few lines of code.

>  
> -	/* Find the highest and lowest page frame numbers we have available. */
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		unsigned long start, end;
> -
> -		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
> -			continue;
> +#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
> +	min_low_pfn = PFN_UP(ramstart);
> +	ARCH_PFN_OFFSET = PFN_UP(ramstart);
> +#else
> +	/*
> +	 * Reserve any memory between the start of RAM and PHYS_OFFSET
> +	 */
> +	if (PFN_UP(ramstart) > PHYS_OFFSET)
> +		memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);

PFN_UP gives you pfn, while PHYS_OFFSET is actual address offset. This is completely
wrong. The former condition was: "(ramstart > PHYS_OFFSET)".
As I see it, this condition could be combined with the next one.

In addition, you are reserving something, which isn't going to be in memory anyway.
Is this correct?

>  
> -		start = PFN_UP(boot_mem_map.map[i].addr);
> -		end = PFN_DOWN(boot_mem_map.map[i].addr
> -				+ boot_mem_map.map[i].size);
> +	if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
> +		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
> +			(unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)),
> +			(unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET));
> +	} else if (ARCH_PFN_OFFSET - PFN_UP(ramstart) > 0UL) {
> +		pr_info("%lu free pages won't be used\n",
> +			(unsigned long)(ARCH_PFN_OFFSET - PFN_UP(ramstart)));
> +	}
> +	min_low_pfn = ARCH_PFN_OFFSET;
> +#endif
>  
> -		ramstart = min(ramstart, boot_mem_map.map[i].addr);
> +	max_pfn = PFN_DOWN(ramend);

So the next loop is only used to calculate the max_low_pfn and min_low_pfn is
always set to ARCH_PFN_OFFSET, right?
Then as far as I could track the min_low_pfn usage, it isn't utilized that much
in the rest of the system. According to the following changes, you don't use it
after this place either. In this case saving any value in it might be just pointless.
Before your patch, the variable was used to save the lowest low-memory pfn boundary,
which then would be used to set the low memory limit. See the loop:
"Install all valid RAM ranges to the memblock memory region." But since you
removed it, there is no point in the code above. We might need to somehow change
the memoblock lower limit here as well.

> +	for_each_memblock(memory, mem) {
> +		unsigned long start = memblock_region_memory_base_pfn(mem);
> +		unsigned long end = memblock_region_memory_end_pfn(mem);
>  
> -#ifndef CONFIG_HIGHMEM
>  		/*
>  		 * Skip highmem here so we get an accurate max_low_pfn if low
>  		 * memory stops short of high memory.
>  		 * If the region overlaps HIGHMEM_START, end is clipped so
>  		 * max_pfn excludes the highmem portion.
>  		 */
> +		if (memblock_is_nomap(mem))
> +			continue;

Sorry, I don't see a reason why do we have to skip the nomap regions here.
Could you explain?

>  		if (start >= PFN_DOWN(HIGHMEM_START))
>  			continue;
>  		if (end > PFN_DOWN(HIGHMEM_START))
>  			end = PFN_DOWN(HIGHMEM_START);
> -#endif
> -
>  		if (end > max_low_pfn)
>  			max_low_pfn = end;
> -		if (start < min_low_pfn)
> -			min_low_pfn = start;
>  	}
>  
> -	if (min_low_pfn >= max_low_pfn)
> -		panic("Incorrect memory mapping !!!");

Hmm, removing this sanity check doesn't seem right. What if a platform code
haven't added any memory region?

> -
> -#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
> -	ARCH_PFN_OFFSET = PFN_UP(ramstart);
> -#else
> -	/*
> -	 * Reserve any memory between the start of RAM and PHYS_OFFSET
> -	 */
> -	if (ramstart > PHYS_OFFSET) {
> -		add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
> -				  BOOT_MEM_RESERVED);
> -		memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
> -	}
> -
> -	if (min_low_pfn > ARCH_PFN_OFFSET) {
> -		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
> -			(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
> -			min_low_pfn - ARCH_PFN_OFFSET);
> -	} else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) {
> -		pr_info("%lu free pages won't be used\n",
> -			ARCH_PFN_OFFSET - min_low_pfn);
> +#ifdef CONFIG_HIGHMEM
> +	if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
> +		highstart_pfn = max_low_pfn;
> +		highend_pfn = max_pfn;
>  	}
> -	min_low_pfn = ARCH_PFN_OFFSET;
>  #endif

Are you sure, that 'max_low_pfn' always ends up at the 'highstart_pfn'?
I am not. Even if 'max_pfn' is greater than HIGHMEM_START, since the memory
space may have wholes, the max_low_pfn might be initialized with something
smaller than HIGHMEM_START.

One more problem I see here. What happens if CONFIG_HIGHMEM is disabled and
max_pfn exceeds HIGHMEM_START? We'll end up with unreachable memory...

>  
>  	/*
> -	 * Determine low and high memory ranges
> +	 * In any case the added to the memblock memory regions
> +	 * (highmem/lowmem, available/reserved, etc) are considered
> +	 * as present, so inform sparsemem about them.
>  	 */
> -	max_pfn = max_low_pfn;
> -	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
> -#ifdef CONFIG_HIGHMEM
> -		highstart_pfn = PFN_DOWN(HIGHMEM_START);
> -		highend_pfn = max_low_pfn;
> -#endif
> -		max_low_pfn = PFN_DOWN(HIGHMEM_START);
> -	}
> -
> -	/* Install all valid RAM ranges to the memblock memory region */
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		unsigned long start, end;
> -
> -		start = PFN_UP(boot_mem_map.map[i].addr);
> -		end = PFN_DOWN(boot_mem_map.map[i].addr
> -				+ boot_mem_map.map[i].size);
> -
> -		if (start < min_low_pfn)
> -			start = min_low_pfn;
> -#ifndef CONFIG_HIGHMEM
> -		/* Ignore highmem regions if highmem is unsupported */
> -		if (end > max_low_pfn)
> -			end = max_low_pfn;
> -#endif

Here we used to set the memory limits if platform code defined something
invalid. Like unreachable memory or a memory less than PHYS_OFFSET.
Since this code is going to be removed, the system might end up with
incorrect memory layout.

> -		if (end <= start)
> -			continue;
> -
> -		memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
> -
> -		/* Reserve any memory except the ordinary RAM ranges. */
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -			break;
> -		case BOOT_MEM_NOMAP: /* Discard the range from the system. */
> -			memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start));
> -			continue;
> -		default: /* Reserve the rest of the memory types at boot time */
> -			memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start));
> -			break;
> -		}
> -
> -		/*
> -		 * In any case the added to the memblock memory regions
> -		 * (highmem/lowmem, available/reserved, etc) are considered
> -		 * as present, so inform sparsemem about them.
> -		 */
> -		memory_present(0, start, end);
> -	}
> +	memblocks_present();
>  
>  	/*
>  	 * Reserve initrd memory if needed.
> @@ -528,8 +395,9 @@ static int __init early_parse_mem(char *p)
>  	 * size.
>  	 */
>  	if (usermem == 0) {
> -		boot_mem_map.nr_map = 0;
>  		usermem = 1;
> +		memblock_remove(memblock_start_of_DRAM(),
> +			memblock_end_of_DRAM() - memblock_start_of_DRAM());
>  	}
>  	start = 0;
>  	size = memparse(p, &p);
> @@ -586,14 +454,13 @@ early_param("memmap", early_parse_memmap);
>  unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
>  static int __init early_parse_elfcorehdr(char *p)
>  {
> -	int i;
> +	struct memblock_region *mem;
>  
>  	setup_elfcorehdr = memparse(p, &p);
>  
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		unsigned long start = boot_mem_map.map[i].addr;
> -		unsigned long end = (boot_mem_map.map[i].addr +
> -				     boot_mem_map.map[i].size);
> +	 for_each_memblock(memory, mem) {
> +		unsigned long start = mem->base;
> +		unsigned long end = mem->end;
>  		if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
>  			/*
>  			 * Reserve from the elf core header to the end of
> @@ -613,47 +480,20 @@ static int __init early_parse_elfcorehdr(char *p)
>  early_param("elfcorehdr", early_parse_elfcorehdr);
>  #endif
>  
> -static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
> -{
> -	phys_addr_t size;
> -	int i;
> -
> -	size = end - mem;
> -	if (!size)
> -		return;
> -
> -	/* Make sure it is in the boot_mem_map */
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		if (mem >= boot_mem_map.map[i].addr &&
> -		    mem < (boot_mem_map.map[i].addr +
> -			   boot_mem_map.map[i].size))
> -			return;
> -	}
> -	add_memory_region(mem, size, type);
> -}
> -
>  #ifdef CONFIG_KEXEC
> -static inline unsigned long long get_total_mem(void)
> -{
> -	unsigned long long total;
> -
> -	total = max_pfn - min_low_pfn;
> -	return total << PAGE_SHIFT;
> -}
> -
>  static void __init mips_parse_crashkernel(void)
>  {
>  	unsigned long long total_mem;
>  	unsigned long long crash_size, crash_base;
>  	int ret;
>  
> -	total_mem = get_total_mem();
> +	total_mem = memblock_phys_mem_size();
>  	ret = parse_crashkernel(boot_command_line, total_mem,
>  				&crash_size, &crash_base);
>  	if (ret != 0 || crash_size <= 0)
>  		return;
>  
> -	if (!memory_region_available(crash_base, crash_size)) {
> +	if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) {
>  		pr_warn("Invalid memory region reserved for crash kernel\n");
>  		return;
>  	}
> @@ -686,6 +526,17 @@ static void __init request_crashkernel(struct resource *res)
>  }
>  #endif /* !defined(CONFIG_KEXEC)  */
>  
> +static void __init check_kernel_sections_mem(void)
> +{
> +	phys_addr_t start = PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT;
> +	phys_addr_t size = (PFN_UP(__pa_symbol(&_end)) - start) << PAGE_SHIFT;
> +
> +	if (!memblock_is_region_memory(start, size)) {
> +		pr_info("Kernel sections are not in the memory maps\n");
> +		memblock_add(start, size);
> +	}
> +}
> +
>  #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
>  #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
>  #define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
> @@ -731,25 +582,6 @@ static void __init arch_mem_init(char **cmdline_p)
>  	plat_mem_setup();
>  	memblock_set_bottom_up(true);
>  
> -	/*
> -	 * Make sure all kernel memory is in the maps.  The "UP" and
> -	 * "DOWN" are opposite for initdata since if it crosses over
> -	 * into another memory section you don't want that to be
> -	 * freed when the initdata is freed.
> -	 */
> -	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
> -			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
> -			 BOOT_MEM_RAM);
> -	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
> -			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
> -			 BOOT_MEM_INIT_RAM);
> -	arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT,
> -			 PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT,
> -			 BOOT_MEM_RAM);
> -

I see you replaced this code with check_kernel_sections_mem(). Neat.
You could also replace "<< PAGE_SHIFT" with PFN_PHYS() macro in the function.

> -	pr_info("Determined physical RAM map:\n");
> -	print_memory_map();

I'll miss you "print_memory_map()"... =) Nothing is going to print a detected
physical memory layout at boot time. Someone might disagree, but I found this
very useful...

> -
>  #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
>  	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
>  #else
> @@ -783,14 +615,17 @@ static void __init arch_mem_init(char **cmdline_p)
>  
>  	parse_early_param();
>  
> -	if (usermem) {
> -		pr_info("User-defined physical RAM map:\n");
> -		print_memory_map();
> -	}
> +	if (usermem)
> +		pr_info("User-defined physical RAM map overwrite\n");
> +
> +	check_kernel_sections_mem();
>  
>  	early_init_fdt_reserve_self();
>  	early_init_fdt_scan_reserved_mem();
>  
> +#ifndef CONFIG_NUMA
> +	memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
> +#endif
>  	bootmem_init();
>  
>  	/*
> @@ -835,7 +670,7 @@ static void __init arch_mem_init(char **cmdline_p)
>  
>  static void __init resource_init(void)
>  {
> -	int i;
> +	struct memblock_region *region;
>  
>  	if (UNCAC_BASE != IO_BASE)
>  		return;
> @@ -847,16 +682,10 @@ static void __init resource_init(void)
>  	bss_resource.start = __pa_symbol(&__bss_start);
>  	bss_resource.end = __pa_symbol(&__bss_stop) - 1;
>  
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> +	for_each_memblock(memory, region) {
> +		phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
> +		phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;

I haven't seen __pfn_to_phys() macro usage in the MIPS code. Instead the upper-case
versions (PFN_PHYS()/PHYS_PFN()) are utilized. It might be better to follow the
MIPS-platform way. They are identical at this moment though. Paul?

>  		struct resource *res;
> -		unsigned long start, end;
> -
> -		start = boot_mem_map.map[i].addr;
> -		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
> -		if (start >= HIGHMEM_START)
> -			continue;
> -		if (end >= HIGHMEM_START)
> -			end = HIGHMEM_START - 1;
>  
>  		res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
>  		if (!res)
> @@ -865,20 +694,7 @@ static void __init resource_init(void)
>  
>  		res->start = start;
>  		res->end = end;
> -		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
> -
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -		case BOOT_MEM_INIT_RAM:
> -		case BOOT_MEM_ROM_DATA:
> -			res->name = "System RAM";

Is that right to also discard the "System RAM" resource name?

> -			res->flags |= IORESOURCE_SYSRAM;
> -			break;
> -		case BOOT_MEM_RESERVED:
> -		case BOOT_MEM_NOMAP:
> -		default:
> -			res->name = "reserved";
> -		}
> +		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
>  
>  		request_resource(&iomem_resource, res);
>  
> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
> index 8a038b30d3c4..2bb8ebf0d2d5 100644
> --- a/arch/mips/mm/init.c
> +++ b/arch/mips/mm/init.c
> @@ -271,25 +271,17 @@ void __init fixrange_init(unsigned long start, unsigned long end,
>  
>  unsigned __weak platform_maar_init(unsigned num_pairs)
>  {
> -	struct maar_config cfg[BOOT_MEM_MAP_MAX];
> -	unsigned i, num_configured, num_cfg = 0;
> -
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -		case BOOT_MEM_INIT_RAM:
> -			break;
> -		default:
> -			continue;
> -		}
> +	struct maar_config cfg[32];
> +	unsigned int num_configured, num_cfg = 0;
> +	struct memblock_region *mem;
>  
> +	for_each_memblock(memory, mem) {
>  		/* Round lower up */
> -		cfg[num_cfg].lower = boot_mem_map.map[i].addr;
> +		cfg[num_cfg].lower = __pfn_to_phys(memblock_region_memory_base_pfn(mem));

The same thing with PFN_PHYS()/PHYS_PFN().

>  		cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
>  
>  		/* Round upper down */
> -		cfg[num_cfg].upper = boot_mem_map.map[i].addr +
> -					boot_mem_map.map[i].size;
> +		cfg[num_cfg].upper = __pfn_to_phys(memblock_region_memory_end_pfn(mem));

PFN_PHYS()/PHYS_PFN() again.

>  		cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
>  
>  		cfg[num_cfg].attrs = MIPS_MAAR_S;
> @@ -382,33 +374,6 @@ void maar_init(void)
>  }
>  
>  #ifndef CONFIG_NEED_MULTIPLE_NODES
> -int page_is_ram(unsigned long pagenr)
> -{
> -	int i;
> -
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		unsigned long addr, end;
> -
> -		switch (boot_mem_map.map[i].type) {
> -		case BOOT_MEM_RAM:
> -		case BOOT_MEM_INIT_RAM:
> -			break;
> -		default:
> -			/* not usable memory */
> -			continue;
> -		}
> -
> -		addr = PFN_UP(boot_mem_map.map[i].addr);
> -		end = PFN_DOWN(boot_mem_map.map[i].addr +
> -			       boot_mem_map.map[i].size);
> -
> -		if (pagenr >= addr && pagenr < end)
> -			return 1;
> -	}
> -
> -	return 0;
> -}
> -
>  void __init paging_init(void)
>  {
>  	unsigned long max_zone_pfns[MAX_NR_ZONES];
> @@ -452,9 +417,7 @@ static inline void mem_init_free_highmem(void)
>  		return;
>  
>  	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
> -		struct page *page = pfn_to_page(tmp);
> -
> -		if (!page_is_ram(tmp))
> +		if (!memblock_is_memory(PFN_PHYS(tmp)))

See. You've used PFN_PHYS() here instead of __pfn_to_phys().

-Sergey

>  			SetPageReserved(page);
>  		else
>  			free_highmem_page(page);
> -- 
> 2.22.0
> 

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

* Re: [PATCH 3/7] MIPS: fw: Record prom memory
  2019-08-08  7:50 ` [PATCH 3/7] MIPS: fw: Record prom memory Jiaxun Yang
@ 2019-08-14 12:03   ` Serge Semin
  2019-08-14 12:50     ` Thomas Bogendoerfer
  2019-08-14 13:45     ` Jiaxun Yang
  0 siblings, 2 replies; 31+ messages in thread
From: Serge Semin @ 2019-08-14 12:03 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

On Thu, Aug 08, 2019 at 03:50:09PM +0800, Jiaxun Yang wrote:
> boot_mem_map is nolonger exist so we need to maintain a list
> of prom memory by ourselves.
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  arch/mips/fw/arc/memory.c | 20 ++++++++++++++------
>  1 file changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
> index 429b7f8d2aeb..02e954b3700e 100644
> --- a/arch/mips/fw/arc/memory.c
> +++ b/arch/mips/fw/arc/memory.c
> @@ -27,6 +27,11 @@
>  
>  #undef DEBUG
>  
> +#define MAX_PROM_MEM 5
> +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
> +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
> +static unsigned int nr_prom_mem __initdata;
> +
>  /*
>   * For ARC firmware memory functions the unit of meassuring memory is always
>   * a 4k page of memory
> @@ -129,6 +134,7 @@ void __init prom_meminit(void)
>  	}
>  #endif
>  
> +	nr_prom_mem = 0;
>  	p = PROM_NULL_MDESC;
>  	while ((p = ArcGetMemoryDescriptor(p))) {
>  		unsigned long base, size;
> @@ -139,6 +145,12 @@ void __init prom_meminit(void)
>  		type = prom_memtype_classify(p->type);
>  
>  		add_memory_region(base, size, type);
> +
> +		if (type == BOOT_MEM_ROM_DATA) {
> +			prom_mem_base[nr_prom_mem] = base;
> +			prom_mem_size[nr_prom_mem] = size;
> +			nr_prom_mem++;

Are you sure, that five prom-mem regions is enough? What about adding
a sanity check here so no to exceed the array size?

-Sergey

> +		}
>  	}
>  }
>  
> @@ -150,12 +162,8 @@ void __init prom_free_prom_memory(void)
>  	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
>  		return;
>  
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
> -			continue;
> -
> -		addr = boot_mem_map.map[i].addr;
> +	for (i = 0; i < nr_prom_mem; i++) {
>  		free_init_pages("prom memory",
> -				addr, addr + boot_mem_map.map[i].size);
> +			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
>  	}
>  }
> -- 
> 2.22.0
> 

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

* Re: [PATCH 5/7] MIPS: msp: Record prom memory
  2019-08-08  7:50 ` [PATCH 5/7] MIPS: msp: Record prom memory Jiaxun Yang
@ 2019-08-14 12:12   ` Serge Semin
  0 siblings, 0 replies; 31+ messages in thread
From: Serge Semin @ 2019-08-14 12:12 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

On Thu, Aug 08, 2019 at 03:50:11PM +0800, Jiaxun Yang wrote:
> boot_mem_map is nolonger exist so we need to maintain a list
> of prom memory by ourselves
> 
> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> ---
>  arch/mips/pmcs-msp71xx/msp_prom.c | 18 ++++++++++++------
>  1 file changed, 12 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c
> index 6fdcb3d6fbb5..13a5eb47af94 100644
> --- a/arch/mips/pmcs-msp71xx/msp_prom.c
> +++ b/arch/mips/pmcs-msp71xx/msp_prom.c
> @@ -61,6 +61,10 @@ int init_debug = 1;
>  /* memory blocks */
>  struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
>  
> +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
> +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
> +static unsigned int nr_prom_mem __initdata;
> +
>  /* default feature sets */
>  static char msp_default_features[] =
>  #if defined(CONFIG_PMC_MSP4200_EVAL) \
> @@ -352,6 +356,12 @@ void __init prom_meminit(void)
>  
>  		add_memory_region(base, size, type);
>  		p++;
> +
> +		if (type == BOOT_MEM_ROM_DATA) {
> +			prom_mem_base[nr_prom_mem] = base;
> +			prom_mem_size[nr_prom_mem] = size;
> +			nr_prom_mem++;

The same as for FW_ARC. I suggest to add a sanity check here as well.

-Sergey

> +		}
>  	}
>  }
>  
> @@ -407,13 +417,9 @@ void __init prom_free_prom_memory(void)
>  	envp[i] = NULL;			/* end array with null pointer */
>  	prom_envp = envp;
>  
> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
> -		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
> -			continue;
> -
> -		addr = boot_mem_map.map[i].addr;
> +	for (i = 0; i < nr_prom_mem; i++) {
>  		free_init_pages("prom memory",
> -				addr, addr + boot_mem_map.map[i].size);
> +			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
>  	}
>  }
>  
> -- 
> 2.22.0
> 

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

* Re: [PATCH 3/7] MIPS: fw: Record prom memory
  2019-08-14 12:03   ` Serge Semin
@ 2019-08-14 12:50     ` Thomas Bogendoerfer
  2019-08-14 13:45     ` Jiaxun Yang
  1 sibling, 0 replies; 31+ messages in thread
From: Thomas Bogendoerfer @ 2019-08-14 12:50 UTC (permalink / raw)
  To: Serge Semin
  Cc: Jiaxun Yang, linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

On Wed, Aug 14, 2019 at 03:03:41PM +0300, Serge Semin wrote:
> On Thu, Aug 08, 2019 at 03:50:09PM +0800, Jiaxun Yang wrote:
> > boot_mem_map is nolonger exist so we need to maintain a list
> > of prom memory by ourselves.
> > 
> > Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> > ---
> >  arch/mips/fw/arc/memory.c | 20 ++++++++++++++------
> >  1 file changed, 14 insertions(+), 6 deletions(-)
> > 
> > diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
> > index 429b7f8d2aeb..02e954b3700e 100644
> > --- a/arch/mips/fw/arc/memory.c
> > +++ b/arch/mips/fw/arc/memory.c
> > @@ -27,6 +27,11 @@
> >  
> >  #undef DEBUG
> >  
> > +#define MAX_PROM_MEM 5
> > +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
> > +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
> > +static unsigned int nr_prom_mem __initdata;
> > +
> >  /*
> >   * For ARC firmware memory functions the unit of meassuring memory is always
> >   * a 4k page of memory
> > @@ -129,6 +134,7 @@ void __init prom_meminit(void)
> >  	}
> >  #endif
> >  
> > +	nr_prom_mem = 0;
> >  	p = PROM_NULL_MDESC;
> >  	while ((p = ArcGetMemoryDescriptor(p))) {
> >  		unsigned long base, size;
> > @@ -139,6 +145,12 @@ void __init prom_meminit(void)
> >  		type = prom_memtype_classify(p->type);
> >  
> >  		add_memory_region(base, size, type);
> > +
> > +		if (type == BOOT_MEM_ROM_DATA) {
> > +			prom_mem_base[nr_prom_mem] = base;
> > +			prom_mem_size[nr_prom_mem] = size;
> > +			nr_prom_mem++;
> 
> Are you sure, that five prom-mem regions is enough?

it's not enough:

ARCH: Microsoft-Jazz
PROMLIB: ARC firmware Version 1 Revision 1
CPU revision is: 00000430
FPU revision is: 00000500
Determined physical RAM map:
 memory: 00054000 @ 00000000 (reserved)
 memory: 0002c000 @ 00054000 (usable)
 memory: 0001f000 @ 007e0000 (ROM data)
 memory: 007b2000 @ 007ff000 (usable)
 memory: 0004f000 @ 00fb1000 (ROM data)
 memory: 01000000 @ 01000000 (usable)
 memory: 00323000 @ 00080000 (reserved)
 memory: 0043d000 @ 003a3000 (usable)

that's from a Olivetti M700 system.

Thomas.

-- 
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea.                                                [ RFC1925, 2.3 ]

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

* Re: [PATCH 1/7] MIPS: init: Drop boot_mem_map
  2019-08-14 11:54   ` Serge Semin
@ 2019-08-14 13:40     ` Jiaxun Yang
  0 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-14 13:40 UTC (permalink / raw)
  To: Serge Semin
  Cc: linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc


On 2019/8/14 下午7:54, Serge Semin wrote:
> Hello Jiaxun,
>
> On Thu, Aug 08, 2019 at 03:50:07PM +0800, Jiaxun Yang wrote:
>> boot_mem_map was introduced very early and cannot handle memory maps
>> with nid. Nowadays, memblock can exactly replace boot_mem_map.
>>
> Seeing how much changes the patch introduces, the message doesn't explains
> the way the replacement and cleanup is performed. I suggest to extend the
> commit message with more descriptive text of what the patch does, what is
> removed and why.

Hi Serge.

I'm going to split maar part from this patch. But I think it's fine to 
keep remaining part together. As it's almost impossible to keep code 
runnable without putting them together.

> As an alternative for better readability the patch could be split up
> into a series of smaller commits.
>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>>   arch/mips/include/asm/bootinfo.h |  15 --
>>   arch/mips/kernel/setup.c         | 352 ++++++++-----------------------
>>   arch/mips/mm/init.c              |  51 +----
>>   3 files changed, 91 insertions(+), 327 deletions(-)
>>
>> diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
>> index 235bc2f52113..f711ccf7bace 100644
>> --- a/arch/mips/include/asm/bootinfo.h
>> +++ b/arch/mips/include/asm/bootinfo.h
>> @@ -94,21 +94,6 @@ extern unsigned long mips_machtype;
>>   #define BOOT_MEM_INIT_RAM	4
>>   #define BOOT_MEM_NOMAP		5
>>   
>> -/*
>> - * A memory map that's built upon what was determined
>> - * or specified on the command line.
>> - */
>> -struct boot_mem_map {
>> -	int nr_map;
>> -	struct boot_mem_map_entry {
>> -		phys_addr_t addr;	/* start of memory segment */
>> -		phys_addr_t size;	/* size of memory segment */
>> -		long type;		/* type of memory segment */
>> -	} map[BOOT_MEM_MAP_MAX];
>> -};
>> -
>> -extern struct boot_mem_map boot_mem_map;
>> -
>>   extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
>>   extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min,  phys_addr_t sz_max);
>>   
>> diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
>> index ab349d2381c3..ceef8240f171 100644
>> --- a/arch/mips/kernel/setup.c
>> +++ b/arch/mips/kernel/setup.c
>> @@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
>>   
>>   EXPORT_SYMBOL(mips_machtype);
>>   
>> -struct boot_mem_map boot_mem_map;
>> -
>>   static char __initdata command_line[COMMAND_LINE_SIZE];
>>   char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
>>   
>> @@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET);
>>   
>>   void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
>>   {
>> -	int x = boot_mem_map.nr_map;
>> -	int i;
>> +	/*
>> +	 * Note: This function only exists for historical reason,
>> +	 * new code should use memblock_add or memblock_add_node instead.
>> +	 */
>>   
> Since now we discourage to use this method to add the memory regions, what about
> printing an info/warning regarding the function being deprecated, for instance
> by using pr_*_once()? In addition, since you are going to mark this function
> as deprecated, it's better to remove it' usage at least from the generic MIPS code:
> arch/mips/kernel/setup.c
> arch/mips/kernel/prom.c
>
> On the other hand we can have a good use of this method. Since platforms are using
> it to declare the whole memory space, we could perform the regions sanity checks right
> here at add-time. For instance this concerns PHYS_OFFSET/PFN_OFFSET checks, HIGHMEM-related
> test and so on. We could also perform the {max,min}_low_pfn, max_pfn, high{start,end}_pfn,
> calculations right here. In this case the corresponding bootmem_init() code can be just
> removed.

As my universal target is to simplify the NUMA memory initialization, 
without add "nid" to this function, I don't think it is a good idea to 
keep it.

But the conversion from this function to memblock is not that urgent, 
probably not worthy to give a warning.

>
> What do you think? Paul, your opinion?
>
>>   	/*
>>   	 * If the region reaches the top of the physical address space, adjust
>> @@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
>>   		return;
>>   	}
>>   
>> -	/*
>> -	 * Try to merge with existing entry, if any.
>> -	 */
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		struct boot_mem_map_entry *entry = boot_mem_map.map + i;
>> -		unsigned long top;
>> -
>> -		if (entry->type != type)
>> -			continue;
>> -
>> -		if (start + size < entry->addr)
>> -			continue;			/* no overlap */
>> +	memblock_add(start, size);
>> +	/* Reserve any memory except the ordinary RAM ranges. */
>> +	switch (type) {
>> +	case BOOT_MEM_RAM:
>> +		break;
>>   
>> -		if (entry->addr + entry->size < start)
>> -			continue;			/* no overlap */
>> +	case BOOT_MEM_NOMAP: /* Discard the range from the system. */
>> +		memblock_remove(start, size);
>> +		break;
>>   
>> -		top = max(entry->addr + entry->size, start + size);
>> -		entry->addr = min(entry->addr, start);
>> -		entry->size = top - entry->addr;
>> -
>> -		return;
>> +	default: /* Reserve the rest of the memory types at boot time */
>> +		memblock_reserve(start, size);
>> +		break;
>>   	}
>> -
>> -	if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
>> -		pr_err("Ooops! Too many entries in the memory map!\n");
>> -		return;
>> -	}
>> -
>> -	boot_mem_map.map[x].addr = start;
>> -	boot_mem_map.map[x].size = size;
>> -	boot_mem_map.map[x].type = type;
>> -	boot_mem_map.nr_map++;
>>   }
>>   
>>   void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
>> @@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
>>   	add_memory_region(start, size, BOOT_MEM_RAM);
>>   }
>>   
>> -static bool __init __maybe_unused memory_region_available(phys_addr_t start,
>> -							  phys_addr_t size)
>> -{
>> -	int i;
>> -	bool in_ram = false, free = true;
>> -
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		phys_addr_t start_, end_;
>> -
>> -		start_ = boot_mem_map.map[i].addr;
>> -		end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
>> -
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -			if (start >= start_ && start + size <= end_)
>> -				in_ram = true;
>> -			break;
>> -		case BOOT_MEM_RESERVED:
>> -		case BOOT_MEM_NOMAP:
>> -			if ((start >= start_ && start < end_) ||
>> -			    (start < start_ && start + size >= start_))
>> -				free = false;
>> -			break;
>> -		default:
>> -			continue;
>> -		}
>> -	}
>> -
>> -	return in_ram && free;
>> -}
>> -
>> -static void __init print_memory_map(void)
>> -{
>> -	int i;
>> -	const int field = 2 * sizeof(unsigned long);
>> -
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
>> -		       field, (unsigned long long) boot_mem_map.map[i].size,
>> -		       field, (unsigned long long) boot_mem_map.map[i].addr);
>> -
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -			printk(KERN_CONT "(usable)\n");
>> -			break;
>> -		case BOOT_MEM_INIT_RAM:
>> -			printk(KERN_CONT "(usable after init)\n");
>> -			break;
>> -		case BOOT_MEM_ROM_DATA:
>> -			printk(KERN_CONT "(ROM data)\n");
>> -			break;
>> -		case BOOT_MEM_RESERVED:
>> -			printk(KERN_CONT "(reserved)\n");
>> -			break;
>> -		case BOOT_MEM_NOMAP:
>> -			printk(KERN_CONT "(nomap)\n");
>> -			break;
>> -		default:
>> -			printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
>> -			break;
>> -		}
>> -	}
>> -}
>> -
>>   /*
>>    * Manage initrd
>>    */
>> @@ -376,8 +294,11 @@ static void __init bootmem_init(void)
>>   
>>   static void __init bootmem_init(void)
>>   {
>> -	phys_addr_t ramstart = PHYS_ADDR_MAX;
>> -	int i;
>> +	struct memblock_region *mem;
>> +	phys_addr_t ramstart, ramend;
>> +
>> +	ramstart = memblock_start_of_DRAM();	
>> +	ramend = memblock_end_of_DRAM();
>>   
>>   	/*
>>   	 * Sanity check any INITRD first. We don't take it into account
>> @@ -398,115 +319,61 @@ static void __init bootmem_init(void)
>>   	min_low_pfn = ~0UL;
>>   	max_low_pfn = 0;
> This initialization is pointless, since max_low_pfn is static and will be zero anyway,
> while min_low_pfn will be reinitialized in the next few lines of code.
I'm going to remove it, nobody knows why it exist.
>
>>   
>> -	/* Find the highest and lowest page frame numbers we have available. */
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		unsigned long start, end;
>> -
>> -		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
>> -			continue;
>> +#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
>> +	min_low_pfn = PFN_UP(ramstart);
>> +	ARCH_PFN_OFFSET = PFN_UP(ramstart);
>> +#else
>> +	/*
>> +	 * Reserve any memory between the start of RAM and PHYS_OFFSET
>> +	 */
>> +	if (PFN_UP(ramstart) > PHYS_OFFSET)
>> +		memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
> PFN_UP gives you pfn, while PHYS_OFFSET is actual address offset. This is completely
> wrong. The former condition was: "(ramstart > PHYS_OFFSET)".
> As I see it, this condition could be combined with the next one.
My fault, will fix it.
>
> In addition, you are reserving something, which isn't going to be in memory anyway.
> Is this correct?
Yes, for memblock it should be safe to reserve it. Or probably removing 
it is better?
>
>>   
>> -		start = PFN_UP(boot_mem_map.map[i].addr);
>> -		end = PFN_DOWN(boot_mem_map.map[i].addr
>> -				+ boot_mem_map.map[i].size);
>> +	if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
>> +		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
>> +			(unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)),
>> +			(unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET));
>> +	} else if (ARCH_PFN_OFFSET - PFN_UP(ramstart) > 0UL) {
>> +		pr_info("%lu free pages won't be used\n",
>> +			(unsigned long)(ARCH_PFN_OFFSET - PFN_UP(ramstart)));
>> +	}
>> +	min_low_pfn = ARCH_PFN_OFFSET;
>> +#endif
>>   
>> -		ramstart = min(ramstart, boot_mem_map.map[i].addr);
>> +	max_pfn = PFN_DOWN(ramend);
> So the next loop is only used to calculate the max_low_pfn and min_low_pfn is
> always set to ARCH_PFN_OFFSET, right?
> Then as far as I could track the min_low_pfn usage, it isn't utilized that much
> in the rest of the system. According to the following changes, you don't use it
> after this place either. In this case saving any value in it might be just pointless.
> Before your patch, the variable was used to save the lowest low-memory pfn boundary,
> which then would be used to set the low memory limit. See the loop:
> "Install all valid RAM ranges to the memblock memory region." But since you
> removed it, there is no point in the code above. We might need to somehow change
> the memoblock lower limit here as well.
Got it, thanks.
>
>> +	for_each_memblock(memory, mem) {
>> +		unsigned long start = memblock_region_memory_base_pfn(mem);
>> +		unsigned long end = memblock_region_memory_end_pfn(mem);
>>   
>> -#ifndef CONFIG_HIGHMEM
>>   		/*
>>   		 * Skip highmem here so we get an accurate max_low_pfn if low
>>   		 * memory stops short of high memory.
>>   		 * If the region overlaps HIGHMEM_START, end is clipped so
>>   		 * max_pfn excludes the highmem portion.
>>   		 */
>> +		if (memblock_is_nomap(mem))
>> +			continue;
> Sorry, I don't see a reason why do we have to skip the nomap regions here.
> Could you explain?

As the origin code have:

         if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
             continue;

>
>>   		if (start >= PFN_DOWN(HIGHMEM_START))
>>   			continue;
>>   		if (end > PFN_DOWN(HIGHMEM_START))
>>   			end = PFN_DOWN(HIGHMEM_START);
>> -#endif
>> -
>>   		if (end > max_low_pfn)
>>   			max_low_pfn = end;
>> -		if (start < min_low_pfn)
>> -			min_low_pfn = start;
>>   	}
>>   
>> -	if (min_low_pfn >= max_low_pfn)
>> -		panic("Incorrect memory mapping !!!");
> Hmm, removing this sanity check doesn't seem right. What if a platform code
> haven't added any memory region?

This won't happen unless platform didn't add any low mem.

>
>> -
>> -#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
>> -	ARCH_PFN_OFFSET = PFN_UP(ramstart);
>> -#else
>> -	/*
>> -	 * Reserve any memory between the start of RAM and PHYS_OFFSET
>> -	 */
>> -	if (ramstart > PHYS_OFFSET) {
>> -		add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
>> -				  BOOT_MEM_RESERVED);
>> -		memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
>> -	}
>> -
>> -	if (min_low_pfn > ARCH_PFN_OFFSET) {
>> -		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
>> -			(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
>> -			min_low_pfn - ARCH_PFN_OFFSET);
>> -	} else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) {
>> -		pr_info("%lu free pages won't be used\n",
>> -			ARCH_PFN_OFFSET - min_low_pfn);
>> +#ifdef CONFIG_HIGHMEM
>> +	if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
>> +		highstart_pfn = max_low_pfn;
>> +		highend_pfn = max_pfn;
>>   	}
>> -	min_low_pfn = ARCH_PFN_OFFSET;
>>   #endif
> Are you sure, that 'max_low_pfn' always ends up at the 'highstart_pfn'?
> I am not. Even if 'max_pfn' is greater than HIGHMEM_START, since the memory
> space may have wholes, the max_low_pfn might be initialized with something
> smaller than HIGHMEM_START.

In mm/memory.c it mentions  max_low_pfn and highstart_pfn must be the same

But it should be a x86-only requirement.

Should I fix it?

> One more problem I see here. What happens if CONFIG_HIGHMEM is disabled and
> max_pfn exceeds HIGHMEM_START? We'll end up with unreachable memory...
I'm going to set max_pfn = HIGHMEM_START if max_pfn > HIGGMEM_START 
while HIGHMEM disabled.

>>   
>>   	/*
>> -	 * Determine low and high memory ranges
>> +	 * In any case the added to the memblock memory regions
>> +	 * (highmem/lowmem, available/reserved, etc) are considered
>> +	 * as present, so inform sparsemem about them.
>>   	 */
>> -	max_pfn = max_low_pfn;
>> -	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
>> -#ifdef CONFIG_HIGHMEM
>> -		highstart_pfn = PFN_DOWN(HIGHMEM_START);
>> -		highend_pfn = max_low_pfn;
>> -#endif
>> -		max_low_pfn = PFN_DOWN(HIGHMEM_START);
>> -	}
>> -
>> -	/* Install all valid RAM ranges to the memblock memory region */
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		unsigned long start, end;
>> -
>> -		start = PFN_UP(boot_mem_map.map[i].addr);
>> -		end = PFN_DOWN(boot_mem_map.map[i].addr
>> -				+ boot_mem_map.map[i].size);
>> -
>> -		if (start < min_low_pfn)
>> -			start = min_low_pfn;
>> -#ifndef CONFIG_HIGHMEM
>> -		/* Ignore highmem regions if highmem is unsupported */
>> -		if (end > max_low_pfn)
>> -			end = max_low_pfn;
>> -#endif
> Here we used to set the memory limits if platform code defined something
> invalid. Like unreachable memory or a memory less than PHYS_OFFSET.
> Since this code is going to be removed, the system might end up with
> incorrect memory layout.
Memblock won't allow something like this happen, never.
>
>> -		if (end <= start)
>> -			continue;
>> -
>> -		memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
>> -
>> -		/* Reserve any memory except the ordinary RAM ranges. */
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -			break;
>> -		case BOOT_MEM_NOMAP: /* Discard the range from the system. */
>> -			memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start));
>> -			continue;
>> -		default: /* Reserve the rest of the memory types at boot time */
>> -			memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start));
>> -			break;
>> -		}
>> -
>> -		/*
>> -		 * In any case the added to the memblock memory regions
>> -		 * (highmem/lowmem, available/reserved, etc) are considered
>> -		 * as present, so inform sparsemem about them.
>> -		 */
>> -		memory_present(0, start, end);
>> -	}
>> +	memblocks_present();
>>   
>>   	/*
>>   	 * Reserve initrd memory if needed.
>> @@ -528,8 +395,9 @@ static int __init early_parse_mem(char *p)
>>   	 * size.
>>   	 */
>>   	if (usermem == 0) {
>> -		boot_mem_map.nr_map = 0;
>>   		usermem = 1;
>> +		memblock_remove(memblock_start_of_DRAM(),
>> +			memblock_end_of_DRAM() - memblock_start_of_DRAM());
>>   	}
>>   	start = 0;
>>   	size = memparse(p, &p);
>> @@ -586,14 +454,13 @@ early_param("memmap", early_parse_memmap);
>>   unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
>>   static int __init early_parse_elfcorehdr(char *p)
>>   {
>> -	int i;
>> +	struct memblock_region *mem;
>>   
>>   	setup_elfcorehdr = memparse(p, &p);
>>   
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		unsigned long start = boot_mem_map.map[i].addr;
>> -		unsigned long end = (boot_mem_map.map[i].addr +
>> -				     boot_mem_map.map[i].size);
>> +	 for_each_memblock(memory, mem) {
>> +		unsigned long start = mem->base;
>> +		unsigned long end = mem->end;
>>   		if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
>>   			/*
>>   			 * Reserve from the elf core header to the end of
>> @@ -613,47 +480,20 @@ static int __init early_parse_elfcorehdr(char *p)
>>   early_param("elfcorehdr", early_parse_elfcorehdr);
>>   #endif
>>   
>> -static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
>> -{
>> -	phys_addr_t size;
>> -	int i;
>> -
>> -	size = end - mem;
>> -	if (!size)
>> -		return;
>> -
>> -	/* Make sure it is in the boot_mem_map */
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		if (mem >= boot_mem_map.map[i].addr &&
>> -		    mem < (boot_mem_map.map[i].addr +
>> -			   boot_mem_map.map[i].size))
>> -			return;
>> -	}
>> -	add_memory_region(mem, size, type);
>> -}
>> -
>>   #ifdef CONFIG_KEXEC
>> -static inline unsigned long long get_total_mem(void)
>> -{
>> -	unsigned long long total;
>> -
>> -	total = max_pfn - min_low_pfn;
>> -	return total << PAGE_SHIFT;
>> -}
>> -
>>   static void __init mips_parse_crashkernel(void)
>>   {
>>   	unsigned long long total_mem;
>>   	unsigned long long crash_size, crash_base;
>>   	int ret;
>>   
>> -	total_mem = get_total_mem();
>> +	total_mem = memblock_phys_mem_size();
>>   	ret = parse_crashkernel(boot_command_line, total_mem,
>>   				&crash_size, &crash_base);
>>   	if (ret != 0 || crash_size <= 0)
>>   		return;
>>   
>> -	if (!memory_region_available(crash_base, crash_size)) {
>> +	if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) {
>>   		pr_warn("Invalid memory region reserved for crash kernel\n");
>>   		return;
>>   	}
>> @@ -686,6 +526,17 @@ static void __init request_crashkernel(struct resource *res)
>>   }
>>   #endif /* !defined(CONFIG_KEXEC)  */
>>   
>> +static void __init check_kernel_sections_mem(void)
>> +{
>> +	phys_addr_t start = PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT;
>> +	phys_addr_t size = (PFN_UP(__pa_symbol(&_end)) - start) << PAGE_SHIFT;
>> +
>> +	if (!memblock_is_region_memory(start, size)) {
>> +		pr_info("Kernel sections are not in the memory maps\n");
>> +		memblock_add(start, size);
>> +	}
>> +}
>> +
>>   #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
>>   #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
>>   #define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
>> @@ -731,25 +582,6 @@ static void __init arch_mem_init(char **cmdline_p)
>>   	plat_mem_setup();
>>   	memblock_set_bottom_up(true);
>>   
>> -	/*
>> -	 * Make sure all kernel memory is in the maps.  The "UP" and
>> -	 * "DOWN" are opposite for initdata since if it crosses over
>> -	 * into another memory section you don't want that to be
>> -	 * freed when the initdata is freed.
>> -	 */
>> -	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
>> -			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
>> -			 BOOT_MEM_RAM);
>> -	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
>> -			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
>> -			 BOOT_MEM_INIT_RAM);
>> -	arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT,
>> -			 PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT,
>> -			 BOOT_MEM_RAM);
>> -
> I see you replaced this code with check_kernel_sections_mem(). Neat.
> You could also replace "<< PAGE_SHIFT" with PFN_PHYS() macro in the function.
>
>> -	pr_info("Determined physical RAM map:\n");
>> -	print_memory_map();
> I'll miss you "print_memory_map()"... =) Nothing is going to print a detected
> physical memory layout at boot time. Someone might disagree, but I found this
> very useful...
memblock will also print it.
>
>> -
>>   #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
>>   	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
>>   #else
>> @@ -783,14 +615,17 @@ static void __init arch_mem_init(char **cmdline_p)
>>   
>>   	parse_early_param();
>>   
>> -	if (usermem) {
>> -		pr_info("User-defined physical RAM map:\n");
>> -		print_memory_map();
>> -	}
>> +	if (usermem)
>> +		pr_info("User-defined physical RAM map overwrite\n");
>> +
>> +	check_kernel_sections_mem();
>>   
>>   	early_init_fdt_reserve_self();
>>   	early_init_fdt_scan_reserved_mem();
>>   
>> +#ifndef CONFIG_NUMA
>> +	memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
>> +#endif
>>   	bootmem_init();
>>   
>>   	/*
>> @@ -835,7 +670,7 @@ static void __init arch_mem_init(char **cmdline_p)
>>   
>>   static void __init resource_init(void)
>>   {
>> -	int i;
>> +	struct memblock_region *region;
>>   
>>   	if (UNCAC_BASE != IO_BASE)
>>   		return;
>> @@ -847,16 +682,10 @@ static void __init resource_init(void)
>>   	bss_resource.start = __pa_symbol(&__bss_start);
>>   	bss_resource.end = __pa_symbol(&__bss_stop) - 1;
>>   
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> +	for_each_memblock(memory, region) {
>> +		phys_addr_t start = __pfn_to_phys(memblock_region_memory_base_pfn(region));
>> +		phys_addr_t end = __pfn_to_phys(memblock_region_memory_end_pfn(region)) - 1;
> I haven't seen __pfn_to_phys() macro usage in the MIPS code. Instead the upper-case
> versions (PFN_PHYS()/PHYS_PFN()) are utilized. It might be better to follow the
> MIPS-platform way. They are identical at this moment though. Paul?
I just copied them from ARM side. I'm going to unify them.
>>   		struct resource *res;
>> -		unsigned long start, end;
>> -
>> -		start = boot_mem_map.map[i].addr;
>> -		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
>> -		if (start >= HIGHMEM_START)
>> -			continue;
>> -		if (end >= HIGHMEM_START)
>> -			end = HIGHMEM_START - 1;
>>   
>>   		res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
>>   		if (!res)
>> @@ -865,20 +694,7 @@ static void __init resource_init(void)
>>   
>>   		res->start = start;
>>   		res->end = end;
>> -		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
>> -
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -		case BOOT_MEM_INIT_RAM:
>> -		case BOOT_MEM_ROM_DATA:
>> -			res->name = "System RAM";
> Is that right to also discard the "System RAM" resource name?
>
>> -			res->flags |= IORESOURCE_SYSRAM;
>> -			break;
>> -		case BOOT_MEM_RESERVED:
>> -		case BOOT_MEM_NOMAP:
>> -		default:
>> -			res->name = "reserved";
>> -		}
>> +		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
>>   
>>   		request_resource(&iomem_resource, res);
>>   
>> diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
>> index 8a038b30d3c4..2bb8ebf0d2d5 100644
>> --- a/arch/mips/mm/init.c
>> +++ b/arch/mips/mm/init.c
>> @@ -271,25 +271,17 @@ void __init fixrange_init(unsigned long start, unsigned long end,
>>   
>>   unsigned __weak platform_maar_init(unsigned num_pairs)
>>   {
>> -	struct maar_config cfg[BOOT_MEM_MAP_MAX];
>> -	unsigned i, num_configured, num_cfg = 0;
>> -
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -		case BOOT_MEM_INIT_RAM:
>> -			break;
>> -		default:
>> -			continue;
>> -		}
>> +	struct maar_config cfg[32];
>> +	unsigned int num_configured, num_cfg = 0;
>> +	struct memblock_region *mem;
>>   
>> +	for_each_memblock(memory, mem) {
>>   		/* Round lower up */
>> -		cfg[num_cfg].lower = boot_mem_map.map[i].addr;
>> +		cfg[num_cfg].lower = __pfn_to_phys(memblock_region_memory_base_pfn(mem));
> The same thing with PFN_PHYS()/PHYS_PFN().
>
>>   		cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
>>   
>>   		/* Round upper down */
>> -		cfg[num_cfg].upper = boot_mem_map.map[i].addr +
>> -					boot_mem_map.map[i].size;
>> +		cfg[num_cfg].upper = __pfn_to_phys(memblock_region_memory_end_pfn(mem));
> PFN_PHYS()/PHYS_PFN() again.
>
>>   		cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
>>   
>>   		cfg[num_cfg].attrs = MIPS_MAAR_S;
>> @@ -382,33 +374,6 @@ void maar_init(void)
>>   }
>>   
>>   #ifndef CONFIG_NEED_MULTIPLE_NODES
>> -int page_is_ram(unsigned long pagenr)
>> -{
>> -	int i;
>> -
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		unsigned long addr, end;
>> -
>> -		switch (boot_mem_map.map[i].type) {
>> -		case BOOT_MEM_RAM:
>> -		case BOOT_MEM_INIT_RAM:
>> -			break;
>> -		default:
>> -			/* not usable memory */
>> -			continue;
>> -		}
>> -
>> -		addr = PFN_UP(boot_mem_map.map[i].addr);
>> -		end = PFN_DOWN(boot_mem_map.map[i].addr +
>> -			       boot_mem_map.map[i].size);
>> -
>> -		if (pagenr >= addr && pagenr < end)
>> -			return 1;
>> -	}
>> -
>> -	return 0;
>> -}
>> -
>>   void __init paging_init(void)
>>   {
>>   	unsigned long max_zone_pfns[MAX_NR_ZONES];
>> @@ -452,9 +417,7 @@ static inline void mem_init_free_highmem(void)
>>   		return;
>>   
>>   	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
>> -		struct page *page = pfn_to_page(tmp);
>> -
>> -		if (!page_is_ram(tmp))
>> +		if (!memblock_is_memory(PFN_PHYS(tmp)))
> See. You've used PFN_PHYS() here instead of __pfn_to_phys().

Because that was written by myself : -)

Thanks for pointing out these issues.

> -Sergey
>
>>   			SetPageReserved(page);
>>   		else
>>   			free_highmem_page(page);
>> -- 
>> 2.22.0
>>
---

Jiaxun


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

* Re: [PATCH 3/7] MIPS: fw: Record prom memory
  2019-08-14 12:03   ` Serge Semin
  2019-08-14 12:50     ` Thomas Bogendoerfer
@ 2019-08-14 13:45     ` Jiaxun Yang
  1 sibling, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-14 13:45 UTC (permalink / raw)
  To: Serge Semin
  Cc: linux-mips, paul.burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc


On 2019/8/14 下午8:03, Serge Semin wrote:
> On Thu, Aug 08, 2019 at 03:50:09PM +0800, Jiaxun Yang wrote:
>> boot_mem_map is nolonger exist so we need to maintain a list
>> of prom memory by ourselves.
>>
>> Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>> ---
>>   arch/mips/fw/arc/memory.c | 20 ++++++++++++++------
>>   1 file changed, 14 insertions(+), 6 deletions(-)
>>
>> diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
>> index 429b7f8d2aeb..02e954b3700e 100644
>> --- a/arch/mips/fw/arc/memory.c
>> +++ b/arch/mips/fw/arc/memory.c
>> @@ -27,6 +27,11 @@
>>   
>>   #undef DEBUG
>>   
>> +#define MAX_PROM_MEM 5
>> +static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
>> +static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
>> +static unsigned int nr_prom_mem __initdata;
>> +
>>   /*
>>    * For ARC firmware memory functions the unit of meassuring memory is always
>>    * a 4k page of memory
>> @@ -129,6 +134,7 @@ void __init prom_meminit(void)
>>   	}
>>   #endif
>>   
>> +	nr_prom_mem = 0;
>>   	p = PROM_NULL_MDESC;
>>   	while ((p = ArcGetMemoryDescriptor(p))) {
>>   		unsigned long base, size;
>> @@ -139,6 +145,12 @@ void __init prom_meminit(void)
>>   		type = prom_memtype_classify(p->type);
>>   
>>   		add_memory_region(base, size, type);
>> +
>> +		if (type == BOOT_MEM_ROM_DATA) {
>> +			prom_mem_base[nr_prom_mem] = base;
>> +			prom_mem_size[nr_prom_mem] = size;
>> +			nr_prom_mem++;
> Are you sure, that five prom-mem regions is enough? What about adding
> a sanity check here so no to exceed the array size?

Five should be enough, as far as I know yamon will only allocate one or two.

But you are right, add a sanity check would be better.

- Jiaxun

>
> -Sergey
>
>> +		}
>>   	}
>>   }
>>   
>> @@ -150,12 +162,8 @@ void __init prom_free_prom_memory(void)
>>   	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
>>   		return;
>>   
>> -	for (i = 0; i < boot_mem_map.nr_map; i++) {
>> -		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
>> -			continue;
>> -
>> -		addr = boot_mem_map.map[i].addr;
>> +	for (i = 0; i < nr_prom_mem; i++) {
>>   		free_init_pages("prom memory",
>> -				addr, addr + boot_mem_map.map[i].size);
>> +			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
>>   	}
>>   }
>> -- 
>> 2.22.0
>>

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

* [PATCH v1 0/8] MIPS: Drop boot_mem_map
  2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
                   ` (7 preceding siblings ...)
  2019-08-12  4:56 ` [EXTERNAL]Drop boot_mem_map Paul Burton
@ 2019-08-19 14:23 ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 1/8] MIPS: OCTEON: " Jiaxun Yang
                     ` (8 more replies)
  8 siblings, 9 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

v1: Reording patches, fixes according to Serge's suggestions,
fix maar section mismatch.

Jiaxun Yang (8):
  MIPS: OCTEON: Drop boot_mem_map
  MIPS: fw: Record prom memory
  MIPS: malta: Drop prom_free_prom_memory
  MIPS: msp: Record prom memory
  MIPS: ip22: Drop addr_is_ram
  MIPS: xlp: Drop boot_mem_map
  MIPS: mm: Drop boot_mem_map
  MIPS: init: Drop boot_mem_map

 arch/mips/cavium-octeon/dma-octeon.c |  17 +-
 arch/mips/cavium-octeon/setup.c      |   3 +-
 arch/mips/fw/arc/memory.c            |  24 +-
 arch/mips/include/asm/bootinfo.h     |  16 --
 arch/mips/include/asm/maar.h         |   8 +-
 arch/mips/kernel/setup.c             | 355 +++++++--------------------
 arch/mips/mm/init.c                  |  82 +++----
 arch/mips/mti-malta/malta-memory.c   |  11 -
 arch/mips/netlogic/xlp/setup.c       |  12 +-
 arch/mips/pmcs-msp71xx/msp_prom.c    |  22 +-
 arch/mips/sgi-ip22/ip28-berr.c       |  20 +-
 11 files changed, 173 insertions(+), 397 deletions(-)

-- 
2.22.0


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

* [PATCH v1 1/8] MIPS: OCTEON: Drop boot_mem_map
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 2/8] MIPS: fw: Record prom memory Jiaxun Yang
                     ` (7 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Replace walk through boot_mem_map with for_each_memblock.
And remove the check of total boot_mem_map.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/cavium-octeon/dma-octeon.c | 17 +++++++----------
 arch/mips/cavium-octeon/setup.c      |  3 +--
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
index 11d5a4e90736..72f24a4db099 100644
--- a/arch/mips/cavium-octeon/dma-octeon.c
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -16,6 +16,7 @@
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/memblock.h>
 
 #include <asm/bootinfo.h>
 
@@ -190,7 +191,7 @@ char *octeon_swiotlb;
 
 void __init plat_swiotlb_setup(void)
 {
-	int i;
+	struct memblock_region *mem;
 	phys_addr_t max_addr;
 	phys_addr_t addr_size;
 	size_t swiotlbsize;
@@ -199,19 +200,15 @@ void __init plat_swiotlb_setup(void)
 	max_addr = 0;
 	addr_size = 0;
 
-	for (i = 0 ; i < boot_mem_map.nr_map; i++) {
-		struct boot_mem_map_entry *e = &boot_mem_map.map[i];
-		if (e->type != BOOT_MEM_RAM && e->type != BOOT_MEM_INIT_RAM)
-			continue;
-
+	for_each_memblock(memory, mem) {
 		/* These addresses map low for PCI. */
-		if (e->addr > 0x410000000ull && !OCTEON_IS_OCTEON2())
+		if (mem->base > 0x410000000ull && !OCTEON_IS_OCTEON2())
 			continue;
 
-		addr_size += e->size;
+		addr_size += mem->size;
 
-		if (max_addr < e->addr + e->size)
-			max_addr = e->addr + e->size;
+		if (max_addr < mem->base + mem->size)
+			max_addr = mem->base + mem->size;
 
 	}
 
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 8bf43c5a7bc7..95034bf5ca83 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -1007,8 +1007,7 @@ void __init plat_mem_setup(void)
 	 * regions next to each other.
 	 */
 	cvmx_bootmem_lock();
-	while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
-		&& (total < max_memory)) {
+	while (total < max_memory) {
 		memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
 						__pa_symbol(&_end), -1,
 						0x100000,
-- 
2.22.0


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

* [PATCH v1 2/8] MIPS: fw: Record prom memory
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 1/8] MIPS: OCTEON: " Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 3/8] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
                     ` (6 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map is nolonger exist so we need to maintain a list
of prom memory by ourselves.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/fw/arc/memory.c | 24 ++++++++++++++++++------
 1 file changed, 18 insertions(+), 6 deletions(-)

diff --git a/arch/mips/fw/arc/memory.c b/arch/mips/fw/arc/memory.c
index 429b7f8d2aeb..09c69a23f908 100644
--- a/arch/mips/fw/arc/memory.c
+++ b/arch/mips/fw/arc/memory.c
@@ -27,6 +27,11 @@
 
 #undef DEBUG
 
+#define MAX_PROM_MEM 5
+static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
+static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
+static unsigned int nr_prom_mem __initdata;
+
 /*
  * For ARC firmware memory functions the unit of meassuring memory is always
  * a 4k page of memory
@@ -129,6 +134,7 @@ void __init prom_meminit(void)
 	}
 #endif
 
+	nr_prom_mem = 0;
 	p = PROM_NULL_MDESC;
 	while ((p = ArcGetMemoryDescriptor(p))) {
 		unsigned long base, size;
@@ -139,6 +145,16 @@ void __init prom_meminit(void)
 		type = prom_memtype_classify(p->type);
 
 		add_memory_region(base, size, type);
+
+		if (type == BOOT_MEM_ROM_DATA) {
+			if (nr_prom_mem >= 5) {
+				pr_err("Too many ROM DATA regions");
+				continue;
+			}
+			prom_mem_base[nr_prom_mem] = base;
+			prom_mem_size[nr_prom_mem] = size;
+			nr_prom_mem++;
+		}
 	}
 }
 
@@ -150,12 +166,8 @@ void __init prom_free_prom_memory(void)
 	if (prom_flags & PROM_FLAG_DONT_FREE_TEMP)
 		return;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
+	for (i = 0; i < nr_prom_mem; i++) {
 		free_init_pages("prom memory",
-				addr, addr + boot_mem_map.map[i].size);
+			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
 	}
 }
-- 
2.22.0


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

* [PATCH v1 3/8] MIPS: malta: Drop prom_free_prom_memory
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 1/8] MIPS: OCTEON: " Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 2/8] MIPS: fw: Record prom memory Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 4/8] MIPS: msp: Record prom memory Jiaxun Yang
                     ` (5 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Current prom_free_prom_memory is freeing maps marked
as BOOT_MEM_ROM_DATA, however, nobody is exactly setting
this type for malta.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/mti-malta/malta-memory.c | 11 -----------
 1 file changed, 11 deletions(-)

diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c
index 868921adef1d..7c25a0a2345c 100644
--- a/arch/mips/mti-malta/malta-memory.c
+++ b/arch/mips/mti-malta/malta-memory.c
@@ -39,17 +39,6 @@ void __init fw_meminit(void)
 
 void __init prom_free_prom_memory(void)
 {
-	unsigned long addr;
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
-		free_init_pages("YAMON memory",
-				addr, addr + boot_mem_map.map[i].size);
-	}
 }
 
 phys_addr_t mips_cdmm_phys_base(void)
-- 
2.22.0


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

* [PATCH v1 4/8] MIPS: msp: Record prom memory
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (2 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 3/8] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 5/8] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
                     ` (4 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map is nolonger exist so we need to maintain a list
of prom memory by ourselves

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/pmcs-msp71xx/msp_prom.c | 22 ++++++++++++++++------
 1 file changed, 16 insertions(+), 6 deletions(-)

diff --git a/arch/mips/pmcs-msp71xx/msp_prom.c b/arch/mips/pmcs-msp71xx/msp_prom.c
index 6fdcb3d6fbb5..0c5e5384b1d7 100644
--- a/arch/mips/pmcs-msp71xx/msp_prom.c
+++ b/arch/mips/pmcs-msp71xx/msp_prom.c
@@ -61,6 +61,10 @@ int init_debug = 1;
 /* memory blocks */
 struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS];
 
+static phys_addr_t prom_mem_base[MAX_PROM_MEM] __initdata;
+static phys_addr_t prom_mem_size[MAX_PROM_MEM] __initdata;
+static unsigned int nr_prom_mem __initdata;
+
 /* default feature sets */
 static char msp_default_features[] =
 #if defined(CONFIG_PMC_MSP4200_EVAL) \
@@ -352,6 +356,16 @@ void __init prom_meminit(void)
 
 		add_memory_region(base, size, type);
 		p++;
+
+		if (type == BOOT_MEM_ROM_DATA) {
+			if (nr_prom_mem >= 5) {
+				pr_err("Too many ROM DATA regions");
+				continue;
+			}
+			prom_mem_base[nr_prom_mem] = base;
+			prom_mem_size[nr_prom_mem] = size;
+			nr_prom_mem++;
+		}
 	}
 }
 
@@ -407,13 +421,9 @@ void __init prom_free_prom_memory(void)
 	envp[i] = NULL;			/* end array with null pointer */
 	prom_envp = envp;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_ROM_DATA)
-			continue;
-
-		addr = boot_mem_map.map[i].addr;
+	for (i = 0; i < nr_prom_mem; i++) {
 		free_init_pages("prom memory",
-				addr, addr + boot_mem_map.map[i].size);
+			prom_mem_base[i], prom_mem_base[i] + prom_mem_size[i]);
 	}
 }
 
-- 
2.22.0


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

* [PATCH v1 5/8] MIPS: ip22: Drop addr_is_ram
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (3 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 4/8] MIPS: msp: Record prom memory Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 6/8] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
                     ` (3 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

It can be replaced by page_is_ram.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/sgi-ip22/ip28-berr.c | 20 ++------------------
 1 file changed, 2 insertions(+), 18 deletions(-)

diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index c0cf7baee36d..c61362d9ea95 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -8,6 +8,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/mm.h>
 #include <linux/sched.h>
 #include <linux/sched/debug.h>
 #include <linux/sched/signal.h>
@@ -300,23 +301,6 @@ static void print_buserr(const struct pt_regs *regs)
 	       field, regs->cp0_epc, field, regs->regs[31]);
 }
 
-/*
- * Check, whether MC's (virtual) DMA address caused the bus error.
- * See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
- */
-
-static int addr_is_ram(unsigned long addr, unsigned sz)
-{
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long a = boot_mem_map.map[i].addr;
-		if (a <= addr && addr+sz <= a+boot_mem_map.map[i].size)
-			return 1;
-	}
-	return 0;
-}
-
 static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 {
 	/* This is likely rather similar to correct code ;-) */
@@ -331,7 +315,7 @@ static int check_microtlb(u32 hi, u32 lo, unsigned long vaddr)
 			/* PTEIndex is VPN-low (bits [22:14]/[20:12] ?) */
 			unsigned long pte = (lo >> 6) << 12; /* PTEBase */
 			pte += 8*((vaddr >> pgsz) & 0x1ff);
-			if (addr_is_ram(pte, 8)) {
+			if (page_is_ram(PFN_DOWN(pte))) {
 				/*
 				 * Note: Since DMA hardware does look up
 				 * translation on its own, this PTE *must*
-- 
2.22.0


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

* [PATCH v1 6/8] MIPS: xlp: Drop boot_mem_map
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (4 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 5/8] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 7/8] MIPS: mm: " Jiaxun Yang
                     ` (2 subsequent siblings)
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Simply replace with memblock functions.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/netlogic/xlp/setup.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index f743fd9da323..1a0fc5b62ba4 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -34,6 +34,7 @@
 
 #include <linux/kernel.h>
 #include <linux/of_fdt.h>
+#include <linux/memblock.h>
 
 #include <asm/idle.h>
 #include <asm/reboot.h>
@@ -67,12 +68,11 @@ static void nlm_linux_exit(void)
 static void nlm_fixup_mem(void)
 {
 	const int pref_backup = 512;
-	int i;
+	struct memblock_region *mem;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
-		boot_mem_map.map[i].size -= pref_backup;
+	for_each_memblock(memory, mem) {
+		memblock_remove(mem->base + mem->size - pref_backup,
+			pref_backup);
 	}
 }
 
@@ -110,7 +110,7 @@ void __init plat_mem_setup(void)
 	/* memory and bootargs from DT */
 	xlp_early_init_devtree();
 
-	if (boot_mem_map.nr_map == 0) {
+	if (memblock_end_of_DRAM() == 0) {
 		pr_info("Using DRAM BARs for memory map.\n");
 		xlp_init_mem_from_bars();
 	}
-- 
2.22.0


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

* [PATCH v1 7/8] MIPS: mm: Drop boot_mem_map
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (5 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 6/8] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-19 14:23   ` [PATCH v1 8/8] MIPS: init: " Jiaxun Yang
  2019-08-23 14:45   ` [PATCH v1 0/8] MIPS: " Paul Burton
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

Initialize maar by resource map and replace page_is_ram
by memblock_is_memory.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/include/asm/maar.h |  8 +++-
 arch/mips/mm/init.c          | 82 ++++++++++++++----------------------
 2 files changed, 38 insertions(+), 52 deletions(-)

diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h
index 6908b93c4ff9..8caa2512d504 100644
--- a/arch/mips/include/asm/maar.h
+++ b/arch/mips/include/asm/maar.h
@@ -78,6 +78,7 @@ extern void maar_init(void);
  *		aligned to one byte before a 2^16 byte boundary.
  * @attrs:	The accessibility attributes to program, eg. MIPS_MAAR_S. The
  *		MIPS_MAAR_VL attribute will automatically be set.
+ * @used:  Determine if the config entry is used.
  *
  * Describes the configuration of a pair of Memory Accessibility Attribute
  * Registers - applying attributes from attrs to the range of physical
@@ -87,7 +88,9 @@ struct maar_config {
 	phys_addr_t lower;
 	phys_addr_t upper;
 	unsigned attrs;
+	bool used;
 };
+#define MAX_MAAR_CONFIGS 32
 
 /**
  * maar_config() - configure MAARs according to provided data
@@ -105,8 +108,11 @@ static inline unsigned maar_config(const struct maar_config *cfg,
 {
 	unsigned i;
 
-	for (i = 0; i < min(num_cfg, num_pairs); i++)
+	for (i = 0; i < num_cfg; i++) {
+		if (!cfg[i].used)
+			continue;
 		write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs);
+	}
 
 	return i;
 }
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c
index 8a038b30d3c4..5b89bdebb3ab 100644
--- a/arch/mips/mm/init.c
+++ b/arch/mips/mm/init.c
@@ -269,31 +269,39 @@ void __init fixrange_init(unsigned long start, unsigned long end,
 #endif
 }
 
-unsigned __weak platform_maar_init(unsigned num_pairs)
+static int maar_res_walk(unsigned long start, unsigned long nr_pages,
+			void *data)
 {
-	struct maar_config cfg[BOOT_MEM_MAP_MAX];
-	unsigned i, num_configured, num_cfg = 0;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-			break;
-		default:
+	struct maar_config *cfg = (struct maar_config *)data;
+	int i;
+
+	/* Find next free config entry and fill from res */
+	for (i = 0; i < MAX_MAAR_CONFIGS; i++) {
+		if (cfg->used)
 			continue;
-		}
+		cfg->used = true;
+		cfg->lower = PFN_DOWN(start);
+		cfg->lower = (cfg->lower + 0xffff) & ~0xffff;
+		cfg->upper = PFN_UP(start + nr_pages);
+		cfg->upper = (cfg->upper & ~0xffff) - 1;
+		cfg->attrs = MIPS_MAAR_S;
+		cfg++;
+	}
 
-		/* Round lower up */
-		cfg[num_cfg].lower = boot_mem_map.map[i].addr;
-		cfg[num_cfg].lower = (cfg[num_cfg].lower + 0xffff) & ~0xffff;
+	return 0;
+}
 
-		/* Round upper down */
-		cfg[num_cfg].upper = boot_mem_map.map[i].addr +
-					boot_mem_map.map[i].size;
-		cfg[num_cfg].upper = (cfg[num_cfg].upper & ~0xffff) - 1;
 
-		cfg[num_cfg].attrs = MIPS_MAAR_S;
-		num_cfg++;
+unsigned __weak platform_maar_init(unsigned num_pairs)
+{
+	struct maar_config cfg[MAX_MAAR_CONFIGS];
+	unsigned int num_configured, i, num_cfg = 0;
+
+	walk_system_ram_range(0, max_pfn, &cfg, maar_res_walk);
+
+	for (i = 0; i < MAX_MAAR_CONFIGS; i++) {
+		if (cfg[i].used)
+			num_cfg++;
 	}
 
 	num_configured = maar_config(cfg, num_cfg, num_pairs);
@@ -376,39 +384,13 @@ void maar_init(void)
 			recorded.cfgs[recorded.used].lower = lower;
 			recorded.cfgs[recorded.used].upper = upper;
 			recorded.cfgs[recorded.used].attrs = attr;
+			recorded.cfgs[recorded.used].used = true;
 			recorded.used++;
 		}
 	}
 }
 
 #ifndef CONFIG_NEED_MULTIPLE_NODES
-int page_is_ram(unsigned long pagenr)
-{
-	int i;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long addr, end;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-			break;
-		default:
-			/* not usable memory */
-			continue;
-		}
-
-		addr = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr +
-			       boot_mem_map.map[i].size);
-
-		if (pagenr >= addr && pagenr < end)
-			return 1;
-	}
-
-	return 0;
-}
-
 void __init paging_init(void)
 {
 	unsigned long max_zone_pfns[MAX_NR_ZONES];
@@ -443,7 +425,7 @@ void __init paging_init(void)
 static struct kcore_list kcore_kseg0;
 #endif
 
-static inline void mem_init_free_highmem(void)
+static inline void __init mem_init_free_highmem(void)
 {
 #ifdef CONFIG_HIGHMEM
 	unsigned long tmp;
@@ -452,9 +434,7 @@ static inline void mem_init_free_highmem(void)
 		return;
 
 	for (tmp = highstart_pfn; tmp < highend_pfn; tmp++) {
-		struct page *page = pfn_to_page(tmp);
-
-		if (!page_is_ram(tmp))
+		if (!memblock_is_memory(PFN_PHYS(tmp)))
 			SetPageReserved(page);
 		else
 			free_highmem_page(page);
-- 
2.22.0


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

* [PATCH v1 8/8] MIPS: init: Drop boot_mem_map
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (6 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 7/8] MIPS: mm: " Jiaxun Yang
@ 2019-08-19 14:23   ` Jiaxun Yang
  2019-08-23 14:45   ` [PATCH v1 0/8] MIPS: " Paul Burton
  8 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-19 14:23 UTC (permalink / raw)
  To: linux-mips
  Cc: paul.burton, yasha.che3, aurelien, sfr, fancer.lancer,
	matt.redfearn, chenhc, Jiaxun Yang

boot_mem_map was introduced very early and cannot handle memory maps
with nid. Nowadays, memblock can exactly replace boot_mem_map.

Detect pfn info and setup resources with memblock maps.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
---
 arch/mips/include/asm/bootinfo.h |  16 --
 arch/mips/kernel/setup.c         | 355 ++++++++-----------------------
 2 files changed, 85 insertions(+), 286 deletions(-)

diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 235bc2f52113..4e296c38b6e6 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -87,28 +87,12 @@ const char *get_system_type(void);
 
 extern unsigned long mips_machtype;
 
-#define BOOT_MEM_MAP_MAX	32
 #define BOOT_MEM_RAM		1
 #define BOOT_MEM_ROM_DATA	2
 #define BOOT_MEM_RESERVED	3
 #define BOOT_MEM_INIT_RAM	4
 #define BOOT_MEM_NOMAP		5
 
-/*
- * A memory map that's built upon what was determined
- * or specified on the command line.
- */
-struct boot_mem_map {
-	int nr_map;
-	struct boot_mem_map_entry {
-		phys_addr_t addr;	/* start of memory segment */
-		phys_addr_t size;	/* size of memory segment */
-		long type;		/* type of memory segment */
-	} map[BOOT_MEM_MAP_MAX];
-};
-
-extern struct boot_mem_map boot_mem_map;
-
 extern void add_memory_region(phys_addr_t start, phys_addr_t size, long type);
 extern void detect_memory_region(phys_addr_t start, phys_addr_t sz_min,  phys_addr_t sz_max);
 
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index ab349d2381c3..0307325ce6e8 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -63,8 +63,6 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
 
 EXPORT_SYMBOL(mips_machtype);
 
-struct boot_mem_map boot_mem_map;
-
 static char __initdata command_line[COMMAND_LINE_SIZE];
 char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
 
@@ -92,8 +90,10 @@ EXPORT_SYMBOL(ARCH_PFN_OFFSET);
 
 void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
 {
-	int x = boot_mem_map.nr_map;
-	int i;
+	/*
+	 * Note: This function only exists for historical reason,
+	 * new code should use memblock_add or memblock_add_node instead.
+	 */
 
 	/*
 	 * If the region reaches the top of the physical address space, adjust
@@ -108,38 +108,20 @@ void __init add_memory_region(phys_addr_t start, phys_addr_t size, long type)
 		return;
 	}
 
-	/*
-	 * Try to merge with existing entry, if any.
-	 */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		struct boot_mem_map_entry *entry = boot_mem_map.map + i;
-		unsigned long top;
-
-		if (entry->type != type)
-			continue;
-
-		if (start + size < entry->addr)
-			continue;			/* no overlap */
+	memblock_add(start, size);
+	/* Reserve any memory except the ordinary RAM ranges. */
+	switch (type) {
+	case BOOT_MEM_RAM:
+		break;
 
-		if (entry->addr + entry->size < start)
-			continue;			/* no overlap */
+	case BOOT_MEM_NOMAP: /* Discard the range from the system. */
+		memblock_remove(start, size);
+		break;
 
-		top = max(entry->addr + entry->size, start + size);
-		entry->addr = min(entry->addr, start);
-		entry->size = top - entry->addr;
-
-		return;
+	default: /* Reserve the rest of the memory types at boot time */
+		memblock_reserve(start, size);
+		break;
 	}
-
-	if (boot_mem_map.nr_map == BOOT_MEM_MAP_MAX) {
-		pr_err("Ooops! Too many entries in the memory map!\n");
-		return;
-	}
-
-	boot_mem_map.map[x].addr = start;
-	boot_mem_map.map[x].size = size;
-	boot_mem_map.map[x].type = type;
-	boot_mem_map.nr_map++;
 }
 
 void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_addr_t sz_max)
@@ -161,70 +143,6 @@ void __init detect_memory_region(phys_addr_t start, phys_addr_t sz_min, phys_add
 	add_memory_region(start, size, BOOT_MEM_RAM);
 }
 
-static bool __init __maybe_unused memory_region_available(phys_addr_t start,
-							  phys_addr_t size)
-{
-	int i;
-	bool in_ram = false, free = true;
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		phys_addr_t start_, end_;
-
-		start_ = boot_mem_map.map[i].addr;
-		end_ = boot_mem_map.map[i].addr + boot_mem_map.map[i].size;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			if (start >= start_ && start + size <= end_)
-				in_ram = true;
-			break;
-		case BOOT_MEM_RESERVED:
-		case BOOT_MEM_NOMAP:
-			if ((start >= start_ && start < end_) ||
-			    (start < start_ && start + size >= start_))
-				free = false;
-			break;
-		default:
-			continue;
-		}
-	}
-
-	return in_ram && free;
-}
-
-static void __init print_memory_map(void)
-{
-	int i;
-	const int field = 2 * sizeof(unsigned long);
-
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		printk(KERN_INFO " memory: %0*Lx @ %0*Lx ",
-		       field, (unsigned long long) boot_mem_map.map[i].size,
-		       field, (unsigned long long) boot_mem_map.map[i].addr);
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			printk(KERN_CONT "(usable)\n");
-			break;
-		case BOOT_MEM_INIT_RAM:
-			printk(KERN_CONT "(usable after init)\n");
-			break;
-		case BOOT_MEM_ROM_DATA:
-			printk(KERN_CONT "(ROM data)\n");
-			break;
-		case BOOT_MEM_RESERVED:
-			printk(KERN_CONT "(reserved)\n");
-			break;
-		case BOOT_MEM_NOMAP:
-			printk(KERN_CONT "(nomap)\n");
-			break;
-		default:
-			printk(KERN_CONT "type %lu\n", boot_mem_map.map[i].type);
-			break;
-		}
-	}
-}
-
 /*
  * Manage initrd
  */
@@ -376,8 +294,11 @@ static void __init bootmem_init(void)
 
 static void __init bootmem_init(void)
 {
-	phys_addr_t ramstart = PHYS_ADDR_MAX;
-	int i;
+	struct memblock_region *mem;
+	phys_addr_t ramstart, ramend;
+
+	ramstart = memblock_start_of_DRAM();
+	ramend = memblock_end_of_DRAM();
 
 	/*
 	 * Sanity check any INITRD first. We don't take it into account
@@ -391,122 +312,66 @@ static void __init bootmem_init(void)
 	memblock_reserve(__pa_symbol(&_text),
 			__pa_symbol(&_end) - __pa_symbol(&_text));
 
+	/* max_low_pfn is not a number of pages but the end pfn of low mem */
+
+#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
+	ARCH_PFN_OFFSET = PFN_UP(ramstart);
+#else
 	/*
-	 * max_low_pfn is not a number of pages. The number of pages
-	 * of the system is given by 'max_low_pfn - min_low_pfn'.
+	 * Reserve any memory between the start of RAM and PHYS_OFFSET
 	 */
-	min_low_pfn = ~0UL;
-	max_low_pfn = 0;
-
-	/* Find the highest and lowest page frame numbers we have available. */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start, end;
-
-		if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
-			continue;
+	if (ramstart > PHYS_OFFSET)
+		memblock_reserve(PHYS_OFFSET, PFN_UP(ramstart) - PHYS_OFFSET);
 
-		start = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr
-				+ boot_mem_map.map[i].size);
+	if (PFN_UP(ramstart) > ARCH_PFN_OFFSET) {
+		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
+			(unsigned long)((PFN_UP(ramstart) - ARCH_PFN_OFFSET) * sizeof(struct page)),
+			(unsigned long)(PFN_UP(ramstart) - ARCH_PFN_OFFSET));
+	}
+#endif
 
-		ramstart = min(ramstart, boot_mem_map.map[i].addr);
+	min_low_pfn = ARCH_PFN_OFFSET;
+	max_pfn = PFN_DOWN(ramend);
+	for_each_memblock(memory, mem) {
+		unsigned long start = memblock_region_memory_base_pfn(mem);
+		unsigned long end = memblock_region_memory_end_pfn(mem);
 
-#ifndef CONFIG_HIGHMEM
 		/*
 		 * Skip highmem here so we get an accurate max_low_pfn if low
 		 * memory stops short of high memory.
 		 * If the region overlaps HIGHMEM_START, end is clipped so
 		 * max_pfn excludes the highmem portion.
 		 */
+		if (memblock_is_nomap(mem))
+			continue;
 		if (start >= PFN_DOWN(HIGHMEM_START))
 			continue;
 		if (end > PFN_DOWN(HIGHMEM_START))
 			end = PFN_DOWN(HIGHMEM_START);
-#endif
-
 		if (end > max_low_pfn)
 			max_low_pfn = end;
-		if (start < min_low_pfn)
-			min_low_pfn = start;
 	}
 
 	if (min_low_pfn >= max_low_pfn)
 		panic("Incorrect memory mapping !!!");
 
-#ifdef CONFIG_MIPS_AUTO_PFN_OFFSET
-	ARCH_PFN_OFFSET = PFN_UP(ramstart);
-#else
-	/*
-	 * Reserve any memory between the start of RAM and PHYS_OFFSET
-	 */
-	if (ramstart > PHYS_OFFSET) {
-		add_memory_region(PHYS_OFFSET, ramstart - PHYS_OFFSET,
-				  BOOT_MEM_RESERVED);
-		memblock_reserve(PHYS_OFFSET, ramstart - PHYS_OFFSET);
-	}
-
-	if (min_low_pfn > ARCH_PFN_OFFSET) {
-		pr_info("Wasting %lu bytes for tracking %lu unused pages\n",
-			(min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page),
-			min_low_pfn - ARCH_PFN_OFFSET);
-	} else if (ARCH_PFN_OFFSET - min_low_pfn > 0UL) {
-		pr_info("%lu free pages won't be used\n",
-			ARCH_PFN_OFFSET - min_low_pfn);
-	}
-	min_low_pfn = ARCH_PFN_OFFSET;
-#endif
-
-	/*
-	 * Determine low and high memory ranges
-	 */
-	max_pfn = max_low_pfn;
-	if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) {
+	if (max_pfn > PFN_DOWN(HIGHMEM_START)) {
 #ifdef CONFIG_HIGHMEM
 		highstart_pfn = PFN_DOWN(HIGHMEM_START);
-		highend_pfn = max_low_pfn;
-#endif
+		highend_pfn = max_pfn;
+#else
 		max_low_pfn = PFN_DOWN(HIGHMEM_START);
-	}
-
-	/* Install all valid RAM ranges to the memblock memory region */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start, end;
-
-		start = PFN_UP(boot_mem_map.map[i].addr);
-		end = PFN_DOWN(boot_mem_map.map[i].addr
-				+ boot_mem_map.map[i].size);
-
-		if (start < min_low_pfn)
-			start = min_low_pfn;
-#ifndef CONFIG_HIGHMEM
-		/* Ignore highmem regions if highmem is unsupported */
-		if (end > max_low_pfn)
-			end = max_low_pfn;
+		max_pfn = max_low_pfn;
 #endif
-		if (end <= start)
-			continue;
-
-		memblock_add_node(PFN_PHYS(start), PFN_PHYS(end - start), 0);
+	}
 
-		/* Reserve any memory except the ordinary RAM ranges. */
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-			break;
-		case BOOT_MEM_NOMAP: /* Discard the range from the system. */
-			memblock_remove(PFN_PHYS(start), PFN_PHYS(end - start));
-			continue;
-		default: /* Reserve the rest of the memory types at boot time */
-			memblock_reserve(PFN_PHYS(start), PFN_PHYS(end - start));
-			break;
-		}
 
-		/*
-		 * In any case the added to the memblock memory regions
-		 * (highmem/lowmem, available/reserved, etc) are considered
-		 * as present, so inform sparsemem about them.
-		 */
-		memory_present(0, start, end);
-	}
+	/*
+	 * In any case the added to the memblock memory regions
+	 * (highmem/lowmem, available/reserved, etc) are considered
+	 * as present, so inform sparsemem about them.
+	 */
+	memblocks_present();
 
 	/*
 	 * Reserve initrd memory if needed.
@@ -528,8 +393,9 @@ static int __init early_parse_mem(char *p)
 	 * size.
 	 */
 	if (usermem == 0) {
-		boot_mem_map.nr_map = 0;
 		usermem = 1;
+		memblock_remove(memblock_start_of_DRAM(),
+			memblock_end_of_DRAM() - memblock_start_of_DRAM());
 	}
 	start = 0;
 	size = memparse(p, &p);
@@ -586,14 +452,13 @@ early_param("memmap", early_parse_memmap);
 unsigned long setup_elfcorehdr, setup_elfcorehdr_size;
 static int __init early_parse_elfcorehdr(char *p)
 {
-	int i;
+	struct memblock_region *mem;
 
 	setup_elfcorehdr = memparse(p, &p);
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		unsigned long start = boot_mem_map.map[i].addr;
-		unsigned long end = (boot_mem_map.map[i].addr +
-				     boot_mem_map.map[i].size);
+	 for_each_memblock(memory, mem) {
+		unsigned long start = mem->base;
+		unsigned long end = mem->end;
 		if (setup_elfcorehdr >= start && setup_elfcorehdr < end) {
 			/*
 			 * Reserve from the elf core header to the end of
@@ -613,47 +478,20 @@ static int __init early_parse_elfcorehdr(char *p)
 early_param("elfcorehdr", early_parse_elfcorehdr);
 #endif
 
-static void __init arch_mem_addpart(phys_addr_t mem, phys_addr_t end, int type)
-{
-	phys_addr_t size;
-	int i;
-
-	size = end - mem;
-	if (!size)
-		return;
-
-	/* Make sure it is in the boot_mem_map */
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
-		if (mem >= boot_mem_map.map[i].addr &&
-		    mem < (boot_mem_map.map[i].addr +
-			   boot_mem_map.map[i].size))
-			return;
-	}
-	add_memory_region(mem, size, type);
-}
-
 #ifdef CONFIG_KEXEC
-static inline unsigned long long get_total_mem(void)
-{
-	unsigned long long total;
-
-	total = max_pfn - min_low_pfn;
-	return total << PAGE_SHIFT;
-}
-
 static void __init mips_parse_crashkernel(void)
 {
 	unsigned long long total_mem;
 	unsigned long long crash_size, crash_base;
 	int ret;
 
-	total_mem = get_total_mem();
+	total_mem = memblock_phys_mem_size();
 	ret = parse_crashkernel(boot_command_line, total_mem,
 				&crash_size, &crash_base);
 	if (ret != 0 || crash_size <= 0)
 		return;
 
-	if (!memory_region_available(crash_base, crash_size)) {
+	if (!memblock_find_in_range(crash_base, crash_base + crash_size, crash_size, 0)) {
 		pr_warn("Invalid memory region reserved for crash kernel\n");
 		return;
 	}
@@ -686,6 +524,17 @@ static void __init request_crashkernel(struct resource *res)
 }
 #endif /* !defined(CONFIG_KEXEC)  */
 
+static void __init check_kernel_sections_mem(void)
+{
+	phys_addr_t start = PFN_PHYS(PFN_DOWN(__pa_symbol(&_text)));
+	phys_addr_t size = PFN_PHYS(PFN_UP(__pa_symbol(&_end)) - start);
+
+	if (!memblock_is_region_memory(start, size)) {
+		pr_info("Kernel sections are not in the memory maps\n");
+		memblock_add(start, size);
+	}
+}
+
 #define USE_PROM_CMDLINE	IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_BOOTLOADER)
 #define USE_DTB_CMDLINE		IS_ENABLED(CONFIG_MIPS_CMDLINE_FROM_DTB)
 #define EXTEND_WITH_PROM	IS_ENABLED(CONFIG_MIPS_CMDLINE_DTB_EXTEND)
@@ -731,25 +580,6 @@ static void __init arch_mem_init(char **cmdline_p)
 	plat_mem_setup();
 	memblock_set_bottom_up(true);
 
-	/*
-	 * Make sure all kernel memory is in the maps.  The "UP" and
-	 * "DOWN" are opposite for initdata since if it crosses over
-	 * into another memory section you don't want that to be
-	 * freed when the initdata is freed.
-	 */
-	arch_mem_addpart(PFN_DOWN(__pa_symbol(&_text)) << PAGE_SHIFT,
-			 PFN_UP(__pa_symbol(&_edata)) << PAGE_SHIFT,
-			 BOOT_MEM_RAM);
-	arch_mem_addpart(PFN_UP(__pa_symbol(&__init_begin)) << PAGE_SHIFT,
-			 PFN_DOWN(__pa_symbol(&__init_end)) << PAGE_SHIFT,
-			 BOOT_MEM_INIT_RAM);
-	arch_mem_addpart(PFN_DOWN(__pa_symbol(&__bss_start)) << PAGE_SHIFT,
-			 PFN_UP(__pa_symbol(&__bss_stop)) << PAGE_SHIFT,
-			 BOOT_MEM_RAM);
-
-	pr_info("Determined physical RAM map:\n");
-	print_memory_map();
-
 #if defined(CONFIG_CMDLINE_BOOL) && defined(CONFIG_CMDLINE_OVERRIDE)
 	strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
 #else
@@ -783,14 +613,17 @@ static void __init arch_mem_init(char **cmdline_p)
 
 	parse_early_param();
 
-	if (usermem) {
-		pr_info("User-defined physical RAM map:\n");
-		print_memory_map();
-	}
+	if (usermem)
+		pr_info("User-defined physical RAM map overwrite\n");
+
+	check_kernel_sections_mem();
 
 	early_init_fdt_reserve_self();
 	early_init_fdt_scan_reserved_mem();
 
+#ifndef CONFIG_NUMA
+	memblock_set_node(0, PHYS_ADDR_MAX, &memblock.memory, 0);
+#endif
 	bootmem_init();
 
 	/*
@@ -830,12 +663,12 @@ static void __init arch_mem_init(char **cmdline_p)
 
 	memblock_dump_all();
 
-	early_memtest(PFN_PHYS(min_low_pfn), PFN_PHYS(max_low_pfn));
+	early_memtest(PFN_PHYS(ARCH_PFN_OFFSET), PFN_PHYS(max_low_pfn));
 }
 
 static void __init resource_init(void)
 {
-	int i;
+	struct memblock_region *region;
 
 	if (UNCAC_BASE != IO_BASE)
 		return;
@@ -847,16 +680,10 @@ static void __init resource_init(void)
 	bss_resource.start = __pa_symbol(&__bss_start);
 	bss_resource.end = __pa_symbol(&__bss_stop) - 1;
 
-	for (i = 0; i < boot_mem_map.nr_map; i++) {
+	for_each_memblock(memory, region) {
+		phys_addr_t start = PFN_PHYS(memblock_region_memory_base_pfn(region));
+		phys_addr_t end = PFN_PHYS(memblock_region_memory_end_pfn(region)) - 1;
 		struct resource *res;
-		unsigned long start, end;
-
-		start = boot_mem_map.map[i].addr;
-		end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1;
-		if (start >= HIGHMEM_START)
-			continue;
-		if (end >= HIGHMEM_START)
-			end = HIGHMEM_START - 1;
 
 		res = memblock_alloc(sizeof(struct resource), SMP_CACHE_BYTES);
 		if (!res)
@@ -865,20 +692,8 @@ static void __init resource_init(void)
 
 		res->start = start;
 		res->end = end;
-		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
-
-		switch (boot_mem_map.map[i].type) {
-		case BOOT_MEM_RAM:
-		case BOOT_MEM_INIT_RAM:
-		case BOOT_MEM_ROM_DATA:
-			res->name = "System RAM";
-			res->flags |= IORESOURCE_SYSRAM;
-			break;
-		case BOOT_MEM_RESERVED:
-		case BOOT_MEM_NOMAP:
-		default:
-			res->name = "reserved";
-		}
+		res->flags = IORESOURCE_SYSTEM_RAM | IORESOURCE_BUSY;
+		res->name = "System RAM";
 
 		request_resource(&iomem_resource, res);
 
-- 
2.22.0


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

* Re: [PATCH v1 0/8] MIPS: Drop boot_mem_map
  2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
                     ` (7 preceding siblings ...)
  2019-08-19 14:23   ` [PATCH v1 8/8] MIPS: init: " Jiaxun Yang
@ 2019-08-23 14:45   ` Paul Burton
  2019-08-23 17:20     ` Jiaxun Yang
  2019-08-23 18:05     ` Serge Semin
  8 siblings, 2 replies; 31+ messages in thread
From: Paul Burton @ 2019-08-23 14:45 UTC (permalink / raw)
  To: Jiaxun Yang
  Cc: linux-mips, Paul Burton, yasha.che3, aurelien, sfr,
	fancer.lancer, matt.redfearn, chenhc, Jiaxun Yang, linux-mips

Hello,

Jiaxun Yang wrote:
> v1: Reording patches, fixes according to Serge's suggestions,
> fix maar section mismatch.
> 
> Jiaxun Yang (8):
>   MIPS: OCTEON: Drop boot_mem_map
>   MIPS: fw: Record prom memory
>   MIPS: malta: Drop prom_free_prom_memory
>   MIPS: msp: Record prom memory
>   MIPS: ip22: Drop addr_is_ram
>   MIPS: xlp: Drop boot_mem_map
>   MIPS: mm: Drop boot_mem_map
>   MIPS: init: Drop boot_mem_map
> 
>  arch/mips/cavium-octeon/dma-octeon.c |  17 +-
>  arch/mips/cavium-octeon/setup.c      |   3 +-
>  arch/mips/fw/arc/memory.c            |  24 +-
>  arch/mips/include/asm/bootinfo.h     |  16 --
>  arch/mips/include/asm/maar.h         |   8 +-

Series applied to mips-next.

> MIPS: OCTEON: Drop boot_mem_map
>   commit 6cda3a5e002f
>   https://git.kernel.org/mips/c/6cda3a5e002f
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: fw: Record prom memory
>   commit 0df1007677d5
>   https://git.kernel.org/mips/c/0df1007677d5
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: malta: Drop prom_free_prom_memory
>   commit 79fd0fe44731
>   https://git.kernel.org/mips/c/79fd0fe44731
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: msp: Record prom memory
>   commit b3c948e2c00f
>   https://git.kernel.org/mips/c/b3c948e2c00f
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: ip22: Drop addr_is_ram
>   commit aa1edac13e5f
>   https://git.kernel.org/mips/c/aa1edac13e5f
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: xlp: Drop boot_mem_map
>   commit a121d6e0caf0
>   https://git.kernel.org/mips/c/a121d6e0caf0
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: mm: Drop boot_mem_map
>   commit a5718fe8f70f
>   https://git.kernel.org/mips/c/a5718fe8f70f
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   [paul.burton@mips.com:
>     - Fix bad MAAR address calculations.
>     - Use ALIGN() & define maar_align to make it clearer what's going on
>       with address manipulations.
>     - Drop the new used field from struct maar_config.
>     - Rework the RAM walk to avoid iterating over the cfg array needlessly
>       to find the first unused entry, then count used entries at the end.
>       Instead just keep the count as we go.]
>   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> MIPS: init: Drop boot_mem_map
>   commit a94e4f24ec83
>   https://git.kernel.org/mips/c/a94e4f24ec83
>   
>   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
>   [paul.burton@mips.com: Fix size calculation in check_kernel_sections_mem]
>   Signed-off-by: Paul Burton <paul.burton@mips.com>

Thanks,
    Paul

[ This message was auto-generated; if you believe anything is incorrect
  then please email paul.burton@mips.com to report it. ]

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

* Re: [PATCH v1 0/8] MIPS: Drop boot_mem_map
  2019-08-23 14:45   ` [PATCH v1 0/8] MIPS: " Paul Burton
@ 2019-08-23 17:20     ` Jiaxun Yang
  2019-08-23 17:36       ` Jiaxun Yang
  2019-08-23 18:05     ` Serge Semin
  1 sibling, 1 reply; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-23 17:20 UTC (permalink / raw)
  To: Paul Burton
  Cc: linux-mips, Paul Burton, yasha.che3, aurelien, sfr,
	fancer.lancer, matt.redfearn, chenhc


On 2019/8/23 下午10:45, Paul Burton wrote:
> Hello,
>
> Jiaxun Yang wrote:
>> v1: Reording patches, fixes according to Serge's suggestions,
>> fix maar section mismatch.
>>
>> Jiaxun Yang (8):
>>    MIPS: OCTEON: Drop boot_mem_map
>>    MIPS: fw: Record prom memory
>>    MIPS: malta: Drop prom_free_prom_memory
>>    MIPS: msp: Record prom memory
>>    MIPS: ip22: Drop addr_is_ram
>>    MIPS: xlp: Drop boot_mem_map
>>    MIPS: mm: Drop boot_mem_map
>>    MIPS: init: Drop boot_mem_map
>>
>>   arch/mips/cavium-octeon/dma-octeon.c |  17 +-
>>   arch/mips/cavium-octeon/setup.c      |   3 +-
>>   arch/mips/fw/arc/memory.c            |  24 +-
>>   arch/mips/include/asm/bootinfo.h     |  16 --
>>   arch/mips/include/asm/maar.h         |   8 +-
> Series applied to mips-next.

Sorry Paul, there are some build issues suggested by kbuild test boot, 
I'm going to send v2 later.

--

Jiaxun Yang


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

* Re: [PATCH v1 0/8] MIPS: Drop boot_mem_map
  2019-08-23 17:20     ` Jiaxun Yang
@ 2019-08-23 17:36       ` Jiaxun Yang
  0 siblings, 0 replies; 31+ messages in thread
From: Jiaxun Yang @ 2019-08-23 17:36 UTC (permalink / raw)
  To: Paul Burton
  Cc: linux-mips, Paul Burton, yasha.che3, aurelien, sfr,
	fancer.lancer, matt.redfearn, chenhc


On 2019/8/24 上午1:20, Jiaxun Yang wrote:
>
> On 2019/8/23 下午10:45, Paul Burton wrote:
>> Hello,
>>
>> Jiaxun Yang wrote:
>>> v1: Reording patches, fixes according to Serge's suggestions,
>>> fix maar section mismatch.
>>>
>>> Jiaxun Yang (8):
>>>    MIPS: OCTEON: Drop boot_mem_map
>>>    MIPS: fw: Record prom memory
>>>    MIPS: malta: Drop prom_free_prom_memory
>>>    MIPS: msp: Record prom memory
>>>    MIPS: ip22: Drop addr_is_ram
>>>    MIPS: xlp: Drop boot_mem_map
>>>    MIPS: mm: Drop boot_mem_map
>>>    MIPS: init: Drop boot_mem_map
>>>
>>>   arch/mips/cavium-octeon/dma-octeon.c |  17 +-
>>>   arch/mips/cavium-octeon/setup.c      |   3 +-
>>>   arch/mips/fw/arc/memory.c            |  24 +-
>>>   arch/mips/include/asm/bootinfo.h     |  16 --
>>>   arch/mips/include/asm/maar.h         |   8 +-
>> Series applied to mips-next.
>
> Sorry Paul, there are some build issues suggested by kbuild test boot, 
> I'm going to send v2 later.
>
Or you can simply fix them and apply again...

Sorry for the stupid problems. I should test with varies of configs 
before send them out.

I promise that won't happen again.

--

Jiaxun Yang



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

* Re: [PATCH v1 0/8] MIPS: Drop boot_mem_map
  2019-08-23 14:45   ` [PATCH v1 0/8] MIPS: " Paul Burton
  2019-08-23 17:20     ` Jiaxun Yang
@ 2019-08-23 18:05     ` Serge Semin
  1 sibling, 0 replies; 31+ messages in thread
From: Serge Semin @ 2019-08-23 18:05 UTC (permalink / raw)
  To: Paul Burton
  Cc: Jiaxun Yang, linux-mips, Paul Burton, yasha.che3, aurelien, sfr,
	matt.redfearn, chenhc

On Fri, Aug 23, 2019 at 02:45:08PM +0000, Paul Burton wrote:
> Hello,
> 
> Jiaxun Yang wrote:
> > v1: Reording patches, fixes according to Serge's suggestions,
> > fix maar section mismatch.
> > 
> > Jiaxun Yang (8):
> >   MIPS: OCTEON: Drop boot_mem_map
> >   MIPS: fw: Record prom memory
> >   MIPS: malta: Drop prom_free_prom_memory
> >   MIPS: msp: Record prom memory
> >   MIPS: ip22: Drop addr_is_ram
> >   MIPS: xlp: Drop boot_mem_map
> >   MIPS: mm: Drop boot_mem_map
> >   MIPS: init: Drop boot_mem_map
> > 
> >  arch/mips/cavium-octeon/dma-octeon.c |  17 +-
> >  arch/mips/cavium-octeon/setup.c      |   3 +-
> >  arch/mips/fw/arc/memory.c            |  24 +-
> >  arch/mips/include/asm/bootinfo.h     |  16 --
> >  arch/mips/include/asm/maar.h         |   8 +-
> 
> Series applied to mips-next.

it seems to me too late to set the tag...
Reviewed-by: Serge Semin <fancer.lancer@gmail.com>

-Sergey

> 
> > MIPS: OCTEON: Drop boot_mem_map
> >   commit 6cda3a5e002f
> >   https://git.kernel.org/mips/c/6cda3a5e002f
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: fw: Record prom memory
> >   commit 0df1007677d5
> >   https://git.kernel.org/mips/c/0df1007677d5
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: malta: Drop prom_free_prom_memory
> >   commit 79fd0fe44731
> >   https://git.kernel.org/mips/c/79fd0fe44731
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: msp: Record prom memory
> >   commit b3c948e2c00f
> >   https://git.kernel.org/mips/c/b3c948e2c00f
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: ip22: Drop addr_is_ram
> >   commit aa1edac13e5f
> >   https://git.kernel.org/mips/c/aa1edac13e5f
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: xlp: Drop boot_mem_map
> >   commit a121d6e0caf0
> >   https://git.kernel.org/mips/c/a121d6e0caf0
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: mm: Drop boot_mem_map
> >   commit a5718fe8f70f
> >   https://git.kernel.org/mips/c/a5718fe8f70f
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   [paul.burton@mips.com:
> >     - Fix bad MAAR address calculations.
> >     - Use ALIGN() & define maar_align to make it clearer what's going on
> >       with address manipulations.
> >     - Drop the new used field from struct maar_config.
> >     - Rework the RAM walk to avoid iterating over the cfg array needlessly
> >       to find the first unused entry, then count used entries at the end.
> >       Instead just keep the count as we go.]
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> > 
> > MIPS: init: Drop boot_mem_map
> >   commit a94e4f24ec83
> >   https://git.kernel.org/mips/c/a94e4f24ec83
> >   
> >   Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
> >   [paul.burton@mips.com: Fix size calculation in check_kernel_sections_mem]
> >   Signed-off-by: Paul Burton <paul.burton@mips.com>
> 
> Thanks,
>     Paul
> 
> [ This message was auto-generated; if you believe anything is incorrect
>   then please email paul.burton@mips.com to report it. ]

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

end of thread, other threads:[~2019-08-23 18:05 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-08  7:50 Drop boot_mem_map Jiaxun Yang
2019-08-08  7:50 ` [PATCH 1/7] MIPS: init: " Jiaxun Yang
2019-08-14 11:54   ` Serge Semin
2019-08-14 13:40     ` Jiaxun Yang
2019-08-08  7:50 ` [PATCH 2/7] MIPS: OCTEON: " Jiaxun Yang
2019-08-08  7:50 ` [PATCH 3/7] MIPS: fw: Record prom memory Jiaxun Yang
2019-08-14 12:03   ` Serge Semin
2019-08-14 12:50     ` Thomas Bogendoerfer
2019-08-14 13:45     ` Jiaxun Yang
2019-08-08  7:50 ` [PATCH 4/7] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
2019-08-08  7:50 ` [PATCH 5/7] MIPS: msp: Record prom memory Jiaxun Yang
2019-08-14 12:12   ` Serge Semin
2019-08-08  7:50 ` [PATCH 6/7] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
2019-08-08  7:50 ` [PATCH 7/7] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
2019-08-12  4:56 ` [EXTERNAL]Drop boot_mem_map Paul Burton
2019-08-12  5:28   ` Jiaxun Yang
2019-08-13  8:39     ` Serge Semin
2019-08-13 15:09       ` Jiaxun Yang
2019-08-19 14:23 ` [PATCH v1 0/8] MIPS: Drop boot_mem_map Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 1/8] MIPS: OCTEON: " Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 2/8] MIPS: fw: Record prom memory Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 3/8] MIPS: malta: Drop prom_free_prom_memory Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 4/8] MIPS: msp: Record prom memory Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 5/8] MIPS: ip22: Drop addr_is_ram Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 6/8] MIPS: xlp: Drop boot_mem_map Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 7/8] MIPS: mm: " Jiaxun Yang
2019-08-19 14:23   ` [PATCH v1 8/8] MIPS: init: " Jiaxun Yang
2019-08-23 14:45   ` [PATCH v1 0/8] MIPS: " Paul Burton
2019-08-23 17:20     ` Jiaxun Yang
2019-08-23 17:36       ` Jiaxun Yang
2019-08-23 18:05     ` Serge Semin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).