Skip to content

Commit 4af22de

Browse files
rpptvineetgarc
authored andcommitted
arc: fix memory initialization for systems with two memory banks
Rework of memory map initialization broke initialization of ARC systems with two memory banks. Before these changes, memblock was not aware of nodes configuration and the memory map was always allocated from the "lowmem" bank. After the addition of node information to memblock, the core mm attempts to allocate the memory map for the "highmem" bank from its node. The access to this memory using __va() fails because it can be only accessed using kmap. Anther problem that was uncovered is that {min,max}_high_pfn are calculated from u64 high_mem_start variable which prevents truncation to 32-bit physical address and the PFN values are above the node and zone boundaries. Use phys_addr_t type for high_mem_start and high_mem_size to ensure correspondence between PFNs and highmem zone boundaries and reserve the entire highmem bank until mem_init() to avoid accesses to it before highmem is enabled. To test this: 1. Enable HIGHMEM in ARC config 2. Enable 2 memory banks in haps_hs.dts (uncomment the 2nd bank) Fixes: 51930df ("mm: free_area_init: allow defining max_zone_pfn in descending order") Cc: [email protected] [5.8] Signed-off-by: Mike Rapoport <[email protected]> Signed-off-by: Vineet Gupta <[email protected]> [vgupta: added instructions to test highmem]
1 parent 89d2999 commit 4af22de

File tree

1 file changed

+16
-11
lines changed

1 file changed

+16
-11
lines changed

arch/arc/mm/init.c

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ static unsigned long low_mem_sz;
2626

2727
#ifdef CONFIG_HIGHMEM
2828
static unsigned long min_high_pfn, max_high_pfn;
29-
static u64 high_mem_start;
30-
static u64 high_mem_sz;
29+
static phys_addr_t high_mem_start;
30+
static phys_addr_t high_mem_sz;
3131
#endif
3232

3333
#ifdef CONFIG_DISCONTIGMEM
@@ -69,6 +69,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
6969
high_mem_sz = size;
7070
in_use = 1;
7171
memblock_add_node(base, size, 1);
72+
memblock_reserve(base, size);
7273
#endif
7374
}
7475

@@ -157,7 +158,7 @@ void __init setup_arch_memory(void)
157158
min_high_pfn = PFN_DOWN(high_mem_start);
158159
max_high_pfn = PFN_DOWN(high_mem_start + high_mem_sz);
159160

160-
max_zone_pfn[ZONE_HIGHMEM] = max_high_pfn;
161+
max_zone_pfn[ZONE_HIGHMEM] = min_low_pfn;
161162

162163
high_memory = (void *)(min_high_pfn << PAGE_SHIFT);
163164
kmap_init();
@@ -166,22 +167,26 @@ void __init setup_arch_memory(void)
166167
free_area_init(max_zone_pfn);
167168
}
168169

169-
/*
170-
* mem_init - initializes memory
171-
*
172-
* Frees up bootmem
173-
* Calculates and displays memory available/used
174-
*/
175-
void __init mem_init(void)
170+
static void __init highmem_init(void)
176171
{
177172
#ifdef CONFIG_HIGHMEM
178173
unsigned long tmp;
179174

180-
reset_all_zones_managed_pages();
175+
memblock_free(high_mem_start, high_mem_sz);
181176
for (tmp = min_high_pfn; tmp < max_high_pfn; tmp++)
182177
free_highmem_page(pfn_to_page(tmp));
183178
#endif
179+
}
184180

181+
/*
182+
* mem_init - initializes memory
183+
*
184+
* Frees up bootmem
185+
* Calculates and displays memory available/used
186+
*/
187+
void __init mem_init(void)
188+
{
185189
memblock_free_all();
190+
highmem_init();
186191
mem_init_print_info(NULL);
187192
}

0 commit comments

Comments
 (0)