forked from mirrors/linux
		
	cpu-hotplug,memory-hotplug: clear cpu_to_node() when offlining the node
When the node is offlined, there is no memory/cpu on the node. If a sleep task runs on a cpu of this node, it will be migrated to the cpu on the other node. So we can clear cpu-to-node mapping. [akpm@linux-foundation.org: numa_clear_node() and numa_set_node() can no longer be __cpuinit] Signed-off-by: Wen Congyang <wency@cn.fujitsu.com> Signed-off-by: Tang Chen <tangchen@cn.fujitsu.com> Cc: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> Cc: David Rientjes <rientjes@google.com> Cc: Jiang Liu <liuj97@gmail.com> Cc: Minchan Kim <minchan.kim@gmail.com> Cc: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Mel Gorman <mel@csn.ul.ie> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
		
							parent
							
								
									76bba1423f
								
							
						
					
					
						commit
						e13fe8695c
					
				
					 3 changed files with 33 additions and 5 deletions
				
			
		| 
						 | 
					@ -57,8 +57,8 @@ static inline int numa_cpu_node(int cpu)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_NUMA
 | 
					#ifdef CONFIG_NUMA
 | 
				
			||||||
extern void __cpuinit numa_set_node(int cpu, int node);
 | 
					extern void numa_set_node(int cpu, int node);
 | 
				
			||||||
extern void __cpuinit numa_clear_node(int cpu);
 | 
					extern void numa_clear_node(int cpu);
 | 
				
			||||||
extern void __init init_cpu_to_node(void);
 | 
					extern void __init init_cpu_to_node(void);
 | 
				
			||||||
extern void __cpuinit numa_add_cpu(int cpu);
 | 
					extern void __cpuinit numa_add_cpu(int cpu);
 | 
				
			||||||
extern void __cpuinit numa_remove_cpu(int cpu);
 | 
					extern void __cpuinit numa_remove_cpu(int cpu);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -78,7 +78,7 @@ EXPORT_SYMBOL(node_to_cpumask_map);
 | 
				
			||||||
DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
 | 
					DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
 | 
				
			||||||
EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
 | 
					EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __cpuinit numa_set_node(int cpu, int node)
 | 
					void numa_set_node(int cpu, int node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
 | 
						int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -101,7 +101,7 @@ void __cpuinit numa_set_node(int cpu, int node)
 | 
				
			||||||
		set_cpu_numa_node(cpu, node);
 | 
							set_cpu_numa_node(cpu, node);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void __cpuinit numa_clear_node(int cpu)
 | 
					void numa_clear_node(int cpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	numa_set_node(cpu, NUMA_NO_NODE);
 | 
						numa_set_node(cpu, NUMA_NO_NODE);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1705,6 +1705,34 @@ static int check_cpu_on_node(void *data)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void unmap_cpu_on_node(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					#ifdef CONFIG_ACPI_NUMA
 | 
				
			||||||
 | 
						struct pglist_data *pgdat = data;
 | 
				
			||||||
 | 
						int cpu;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for_each_possible_cpu(cpu)
 | 
				
			||||||
 | 
							if (cpu_to_node(cpu) == pgdat->node_id)
 | 
				
			||||||
 | 
								numa_clear_node(cpu);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int check_and_unmap_cpu_on_node(void *data)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret = check_cpu_on_node(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/*
 | 
				
			||||||
 | 
						 * the node will be offlined when we come here, so we can clear
 | 
				
			||||||
 | 
						 * the cpu_to_node() now.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						unmap_cpu_on_node(data);
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* offline the node if all memory sections of this node are removed */
 | 
					/* offline the node if all memory sections of this node are removed */
 | 
				
			||||||
void try_offline_node(int nid)
 | 
					void try_offline_node(int nid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -1731,7 +1759,7 @@ void try_offline_node(int nid)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (stop_machine(check_cpu_on_node, pgdat, NULL))
 | 
						if (stop_machine(check_and_unmap_cpu_on_node, pgdat, NULL))
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue