x86-32, memblock: Make add_highpages honor early reserved ranges

Originally the only early reserved range that is overlapped with high
pages is "KVA RAM", but we already do remove that from the active ranges.

However, It turns out Xen could have that kind of overlapping to support memory
ballooning.x

So we need to make add_highpage_with_active_regions() to subtract
memblock reserved just like low ram; this is the proper design anyway.

In this patch, refactering get_freel_all_memory_range() to make it can
be used by add_highpage_with_active_regions(). Also we don't need to
remove "KVA RAM" from active ranges.

Signed-off-by: Yinghai Lu <yinghai@kernel.org>
LKML-Reference: <4CABB183.1040607@kernel.org>
Signed-off-by: H. Peter Anvin <hpa@zytor.com>

authored by

Yinghai Lu and committed by
H. Peter Anvin
1d931264 9f4c1396

+33 -43
+2
arch/x86/include/asm/memblock.h
··· 9 void memblock_x86_reserve_range(u64 start, u64 end, char *name); 10 void memblock_x86_free_range(u64 start, u64 end); 11 struct range; 12 int get_free_all_memory_range(struct range **rangep, int nodeid); 13 14 void memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
··· 9 void memblock_x86_reserve_range(u64 start, u64 end, char *name); 10 void memblock_x86_free_range(u64 start, u64 end); 11 struct range; 12 + int __get_free_all_memory_range(struct range **range, int nodeid, 13 + unsigned long start_pfn, unsigned long end_pfn); 14 int get_free_all_memory_range(struct range **rangep, int nodeid); 15 16 void memblock_x86_register_active_regions(int nid, unsigned long start_pfn,
+16 -37
arch/x86/mm/init_32.c
··· 423 totalhigh_pages++; 424 } 425 426 - struct add_highpages_data { 427 - unsigned long start_pfn; 428 - unsigned long end_pfn; 429 - }; 430 - 431 - static int __init add_highpages_work_fn(unsigned long start_pfn, 432 - unsigned long end_pfn, void *datax) 433 { 434 - int node_pfn; 435 - struct page *page; 436 - unsigned long final_start_pfn, final_end_pfn; 437 - struct add_highpages_data *data; 438 439 - data = (struct add_highpages_data *)datax; 440 441 - final_start_pfn = max(start_pfn, data->start_pfn); 442 - final_end_pfn = min(end_pfn, data->end_pfn); 443 - if (final_start_pfn >= final_end_pfn) 444 - return 0; 445 446 - for (node_pfn = final_start_pfn; node_pfn < final_end_pfn; 447 - node_pfn++) { 448 - if (!pfn_valid(node_pfn)) 449 - continue; 450 - page = pfn_to_page(node_pfn); 451 - add_one_highpage_init(page); 452 } 453 - 454 - return 0; 455 - 456 } 457 - 458 - void __init add_highpages_with_active_regions(int nid, unsigned long start_pfn, 459 - unsigned long end_pfn) 460 - { 461 - struct add_highpages_data data; 462 - 463 - data.start_pfn = start_pfn; 464 - data.end_pfn = end_pfn; 465 - 466 - work_with_active_regions(nid, add_highpages_work_fn, &data); 467 - } 468 - 469 #else 470 static inline void permanent_kmaps_init(pgd_t *pgd_base) 471 {
··· 423 totalhigh_pages++; 424 } 425 426 + void __init add_highpages_with_active_regions(int nid, 427 + unsigned long start_pfn, unsigned long end_pfn) 428 { 429 + struct range *range; 430 + int nr_range; 431 + int i; 432 433 + nr_range = __get_free_all_memory_range(&range, nid, start_pfn, end_pfn); 434 435 + for (i = 0; i < nr_range; i++) { 436 + struct page *page; 437 + int node_pfn; 438 439 + for (node_pfn = range[i].start; node_pfn < range[i].end; 440 + node_pfn++) { 441 + if (!pfn_valid(node_pfn)) 442 + continue; 443 + page = pfn_to_page(node_pfn); 444 + add_one_highpage_init(page); 445 + } 446 } 447 } 448 #else 449 static inline void permanent_kmaps_init(pgd_t *pgd_base) 450 {
+15 -4
arch/x86/mm/memblock.c
··· 156 return data.nr; 157 } 158 159 - int __init get_free_all_memory_range(struct range **rangep, int nodeid) 160 { 161 int count; 162 struct range *range; ··· 173 * at first 174 */ 175 nr_range = add_from_early_node_map(range, count, nr_range, nodeid); 176 - #ifdef CONFIG_X86_32 177 - subtract_range(range, count, max_low_pfn, -1ULL); 178 - #endif 179 memblock_x86_subtract_reserved(range, count); 180 nr_range = clean_sort_range(range, count); 181 182 *rangep = range; 183 return nr_range; 184 } 185 186 static u64 __init __memblock_x86_memory_in_range(u64 addr, u64 limit, bool get_free)
··· 156 return data.nr; 157 } 158 159 + int __init __get_free_all_memory_range(struct range **rangep, int nodeid, 160 + unsigned long start_pfn, unsigned long end_pfn) 161 { 162 int count; 163 struct range *range; ··· 172 * at first 173 */ 174 nr_range = add_from_early_node_map(range, count, nr_range, nodeid); 175 + subtract_range(range, count, 0, start_pfn); 176 + subtract_range(range, count, end_pfn, -1ULL); 177 + 178 memblock_x86_subtract_reserved(range, count); 179 nr_range = clean_sort_range(range, count); 180 181 *rangep = range; 182 return nr_range; 183 + } 184 + 185 + int __init get_free_all_memory_range(struct range **rangep, int nodeid) 186 + { 187 + unsigned long end_pfn = -1UL; 188 + 189 + #ifdef CONFIG_X86_32 190 + end_pfn = max_low_pfn; 191 + #endif 192 + return __get_free_all_memory_range(rangep, nodeid, 0, end_pfn); 193 } 194 195 static u64 __init __memblock_x86_memory_in_range(u64 addr, u64 limit, bool get_free)
-2
arch/x86/mm/numa_32.c
··· 326 "KVA RAM"); 327 328 node_remap_start_pfn[nid] = node_kva_final>>PAGE_SHIFT; 329 - remove_active_range(nid, node_remap_start_pfn[nid], 330 - node_remap_start_pfn[nid] + size); 331 } 332 printk(KERN_INFO "Reserving total of %lx pages for numa KVA remap\n", 333 reserve_pages);
··· 326 "KVA RAM"); 327 328 node_remap_start_pfn[nid] = node_kva_final>>PAGE_SHIFT; 329 } 330 printk(KERN_INFO "Reserving total of %lx pages for numa KVA remap\n", 331 reserve_pages);