forked from mirrors/linux
		
	memory-hotplug: fix wrong edge when hot add a new node
When we add a new node, the edge of memory may be wrong.
e.g. system has 4 nodes, and node3 is movable, node3 mem:[24G-32G],
1. hotremove the node3,
2. then hotadd node3 with a part of memory, mem:[26G-30G],
3. call hotadd_new_pgdat()
        free_area_init_node()
                get_pfn_range_for_nid()
4. it will return wrong start_pfn and end_pfn, because we have not
update the memblock.
This patch also fixes a BUG_ON during hot-addition, please see
http://marc.info/?l=linux-kernel&m=142961156129456&w=2
Signed-off-by: Xishi Qiu <qiuxishi@huawei.com>
Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com>
Cc: Taku Izumi <izumi.taku@jp.fujitsu.com>
Cc: Tang Chen <tangchen@cn.fujitsu.com>
Cc: Gu Zheng <guz.fnst@cn.fujitsu.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
			
			
This commit is contained in:
		
							parent
							
								
									2baf9e8948
								
							
						
					
					
						commit
						f9126ab924
					
				
					 2 changed files with 11 additions and 0 deletions
				
			
		|  | @ -1277,6 +1277,7 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
| 
 | ||||
| 	/* create new memmap entry */ | ||||
| 	firmware_map_add_hotplug(start, start + size, "System RAM"); | ||||
| 	memblock_add_node(start, size, nid); | ||||
| 
 | ||||
| 	goto out; | ||||
| 
 | ||||
|  | @ -2013,6 +2014,8 @@ void __ref remove_memory(int nid, u64 start, u64 size) | |||
| 
 | ||||
| 	/* remove memmap entry */ | ||||
| 	firmware_map_remove(start, start + size, "System RAM"); | ||||
| 	memblock_free(start, size); | ||||
| 	memblock_remove(start, size); | ||||
| 
 | ||||
| 	arch_remove_memory(start, size); | ||||
| 
 | ||||
|  |  | |||
|  | @ -5060,6 +5060,10 @@ static unsigned long __meminit zone_spanned_pages_in_node(int nid, | |||
| { | ||||
| 	unsigned long zone_start_pfn, zone_end_pfn; | ||||
| 
 | ||||
| 	/* When hotadd a new node, the node should be empty */ | ||||
| 	if (!node_start_pfn && !node_end_pfn) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	/* Get the start and end of the zone */ | ||||
| 	zone_start_pfn = arch_zone_lowest_possible_pfn[zone_type]; | ||||
| 	zone_end_pfn = arch_zone_highest_possible_pfn[zone_type]; | ||||
|  | @ -5123,6 +5127,10 @@ static unsigned long __meminit zone_absent_pages_in_node(int nid, | |||
| 	unsigned long zone_high = arch_zone_highest_possible_pfn[zone_type]; | ||||
| 	unsigned long zone_start_pfn, zone_end_pfn; | ||||
| 
 | ||||
| 	/* When hotadd a new node, the node should be empty */ | ||||
| 	if (!node_start_pfn && !node_end_pfn) | ||||
| 		return 0; | ||||
| 
 | ||||
| 	zone_start_pfn = clamp(node_start_pfn, zone_low, zone_high); | ||||
| 	zone_end_pfn = clamp(node_end_pfn, zone_low, zone_high); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Xishi Qiu
						Xishi Qiu