forked from mirrors/linux
		
	mem-hotplug: introduce {un}lock_memory_hotplug()
Presently hwpoison is using lock_system_sleep() to prevent a race with memory hotplug. However lock_system_sleep() is a no-op if CONFIG_HIBERNATION=n. Therefore we need a new lock. Signed-off-by: KOSAKI Motohiro <kosaki.motohiro@jp.fujitsu.com> Cc: Andi Kleen <andi@firstfloor.org> Cc: Kamezawa Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Suggested-by: Hugh Dickins <hughd@google.com> Acked-by: Hugh Dickins <hughd@google.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
							
								
									4fe65cab84
								
							
						
					
					
						commit
						20d6c96b5f
					
				
					 3 changed files with 34 additions and 11 deletions
				
			
		|  | @ -161,6 +161,9 @@ extern void register_page_bootmem_info_node(struct pglist_data *pgdat); | |||
| extern void put_page_bootmem(struct page *page); | ||||
| #endif | ||||
| 
 | ||||
| void lock_memory_hotplug(void); | ||||
| void unlock_memory_hotplug(void); | ||||
| 
 | ||||
| #else /* ! CONFIG_MEMORY_HOTPLUG */ | ||||
| /*
 | ||||
|  * Stub functions for when hotplug is off | ||||
|  | @ -192,6 +195,9 @@ static inline void register_page_bootmem_info_node(struct pglist_data *pgdat) | |||
| { | ||||
| } | ||||
| 
 | ||||
| static inline void lock_memory_hotplug(void) {} | ||||
| static inline void unlock_memory_hotplug(void) {} | ||||
| 
 | ||||
| #endif /* ! CONFIG_MEMORY_HOTPLUG */ | ||||
| 
 | ||||
| #ifdef CONFIG_MEMORY_HOTREMOVE | ||||
|  |  | |||
|  | @ -51,6 +51,7 @@ | |||
| #include <linux/slab.h> | ||||
| #include <linux/swapops.h> | ||||
| #include <linux/hugetlb.h> | ||||
| #include <linux/memory_hotplug.h> | ||||
| #include "internal.h" | ||||
| 
 | ||||
| int sysctl_memory_failure_early_kill __read_mostly = 0; | ||||
|  | @ -1230,11 +1231,10 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags) | |||
| 		return 1; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The lock_system_sleep prevents a race with memory hotplug, | ||||
| 	 * because the isolation assumes there's only a single user. | ||||
| 	 * The lock_memory_hotplug prevents a race with memory hotplug. | ||||
| 	 * This is a big hammer, a better would be nicer. | ||||
| 	 */ | ||||
| 	lock_system_sleep(); | ||||
| 	lock_memory_hotplug(); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Isolate the page, so that it doesn't get reallocated if it | ||||
|  | @ -1264,7 +1264,7 @@ static int get_any_page(struct page *p, unsigned long pfn, int flags) | |||
| 		ret = 1; | ||||
| 	} | ||||
| 	unset_migratetype_isolate(p); | ||||
| 	unlock_system_sleep(); | ||||
| 	unlock_memory_hotplug(); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -34,6 +34,23 @@ | |||
| 
 | ||||
| #include "internal.h" | ||||
| 
 | ||||
| DEFINE_MUTEX(mem_hotplug_mutex); | ||||
| 
 | ||||
| void lock_memory_hotplug(void) | ||||
| { | ||||
| 	mutex_lock(&mem_hotplug_mutex); | ||||
| 
 | ||||
| 	/* for exclusive hibernation if CONFIG_HIBERNATION=y */ | ||||
| 	lock_system_sleep(); | ||||
| } | ||||
| 
 | ||||
| void unlock_memory_hotplug(void) | ||||
| { | ||||
| 	unlock_system_sleep(); | ||||
| 	mutex_unlock(&mem_hotplug_mutex); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* add this memory to iomem resource */ | ||||
| static struct resource *register_memory_resource(u64 start, u64 size) | ||||
| { | ||||
|  | @ -493,7 +510,7 @@ int mem_online_node(int nid) | |||
| 	pg_data_t	*pgdat; | ||||
| 	int	ret; | ||||
| 
 | ||||
| 	lock_system_sleep(); | ||||
| 	lock_memory_hotplug(); | ||||
| 	pgdat = hotadd_new_pgdat(nid, 0); | ||||
| 	if (pgdat) { | ||||
| 		ret = -ENOMEM; | ||||
|  | @ -504,7 +521,7 @@ int mem_online_node(int nid) | |||
| 	BUG_ON(ret); | ||||
| 
 | ||||
| out: | ||||
| 	unlock_system_sleep(); | ||||
| 	unlock_memory_hotplug(); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  | @ -516,7 +533,7 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
| 	struct resource *res; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	lock_system_sleep(); | ||||
| 	lock_memory_hotplug(); | ||||
| 
 | ||||
| 	res = register_memory_resource(start, size); | ||||
| 	ret = -EEXIST; | ||||
|  | @ -563,7 +580,7 @@ int __ref add_memory(int nid, u64 start, u64 size) | |||
| 		release_memory_resource(res); | ||||
| 
 | ||||
| out: | ||||
| 	unlock_system_sleep(); | ||||
| 	unlock_memory_hotplug(); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(add_memory); | ||||
|  | @ -791,7 +808,7 @@ static int offline_pages(unsigned long start_pfn, | |||
| 	if (!test_pages_in_a_zone(start_pfn, end_pfn)) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	lock_system_sleep(); | ||||
| 	lock_memory_hotplug(); | ||||
| 
 | ||||
| 	zone = page_zone(pfn_to_page(start_pfn)); | ||||
| 	node = zone_to_nid(zone); | ||||
|  | @ -880,7 +897,7 @@ static int offline_pages(unsigned long start_pfn, | |||
| 	writeback_set_ratelimit(); | ||||
| 
 | ||||
| 	memory_notify(MEM_OFFLINE, &arg); | ||||
| 	unlock_system_sleep(); | ||||
| 	unlock_memory_hotplug(); | ||||
| 	return 0; | ||||
| 
 | ||||
| failed_removal: | ||||
|  | @ -891,7 +908,7 @@ static int offline_pages(unsigned long start_pfn, | |||
| 	undo_isolate_page_range(start_pfn, end_pfn); | ||||
| 
 | ||||
| out: | ||||
| 	unlock_system_sleep(); | ||||
| 	unlock_memory_hotplug(); | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 KOSAKI Motohiro
						KOSAKI Motohiro